xref: /reactos/dll/win32/browseui/shellbrowser.cpp (revision 751641c2)
1 /*
2  * ReactOS Explorer
3  *
4  * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include "precomp.h"
22 
23 #include <shellapi.h>
24 #include <htiframe.h>
25 #include <strsafe.h>
26 
27 extern HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow);
28 
29 #include "newatlinterfaces.h"
30 
31 /*
32 TODO:
33   **Provide implementation of new and delete that use LocalAlloc
34   **Persist history for shell view isn't working correctly, possibly because of the mismatch between traveling and updating the travel log. The
35         view doesn't restore the selection correctly.
36   **Build explorer.exe, browseui.dll, comctl32.dll, shdocvw.dll, shell32.dll, shlwapi.dll into a directory and run them for testing...
37   **Add brand band bitmaps to shell32.dll
38   **If Go button on address bar is clicked, each time a new duplicate entry is added to travel log
39 ****The current entry is updated in travel log before doing the travel, which means when traveling back the update of the
40         current state overwrites the wrong entry's contents. This needs to be changed.
41 ****Fix close of browser window to release all objects
42 ****Given only a GUID in ShowBrowserBar, what is the correct way to determine if the bar is vertical or horizontal?
43   **When a new bar is added to base bar site, how is base bar told so it can resize?
44   **Does the base bar site have a classid?
45   **What should refresh command send to views to make them refresh?
46   **When new bar is created, what status notifications need to be fired?
47   **How does keyboard filtering dispatch?
48   **For deferred persist history load, how does the view connect up and get the state?
49     How does context menu send open, cut, rename commands to its site (the shell view)?
50   **Fix browser to implement IProfferService and hold onto brand band correctly - this will allow animations.
51 
52   **Route View->Toolbars commands to internet toolbar
53   **Handle travel log items in View->Go
54   **Fix ShowBrowserBar to pass correct size on when bar is shown
55 ****Fix SetBorderSpaceDW to cascade resize to subsequent bars
56 ****Make ShowToolbar check if bar is already created before creating it again
57 ****Shell should fill in the list of explorer bars in the View submenus
58   **Add folder menu in the file menu
59   **Fix CShellBrowser::GetBorderDW to compute available size correctly
60   **When a new bar is shown, re-fire the navigate event. This makes the explorer band select the correct folder
61   **Implement support for refresh. Forward refresh to explorer bar (refresh on toolbar and in menu is dispatched different)
62     Make folders toolbar item update state appropriately
63     Read list of bands from registry on launch
64     Read list of bars from registry on launch
65     If the folders or search bars don't exist, disable the toolbar buttons
66     If the favorites or history bars don't exist, disable the toolbar butons
67     Fix Apply to all Folders in Folder Options
68     Implement close command
69     Add explorer band context menu to file menu
70     Add code to allow restore of internet toolbar from registry
71     Fix code that calls FireNavigateComplete to pass the correct new path
72 
73     What are the other command ids for QueryStatus/FireCommandStateChange?
74 
75     Add handler for cabinet settings change
76     Add handler for system metrics change (renegotiate border space?)
77     Add handler for theme change and forward to contained windows
78 
79     When folders are shown, the status bar text should change
80     Add code to save/restore shell view settings
81     Implement tabbing between frames
82     Fix handling of focus everywhere
83     Most keyboard shortcuts don't work, such as F2 for rename, F5 for refresh (see list in "explorer keyboard shortcuts")
84 
85     The status bar doesn't show help text for items owned by frame during menu tracking
86     Stub out frame command handlers
87     "Arrange icons by" group is not checked properly
88 
89     When folders are hidden, icon is the same as the current shell object being displayed. When folders are shown,
90         the icon is always an open folder with magnifying glass
91     Fix bars to calculate height correctly
92     Hookup policies for everything...
93     Investigate toolbar message WM_USER+93
94     Investigate toolbar message WM_USER+100 (Adds extra padding between parts of buttons with BTNS_DROPDOWN | BTNS_SHOWTEXT style
95 
96     Vertical Explorer Bar		CATID_InfoBand
97     Horizontal Explorer Bar		CATID_CommBand
98     Desk Band					CATID_DeskBand
99 
100     cache of bars
101     HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021493-0000-0000-C000-000000000046}\Enum
102     HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021494-0000-0000-C000-000000000046}\Enum
103 
104     create key here with CLSID of bar to register tool band
105     HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Toolbar
106 
107 */
108 
109 #ifndef __GNUC__
110 #pragma comment(linker, \
111     "\"/manifestdependency:type='Win32' "\
112     "name='Microsoft.Windows.Common-Controls' "\
113     "version='6.0.0.0' "\
114     "processorArchitecture='*' "\
115     "publicKeyToken='6595b64144ccf1df' "\
116     "language='*'\"")
117 #endif // __GNUC__
118 
119 static const unsigned int                   folderOptionsPageCountMax = 20;
120 static const long                           BTP_DONT_UPDATE_HISTORY = 0;
121 static const long                           BTP_UPDATE_CUR_HISTORY = 1;
122 static const long                           BTP_UPDATE_NEXT_HISTORY = 2;
123 static const long                           BTP_ACTIVATE_NOFOCUS = 0x04;
124 
125 BOOL                                        createNewStuff = false;
126 
127 
128 // this class is private to browseui.dll and is not registered externally?
129 //DEFINE_GUID(CLSID_ShellFldSetExt, 0x6D5313C0, 0x8C62, 0x11D1, 0xB2, 0xCD, 0x00, 0x60, 0x97, 0xDF, 0x8C, 0x11);
130 
DeleteMenuItems(HMENU theMenu,unsigned int firstIDToDelete,unsigned int lastIDToDelete)131 void DeleteMenuItems(HMENU theMenu, unsigned int firstIDToDelete, unsigned int lastIDToDelete)
132 {
133     MENUITEMINFO                            menuItemInfo;
134     int                                     menuItemCount;
135     int                                     curIndex;
136 
137     menuItemCount = GetMenuItemCount(theMenu);
138     curIndex = 0;
139     while (curIndex < menuItemCount)
140     {
141         menuItemInfo.cbSize = sizeof(menuItemInfo);
142         menuItemInfo.fMask = MIIM_ID;
143         if (GetMenuItemInfo(theMenu, curIndex, TRUE, &menuItemInfo) &&
144             menuItemInfo.wID >= firstIDToDelete && menuItemInfo.wID <= lastIDToDelete)
145         {
146             DeleteMenu(theMenu, curIndex, MF_BYPOSITION);
147             menuItemCount--;
148         }
149         else
150             curIndex++;
151     }
152 }
153 
SHBindToFolder(LPCITEMIDLIST path,IShellFolder ** newFolder)154 HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder)
155 {
156     CComPtr<IShellFolder>                   desktop;
157 
158     HRESULT hr = ::SHGetDesktopFolder(&desktop);
159     if (FAILED_UNEXPECTEDLY(hr))
160         return E_FAIL;
161     if (path == NULL || path->mkid.cb == 0)
162     {
163         *newFolder = desktop;
164         desktop.p->AddRef ();
165         return S_OK;
166     }
167     return desktop->BindToObject (path, NULL, IID_PPV_ARG(IShellFolder, newFolder));
168 }
169 
170 static const TCHAR szCabinetWndClass[] = TEXT("CabinetWClass");
171 //static const TCHAR szExploreWndClass[] = TEXT("ExploreWClass");
172 
173 class CDockManager;
174 class CShellBrowser;
175 
176 class CToolbarProxy :
177     public CWindowImpl<CToolbarProxy, CWindow, CControlWinTraits>
178 {
179 private:
180     CComPtr<IExplorerToolbar>               fExplorerToolbar;
181 public:
182     void Initialize(HWND parent, IUnknown *explorerToolbar);
183     void Destroy();
184 private:
185 
186     // message handlers
187     LRESULT OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
188     LRESULT OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
189 
190     BEGIN_MSG_MAP(CToolbarProxy)
191         MESSAGE_HANDLER(TB_ADDBITMAP, OnAddBitmap)
192         MESSAGE_RANGE_HANDLER(WM_USER, 0x7fff, OnForwardMessage)
193     END_MSG_MAP()
194 };
195 
Initialize(HWND parent,IUnknown * explorerToolbar)196 void CToolbarProxy::Initialize(HWND parent, IUnknown *explorerToolbar)
197 {
198     HWND                                    myWindow;
199     HRESULT                                 hResult;
200 
201     myWindow = SHCreateWorkerWindowW(0, parent, 0, WS_CHILD, NULL, 0);
202     if (myWindow != NULL)
203     {
204         SubclassWindow(myWindow);
205         SetWindowPos(NULL, -32000, -32000, 0, 0, SWP_NOOWNERZORDER | SWP_NOZORDER);
206         hResult = explorerToolbar->QueryInterface(
207             IID_PPV_ARG(IExplorerToolbar, &fExplorerToolbar));
208     }
209 }
210 
Destroy()211 void CToolbarProxy::Destroy()
212 {
213     DestroyWindow();
214     fExplorerToolbar = NULL;
215 }
216 
OnAddBitmap(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)217 LRESULT CToolbarProxy::OnAddBitmap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
218 {
219     long int                                result;
220     HRESULT                                 hResult;
221 
222     result = 0;
223     if (fExplorerToolbar.p != NULL)
224     {
225         hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 1, (long)wParam,
226             reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
227         hResult = fExplorerToolbar->AddBitmap(&CGID_ShellBrowser, 2, (long)wParam,
228             reinterpret_cast<TBADDBITMAP *>(lParam), &result, RGB(192, 192, 192));
229     }
230     return result;
231 }
232 
OnForwardMessage(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)233 LRESULT CToolbarProxy::OnForwardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
234 {
235     LRESULT                                 result;
236     HRESULT                                 hResult;
237 
238     result = 0;
239     if (fExplorerToolbar.p != NULL)
240         hResult = fExplorerToolbar->SendToolbarMsg(&CGID_ShellBrowser, uMsg, wParam, lParam, &result);
241     return result;
242 }
243 
244 /*
245 Switch to a new bar when it receives an Exec(CGID_IDeskBand, 1, 1, vaIn, NULL);
246     where vaIn will be a VT_UNKNOWN with the new bar. It also sends a RB_SHOWBAND to the
247     rebar
248 */
249 
250 struct MenuBandInfo {
251     GUID barGuid;
252     BOOL fVertical;
253 };
254 
255 class CShellBrowser :
256     public CWindowImpl<CShellBrowser, CWindow, CFrameWinTraits>,
257     public CComObjectRootEx<CComMultiThreadModelNoCS>,
258     public IShellBrowser,
259     public IDropTarget,
260     public IServiceProvider,
261     public IProfferServiceImpl<CShellBrowser>,
262     public IShellBrowserService,
263     public IWebBrowser2,
264     public ITravelLogClient,
265     public IPersistHistory,
266     public IDockingWindowSite,
267     public IOleCommandTarget,
268     public IBrowserService2,
269     public IConnectionPointContainerImpl<CShellBrowser>,
270     public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>,
271     public MyIConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>
272 {
273 private:
274     class barInfo
275     {
276     public:
barInfo()277         barInfo()
278         {
279             memset(&borderSpace, 0, sizeof(borderSpace));
280             hwnd = NULL;
281         }
282 
283         RECT                                borderSpace;
284         CComPtr<IUnknown>                   clientBar;
285         HWND                                hwnd;
286     };
287     static const int                        BIInternetToolbar = 0;
288     static const int                        BIVerticalBaseBar = 1;
289     static const int                        BIHorizontalBaseBar = 2;
290 
291     HWND                                    fCurrentShellViewWindow;    // our currently hosted shell view window
292     CComPtr<IShellFolder>                   fCurrentShellFolder;        //
293     CComPtr<IShellView>                     fCurrentShellView;          //
294     LPITEMIDLIST                            fCurrentDirectoryPIDL;      //
295     HWND                                    fStatusBar;
296     CToolbarProxy                           fToolbarProxy;
297     barInfo                                 fClientBars[3];
298     CComPtr<ITravelLog>                     fTravelLog;
299     HMENU                                   fCurrentMenuBar;
300     GUID                                    fCurrentVertBar;             //The guid of the built in vertical bar that is being shown
301     // The next three fields support persisted history for shell views.
302     // They do not need to be reference counted.
303     IOleObject                              *fHistoryObject;
304     IStream                                 *fHistoryStream;
305     IBindCtx                                *fHistoryBindContext;
306     HDSA menuDsa;
307     HACCEL m_hAccel;
308     ShellSettings m_settings;
309     SBFOLDERSETTINGS m_deffoldersettings;
310     DWORD m_BrowserSvcFlags;
311     bool m_Destroyed;
312 public:
313 #if 0
314     ULONG InternalAddRef()
315     {
316         OutputDebugString(_T("AddRef\n"));
317         return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalAddRef();
318     }
319     ULONG InternalRelease()
320     {
321         OutputDebugString(_T("Release\n"));
322         return CComObjectRootEx<CComMultiThreadModelNoCS>::InternalRelease();
323     }
324 #endif
325 
326     CShellBrowser();
327     ~CShellBrowser();
328     HRESULT Initialize();
329 public:
330     UINT ApplyNewBrowserFlag(UINT Flags);
331     HRESULT OpenNewBrowserWindow(LPCITEMIDLIST pidl, UINT SbspFlags);
332     HRESULT CreateRelativeBrowsePIDL(LPCITEMIDLIST relative, UINT SbspFlags, LPITEMIDLIST *ppidl);
333     HRESULT BrowseToPIDL(LPCITEMIDLIST pidl, long flags);
334     HRESULT BrowseToPath(IShellFolder *newShellFolder, LPCITEMIDLIST absolutePIDL,
335         FOLDERSETTINGS *folderSettings, long flags);
336     void SaveViewState();
337     HRESULT GetMenuBand(REFIID riid, void **shellMenu);
338     HRESULT GetBaseBar(bool vertical, REFIID riid, void **theBaseBar);
339     BOOL IsBandLoaded(const CLSID clsidBand, bool vertical, DWORD *pdwBandID);
340     HRESULT ShowBand(const CLSID &classID, bool vertical);
341     HRESULT NavigateToParent();
342     HRESULT DoFolderOptions();
343     HRESULT ApplyBrowserDefaultFolderSettings(IShellView *pvs);
344     static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
345     void RepositionBars();
346     HRESULT BuildExplorerBandMenu();
347     HRESULT BuildExplorerBandCategory(HMENU hBandsMenu, CATID category, DWORD dwPos, UINT *nbFound);
348     BOOL IsBuiltinBand(CLSID &bandID);
GetWindowProc()349     virtual WNDPROC GetWindowProc()
350     {
351         return WindowProc;
352     }
353     HRESULT FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments);
354     HRESULT FireNavigateComplete(const wchar_t *newDirectory);
355     HRESULT FireCommandStateChange(bool newState, int commandID);
356     HRESULT FireCommandStateChangeAll();
357     HRESULT UpdateForwardBackState();
358     HRESULT UpdateUpState();
359     void UpdateGotoMenu(HMENU theMenu);
360     void UpdateViewMenu(HMENU theMenu);
361     HRESULT IsInternetToolbarBandShown(UINT ITId);
362     void RefreshCabinetState();
363     void UpdateWindowTitle();
364     void SaveITBarLayout();
365 
366 /*    // *** IDockingWindowFrame methods ***
367     STDMETHOD(AddToolbar)(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags) override;
368     STDMETHOD(RemoveToolbar)(IUnknown *punkSrc, DWORD dwRemoveFlags) override;
369     STDMETHOD(FindToolbar)(LPCWSTR pwszItem, REFIID riid, void **ppv) override;
370     */
371 
372     // *** IDockingWindowSite methods ***
373     STDMETHOD(GetBorderDW)(IUnknown* punkObj, LPRECT prcBorder) override;
374     STDMETHOD(RequestBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override;
375     STDMETHOD(SetBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override;
376 
377     // *** IOleCommandTarget methods ***
378     STDMETHOD(QueryStatus)(const GUID *pguidCmdGroup, ULONG cCmds,
379         OLECMD prgCmds[  ], OLECMDTEXT *pCmdText) override;
380     STDMETHOD(Exec)(const GUID *pguidCmdGroup, DWORD nCmdID,
381         DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override;
382 
383     // *** IOleWindow methods ***
384     STDMETHOD(GetWindow)(HWND *lphwnd) override;
385     STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override;
386 
387     // *** IShellBrowser methods ***
388     STDMETHOD(InsertMenusSB)(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) override;
389     STDMETHOD(SetMenuSB)(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject) override;
390     STDMETHOD(RemoveMenusSB)(HMENU hmenuShared) override;
391     STDMETHOD(SetStatusTextSB)(LPCOLESTR pszStatusText) override;
392     STDMETHOD(EnableModelessSB)(BOOL fEnable) override;
393     STDMETHOD(TranslateAcceleratorSB)(MSG *pmsg, WORD wID) override;
394     STDMETHOD(BrowseObject)(LPCITEMIDLIST pidl, UINT wFlags) override;
395     STDMETHOD(GetViewStateStream)(DWORD grfMode, IStream **ppStrm) override;
396     STDMETHOD(GetControlWindow)(UINT id, HWND *lphwnd) override;
397     STDMETHOD(SendControlMsg)(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) override;
398     STDMETHOD(QueryActiveShellView)(IShellView **ppshv) override;
399     STDMETHOD(OnViewWindowActive)(IShellView *ppshv) override;
400     STDMETHOD(SetToolbarItems)(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags) override;
401 
402     // *** IDropTarget methods ***
403     STDMETHOD(DragEnter)(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override;
404     STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override;
405     STDMETHOD(DragLeave)() override;
406     STDMETHOD(Drop)(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) override;
407 
408     // *** IServiceProvider methods ***
409     STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override;
410 
411     // *** IShellBrowserService methods ***
412     STDMETHOD(GetPropertyBag)(long flags, REFIID riid, void **ppvObject) override;
413 
414     // *** IDispatch methods ***
415     STDMETHOD(GetTypeInfoCount)(UINT *pctinfo) override;
416     STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override;
417     STDMETHOD(GetIDsOfNames)(
418         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) override;
419     STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
420         DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override;
421 
422     // *** IBrowserService methods ***
423     STDMETHOD(GetParentSite)(IOleInPlaceSite **ppipsite) override;
424     STDMETHOD(SetTitle)(IShellView *psv, LPCWSTR pszName) override;
425     STDMETHOD(GetTitle)(IShellView *psv, LPWSTR pszName, DWORD cchName) override;
426     STDMETHOD(GetOleObject)(IOleObject **ppobjv) override;
427     STDMETHOD(GetTravelLog)(ITravelLog **pptl) override;
428     STDMETHOD(ShowControlWindow)(UINT id, BOOL fShow) override;
429     STDMETHOD(IsControlWindowShown)(UINT id, BOOL *pfShown) override;
430     STDMETHOD(IEGetDisplayName)(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags) override;
431     STDMETHOD(IEParseDisplayName)(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut) override;
432     STDMETHOD(DisplayParseError)(HRESULT hres, LPCWSTR pwszPath) override;
433     STDMETHOD(NavigateToPidl)(LPCITEMIDLIST pidl, DWORD grfHLNF) override;
434     STDMETHOD(SetNavigateState)(BNSTATE bnstate) override;
435     STDMETHOD(GetNavigateState)(BNSTATE *pbnstate) override;
436     STDMETHOD(NotifyRedirect)(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse) override;
437     STDMETHOD(UpdateWindowList)() override;
438     STDMETHOD(UpdateBackForwardState)() override;
439     STDMETHOD(SetFlags)(DWORD dwFlags, DWORD dwFlagMask) override;
440     STDMETHOD(GetFlags)(DWORD *pdwFlags) override;
441     STDMETHOD(CanNavigateNow)( void) override;
442     STDMETHOD(GetPidl)(LPITEMIDLIST *ppidl) override;
443     STDMETHOD(SetReferrer)(LPCITEMIDLIST pidl) override;
444     STDMETHOD_(DWORD, GetBrowserIndex)() override;
445     STDMETHOD(GetBrowserByIndex)(DWORD dwID, IUnknown **ppunk) override;
446     STDMETHOD(GetHistoryObject)(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc) override;
447     STDMETHOD(SetHistoryObject)(IOleObject *pole, BOOL fIsLocalAnchor) override;
448     STDMETHOD(CacheOLEServer)(IOleObject *pole) override;
449     STDMETHOD(GetSetCodePage)(VARIANT *pvarIn, VARIANT *pvarOut) override;
450     STDMETHOD(OnHttpEquiv)(IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut) override;
451     STDMETHOD(GetPalette)(HPALETTE *hpal) override;
452     STDMETHOD(RegisterWindow)(BOOL fForceRegister, int swc) override;
453 
454     // *** IBrowserService2 methods ***
455     STDMETHOD_(LRESULT, WndProcBS)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
456     STDMETHOD(SetAsDefFolderSettings)() override;
457     STDMETHOD(GetViewRect)(RECT *prc) override;
458     STDMETHOD(OnSize)(WPARAM wParam) override;
459     STDMETHOD(OnCreate)(struct tagCREATESTRUCTW *pcs) override;
460     STDMETHOD_(LRESULT, OnCommand)(WPARAM wParam, LPARAM lParam) override;
461     STDMETHOD(OnDestroy)() override;
462     STDMETHOD_(LRESULT, OnNotify)(struct tagNMHDR *pnm) override;
463     STDMETHOD(OnSetFocus)() override;
464     STDMETHOD(OnFrameWindowActivateBS)(BOOL fActive) override;
465     STDMETHOD(ReleaseShellView)() override;
466     STDMETHOD(ActivatePendingView)() override;
467     STDMETHOD(CreateViewWindow)(IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd) override;
468     STDMETHOD(CreateBrowserPropSheetExt)(REFIID riid, void **ppv) override;
469     STDMETHOD(GetViewWindow)(HWND *phwndView) override;
470     STDMETHOD(GetBaseBrowserData)(LPCBASEBROWSERDATA *pbbd) override;
471     STDMETHOD_(LPBASEBROWSERDATA, PutBaseBrowserData)(void) override;
472     STDMETHOD(InitializeTravelLog)(ITravelLog *ptl, DWORD dw) override;
473     STDMETHOD(SetTopBrowser)() override;
474     STDMETHOD(Offline)(int iCmd) override;
475     STDMETHOD(AllowViewResize)(BOOL f) override;
476     STDMETHOD(SetActivateState)(UINT u) override;
477     STDMETHOD(UpdateSecureLockIcon)(int eSecureLock) override;
478     STDMETHOD(InitializeDownloadManager)() override;
479     STDMETHOD(InitializeTransitionSite)() override;
480     STDMETHOD(_Initialize)(HWND hwnd, IUnknown *pauto) override;
481     STDMETHOD(_CancelPendingNavigationAsync)( void) override;
482     STDMETHOD(_CancelPendingView)() override;
483     STDMETHOD(_MaySaveChanges)() override;
484     STDMETHOD(_PauseOrResumeView)(BOOL fPaused) override;
485     STDMETHOD(_DisableModeless)() override;
486     STDMETHOD(_NavigateToPidl)(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags) override;
487     STDMETHOD(_TryShell2Rename)(IShellView *psv, LPCITEMIDLIST pidlNew) override;
488     STDMETHOD(_SwitchActivationNow)() override;
489     STDMETHOD(_ExecChildren)(IUnknown *punkBar, BOOL fBroadcast, const GUID *pguidCmdGroup,
490         DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut) override;
491     STDMETHOD(_SendChildren)(
492         HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
493     STDMETHOD(GetFolderSetData)(struct tagFolderSetData *pfsd) override;
494     STDMETHOD(_OnFocusChange)(UINT itb) override;
495     STDMETHOD(v_ShowHideChildWindows)(BOOL fChildOnly) override;
496     STDMETHOD_(UINT, _get_itbLastFocus)() override;
497     STDMETHOD(_put_itbLastFocus)(UINT itbLastFocus) override;
498     STDMETHOD(_UIActivateView)(UINT uState) override;
499     STDMETHOD(_GetViewBorderRect)(RECT *prc) override;
500     STDMETHOD(_UpdateViewRectSize)() override;
501     STDMETHOD(_ResizeNextBorder)(UINT itb) override;
502     STDMETHOD(_ResizeView)() override;
503     STDMETHOD(_GetEffectiveClientArea)(LPRECT lprectBorder, HMONITOR hmon) override;
504     STDMETHOD_(IStream *, v_GetViewStream)(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName) override;
505     STDMETHOD_(LRESULT, ForwardViewMsg)(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
506     STDMETHOD(SetAcceleratorMenu)(HACCEL hacc) override;
507     STDMETHOD_(int, _GetToolbarCount)() override;
508     STDMETHOD_(LPTOOLBARITEM, _GetToolbarItem)(int itb) override;
509     STDMETHOD(_SaveToolbars)(IStream *pstm) override;
510     STDMETHOD(_LoadToolbars)(IStream *pstm) override;
511     STDMETHOD(_CloseAndReleaseToolbars)(BOOL fClose) override;
512     STDMETHOD(v_MayGetNextToolbarFocus)(LPMSG lpMsg, UINT itbNext,
513         int citb, LPTOOLBARITEM *pptbi, HWND *phwnd) override;
514     STDMETHOD(_ResizeNextBorderHelper)(UINT itb, BOOL bUseHmonitor) override;
515     STDMETHOD_(UINT, _FindTBar)(IUnknown *punkSrc) override;
516     STDMETHOD(_SetFocus)(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg) override;
517     STDMETHOD(v_MayTranslateAccelerator)(MSG *pmsg) override;
518     STDMETHOD(_GetBorderDWHelper)(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor) override;
519     STDMETHOD(v_CheckZoneCrossing)(LPCITEMIDLIST pidl) override;
520 
521     // *** IWebBrowser methods ***
522     STDMETHOD(GoBack)() override;
523     STDMETHOD(GoForward)() override;
524     STDMETHOD(GoHome)() override;
525     STDMETHOD(GoSearch)() override;
526     STDMETHOD(Navigate)(BSTR URL, VARIANT *Flags, VARIANT *TargetFrameName,
527         VARIANT *PostData, VARIANT *Headers) override;
528     STDMETHOD(Refresh)() override;
529     STDMETHOD(Refresh2)(VARIANT *Level) override;
530     STDMETHOD(Stop)() override;
531     STDMETHOD(get_Application)(IDispatch **ppDisp) override;
532     STDMETHOD(get_Parent)(IDispatch **ppDisp) override;
533     STDMETHOD(get_Container)(IDispatch **ppDisp) override;
534     STDMETHOD(get_Document)(IDispatch **ppDisp) override;
535     STDMETHOD(get_TopLevelContainer)(VARIANT_BOOL *pBool) override;
536     STDMETHOD(get_Type)(BSTR *Type) override;
537     STDMETHOD(get_Left)(long *pl) override;
538     STDMETHOD(put_Left)(long Left) override;
539     STDMETHOD(get_Top)(long *pl) override;
540     STDMETHOD(put_Top)(long Top) override;
541     STDMETHOD(get_Width)(long *pl) override;
542     STDMETHOD(put_Width)(long Width) override;
543     STDMETHOD(get_Height)(long *pl) override;
544     STDMETHOD(put_Height)(long Height) override;
545     STDMETHOD(get_LocationName)(BSTR *LocationName) override;
546     STDMETHOD(get_LocationURL)(BSTR *LocationURL) override;
547     STDMETHOD(get_Busy)(VARIANT_BOOL *pBool) override;
548 
549     // *** IWebBrowserApp methods ***
550     STDMETHOD(Quit)() override;
551     STDMETHOD(ClientToWindow)(int *pcx, int *pcy) override;
552     STDMETHOD(PutProperty)(BSTR Property, VARIANT vtValue) override;
553     STDMETHOD(GetProperty)(BSTR Property, VARIANT *pvtValue) override;
554     STDMETHOD(get_Name)(BSTR *Name) override;
555     STDMETHOD(get_HWND)(SHANDLE_PTR *pHWND) override;
556     STDMETHOD(get_FullName)(BSTR *FullName) override;
557     STDMETHOD(get_Path)(BSTR *Path) override;
558     STDMETHOD(get_Visible)(VARIANT_BOOL *pBool) override;
559     STDMETHOD(put_Visible)(VARIANT_BOOL Value) override;
560     STDMETHOD(get_StatusBar)(VARIANT_BOOL *pBool) override;
561     STDMETHOD(put_StatusBar)(VARIANT_BOOL Value) override;
562     STDMETHOD(get_StatusText)(BSTR *StatusText) override;
563     STDMETHOD(put_StatusText)(BSTR StatusText) override;
564     STDMETHOD(get_ToolBar)(int *Value) override;
565     STDMETHOD(put_ToolBar)(int Value) override;
566     STDMETHOD(get_MenuBar)(VARIANT_BOOL *Value) override;
567     STDMETHOD(put_MenuBar)(VARIANT_BOOL Value) override;
568     STDMETHOD(get_FullScreen)(VARIANT_BOOL *pbFullScreen) override;
569     STDMETHOD(put_FullScreen)(VARIANT_BOOL bFullScreen) override;
570 
571     // *** IWebBrowser2 methods ***
572     STDMETHOD(Navigate2)(VARIANT *URL, VARIANT *Flags, VARIANT *TargetFrameName,
573         VARIANT *PostData, VARIANT *Headers) override;
574     STDMETHOD(QueryStatusWB)(OLECMDID cmdID, OLECMDF *pcmdf) override;
575     STDMETHOD(ExecWB)(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
576         VARIANT *pvaIn, VARIANT *pvaOut) override;
577     STDMETHOD(ShowBrowserBar)(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize) override;
578     STDMETHOD(get_ReadyState)(READYSTATE *plReadyState) override;
579     STDMETHOD(get_Offline)(VARIANT_BOOL *pbOffline) override;
580     STDMETHOD(put_Offline)(VARIANT_BOOL bOffline) override;
581     STDMETHOD(get_Silent)(VARIANT_BOOL *pbSilent) override;
582     STDMETHOD(put_Silent)(VARIANT_BOOL bSilent) override;
583     STDMETHOD(get_RegisterAsBrowser)(VARIANT_BOOL *pbRegister) override;
584     STDMETHOD(put_RegisterAsBrowser)(VARIANT_BOOL bRegister) override;
585     STDMETHOD(get_RegisterAsDropTarget)(VARIANT_BOOL *pbRegister) override;
586     STDMETHOD(put_RegisterAsDropTarget)(VARIANT_BOOL bRegister) override;
587     STDMETHOD(get_TheaterMode)(VARIANT_BOOL *pbRegister) override;
588     STDMETHOD(put_TheaterMode)(VARIANT_BOOL bRegister) override;
589     STDMETHOD(get_AddressBar)(VARIANT_BOOL *Value) override;
590     STDMETHOD(put_AddressBar)(VARIANT_BOOL Value) override;
591     STDMETHOD(get_Resizable)(VARIANT_BOOL *Value) override;
592     STDMETHOD(put_Resizable)(VARIANT_BOOL Value) override;
593 
594     // *** ITravelLogClient methods ***
595     STDMETHOD(FindWindowByIndex)(DWORD dwID, IUnknown **ppunk) override;
596     STDMETHOD(GetWindowData)(IStream *pStream, LPWINDOWDATA pWinData) override;
597     STDMETHOD(LoadHistoryPosition)(LPWSTR pszUrlLocation, DWORD dwPosition) override;
598 
599     // *** IPersist methods ***
600     STDMETHOD(GetClassID)(CLSID *pClassID) override;
601 
602     // *** IPersistHistory methods ***
603     STDMETHOD(LoadHistory)(IStream *pStream, IBindCtx *pbc) override;
604     STDMETHOD(SaveHistory)(IStream *pStream) override;
605     STDMETHOD(SetPositionCookie)(DWORD dwPositioncookie) override;
606     STDMETHOD(GetPositionCookie)(DWORD *pdwPositioncookie) override;
607 
608     // message handlers
609     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
610     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
611     LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
612     LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
613     LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
614     LRESULT RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
615     LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
616     LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
617     LRESULT OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
618     LRESULT OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
619     LRESULT OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
620     LRESULT OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
621     LRESULT OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
622     LRESULT OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
623     LRESULT OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
624     LRESULT OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
625     LRESULT OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
626     LRESULT OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
627     LRESULT OnAddToFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
628     LRESULT OnOrganizeFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
629     LRESULT OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
630     LRESULT OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
631     LRESULT OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
632     LRESULT OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
633     LRESULT OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
634     LRESULT OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
635     LRESULT OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
636     LRESULT OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
637     LRESULT OnRefresh(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
638     LRESULT OnExplorerBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
639     LRESULT RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
640     LRESULT OnCabinetStateChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
641     LRESULT OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
642     LRESULT OnGetSettingsPtr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
643     LRESULT OnAppCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
644     HRESULT OnSearch();
645 
GetWndClassInfo()646     static ATL::CWndClassInfo& GetWndClassInfo()
647     {
648         static ATL::CWndClassInfo wc =
649         {
650             { sizeof(WNDCLASSEX), CS_DBLCLKS, StartWindowProc,
651               0, 0, NULL, LoadIcon(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDI_CABINET)),
652               LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, szCabinetWndClass, NULL },
653             NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
654         };
655         return wc;
656     }
657 
658     BEGIN_MSG_MAP(CShellBrowser)
659         MESSAGE_HANDLER(WM_CREATE, OnCreate)
660         MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
661         MESSAGE_HANDLER(WM_SIZE, OnSize)
662         MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
663         MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
664         MESSAGE_HANDLER(WM_MEASUREITEM, RelayMsgToShellView)
665         MESSAGE_HANDLER(WM_DRAWITEM, RelayMsgToShellView)
666         MESSAGE_HANDLER(WM_MENUSELECT, RelayMsgToShellView)
667         MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
668         MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
669         COMMAND_ID_HANDLER(IDM_FILE_CLOSE, OnClose)
670         COMMAND_ID_HANDLER(IDM_TOOLS_FOLDEROPTIONS, OnFolderOptions)
671         COMMAND_ID_HANDLER(IDM_TOOLS_MAPNETWORKDRIVE, OnMapNetworkDrive)
672         COMMAND_ID_HANDLER(IDM_TOOLS_DISCONNECTNETWORKDRIVE, OnDisconnectNetworkDrive)
673         COMMAND_ID_HANDLER(IDM_HELP_ABOUT, OnAboutReactOS)
674         COMMAND_ID_HANDLER(IDM_GOTO_BACK, OnGoBack)
675         COMMAND_ID_HANDLER(IDM_GOTO_FORWARD, OnGoForward)
676         COMMAND_ID_HANDLER(IDM_GOTO_UPONELEVEL, OnGoUpLevel)
677         COMMAND_ID_HANDLER(IDM_GOTO_HOMEPAGE, OnGoHome)
678         COMMAND_ID_HANDLER(IDM_FAVORITES_ADDTOFAVORITES, OnAddToFavorites)
679         COMMAND_ID_HANDLER(IDM_FAVORITES_ORGANIZEFAVORITES, OnOrganizeFavorites)
680         COMMAND_ID_HANDLER(IDM_VIEW_STATUSBAR, OnToggleStatusBarVisible)
681         COMMAND_ID_HANDLER(IDM_VIEW_REFRESH, OnRefresh)
682         COMMAND_ID_HANDLER(IDM_TOOLBARS_LOCKTOOLBARS, OnToggleToolbarLock)
683         COMMAND_ID_HANDLER(IDM_TOOLBARS_STANDARDBUTTONS, OnToggleToolbarBandVisible)
684         COMMAND_ID_HANDLER(IDM_TOOLBARS_ADDRESSBAR, OnToggleAddressBandVisible)
685         COMMAND_ID_HANDLER(IDM_TOOLBARS_LINKSBAR, OnToggleLinksBandVisible)
686         COMMAND_ID_HANDLER(IDM_TOOLBARS_TEXTLABELS, OnToggleTextLabels)
687         COMMAND_ID_HANDLER(IDM_TOOLBARS_CUSTOMIZE, OnToolbarCustomize)
688         COMMAND_ID_HANDLER(IDM_EXPLORERBAR_SEARCH, OnExplorerBar)
689         COMMAND_ID_HANDLER(IDM_EXPLORERBAR_FOLDERS, OnExplorerBar)
690         COMMAND_ID_HANDLER(IDM_EXPLORERBAR_HISTORY, OnExplorerBar)
691         COMMAND_ID_HANDLER(IDM_EXPLORERBAR_FAVORITES, OnExplorerBar)
692         COMMAND_ID_HANDLER(IDM_BACKSPACE, OnBackspace)
693         COMMAND_RANGE_HANDLER(IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, OnGoTravel)
694         COMMAND_RANGE_HANDLER(IDM_EXPLORERBAND_BEGINCUSTOM, IDM_EXPLORERBAND_ENDCUSTOM, OnExplorerBar)
695         MESSAGE_HANDLER(WM_COMMAND, RelayCommands)
696         MESSAGE_HANDLER(CWM_STATECHANGE, OnCabinetStateChange)
697         MESSAGE_HANDLER(BWM_SETTINGCHANGE, OnSettingsChange)
698         MESSAGE_HANDLER(BWM_GETSETTINGSPTR, OnGetSettingsPtr)
699         MESSAGE_HANDLER(WM_APPCOMMAND, OnAppCommand)
700     END_MSG_MAP()
701 
702     BEGIN_CONNECTION_POINT_MAP(CShellBrowser)
703         CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents2)
704         CONNECTION_POINT_ENTRY(DIID_DWebBrowserEvents)
705     END_CONNECTION_POINT_MAP()
706 
707     BEGIN_COM_MAP(CShellBrowser)
708         COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
709         COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
710         COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDockingWindowSite)
711         COM_INTERFACE_ENTRY_IID(IID_IShellBrowser, IShellBrowser)
712         COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
713         COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
714         COM_INTERFACE_ENTRY_IID(IID_IProfferService, IProfferService)
715         COM_INTERFACE_ENTRY_IID(IID_IShellBrowserService, IShellBrowserService)
716         COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch)
717         COM_INTERFACE_ENTRY_IID(IID_IConnectionPointContainer, IConnectionPointContainer)
718         COM_INTERFACE_ENTRY_IID(IID_IWebBrowser, IWebBrowser)
719         COM_INTERFACE_ENTRY_IID(IID_IWebBrowserApp, IWebBrowserApp)
720         COM_INTERFACE_ENTRY_IID(IID_IWebBrowser2, IWebBrowser2)
721         COM_INTERFACE_ENTRY_IID(IID_ITravelLogClient, ITravelLogClient)
722         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
723         COM_INTERFACE_ENTRY_IID(IID_IPersistHistory, IPersistHistory)
724         COM_INTERFACE_ENTRY_IID(IID_IBrowserService, IBrowserService)
725         COM_INTERFACE_ENTRY_IID(IID_IBrowserService2, IBrowserService2)
726     END_COM_MAP()
727 };
728 
729 extern HRESULT CreateProgressDialog(REFIID riid, void **ppv);
730 
CShellBrowser()731 CShellBrowser::CShellBrowser()
732 {
733     m_BrowserSvcFlags = BSF_RESIZABLE | BSF_CANMAXIMIZE;
734     m_Destroyed = false;
735     fCurrentShellViewWindow = NULL;
736     fCurrentDirectoryPIDL = NULL;
737     fStatusBar = NULL;
738     fCurrentMenuBar = NULL;
739     fHistoryObject = NULL;
740     fHistoryStream = NULL;
741     fHistoryBindContext = NULL;
742     m_settings.Load();
743     m_deffoldersettings.Load();
744     gCabinetState.Load();
745     SetTopBrowser();
746 }
747 
~CShellBrowser()748 CShellBrowser::~CShellBrowser()
749 {
750     if (menuDsa)
751         DSA_Destroy(menuDsa);
752 }
753 
Initialize()754 HRESULT CShellBrowser::Initialize()
755 {
756     CComPtr<IPersistStreamInit>             persistStreamInit;
757     HRESULT                                 hResult;
758     CComPtr<IUnknown> clientBar;
759 
760     _AtlInitialConstruct();
761 
762     menuDsa = DSA_Create(sizeof(MenuBandInfo), 5);
763     if (!menuDsa)
764         return E_OUTOFMEMORY;
765 
766     // create window
767     Create(HWND_DESKTOP);
768     if (m_hWnd == NULL)
769         return E_FAIL;
770 
771     hResult = CInternetToolbar_CreateInstance(IID_PPV_ARG(IUnknown, &clientBar));
772     if (FAILED_UNEXPECTEDLY(hResult))
773         return hResult;
774 
775     fClientBars[BIInternetToolbar].clientBar = clientBar;
776 
777     // create interfaces
778     hResult = clientBar->QueryInterface(IID_PPV_ARG(IPersistStreamInit, &persistStreamInit));
779     if (FAILED_UNEXPECTEDLY(hResult))
780         return hResult;
781 
782     hResult = IUnknown_SetSite(clientBar, static_cast<IShellBrowser *>(this));
783     if (FAILED_UNEXPECTEDLY(hResult))
784         return hResult;
785 
786     hResult = IUnknown_Exec(clientBar, CGID_PrivCITCommands, 1, 1 /* or 0 */, NULL, NULL);
787     if (FAILED_UNEXPECTEDLY(hResult))
788         return hResult;
789 
790     CComPtr<IStream> pITBarStream;
791     hResult = CInternetToolbar::GetStream(ITBARSTREAM_EXPLORER, STGM_READ, &pITBarStream);
792     hResult = SUCCEEDED(hResult) ? persistStreamInit->Load(pITBarStream) : persistStreamInit->InitNew();
793     if (FAILED_UNEXPECTEDLY(hResult))
794         return hResult;
795 
796     hResult = IUnknown_ShowDW(clientBar, TRUE);
797     if (FAILED_UNEXPECTEDLY(hResult))
798         return hResult;
799 
800     fToolbarProxy.Initialize(m_hWnd, clientBar);
801 
802     // create status bar
803     DWORD dwStatusStyle = WS_CHILD | WS_CLIPSIBLINGS | SBARS_SIZEGRIP | SBARS_TOOLTIPS;
804     if (m_settings.fStatusBarVisible)
805         dwStatusStyle |= WS_VISIBLE;
806     fStatusBar = ::CreateWindowExW(0, STATUSCLASSNAMEW, NULL, dwStatusStyle,
807                                    0, 0, 500, 20, m_hWnd, (HMENU)IDC_STATUSBAR,
808                                    _AtlBaseModule.GetModuleInstance(), 0);
809 
810     ShowWindow(SW_SHOWNORMAL);
811     UpdateWindow();
812 
813     return S_OK;
814 }
815 
ApplyBrowserDefaultFolderSettings(IShellView * pvs)816 HRESULT CShellBrowser::ApplyBrowserDefaultFolderSettings(IShellView *pvs)
817 {
818     HRESULT hr;
819     if (pvs)
820     {
821         m_settings.Save();
822         SBFOLDERSETTINGS &sbfs = m_deffoldersettings, defsbfs;
823         if (FAILED(pvs->GetCurrentInfo(&sbfs.FolderSettings)))
824         {
825             defsbfs.InitializeDefaults();
826             sbfs = defsbfs;
827         }
828         hr = CGlobalFolderSettings::SaveBrowserSettings(sbfs);
829     }
830     else
831     {
832         m_settings.Reset();
833         hr = CGlobalFolderSettings::ResetBrowserSettings();
834         if (SUCCEEDED(hr))
835             m_deffoldersettings.Load();
836     }
837     return hr;
838 }
839 
ApplyNewBrowserFlag(UINT Flags)840 UINT CShellBrowser::ApplyNewBrowserFlag(UINT Flags)
841 {
842     if ((Flags & (SBSP_SAMEBROWSER | SBSP_NEWBROWSER)) == SBSP_DEFBROWSER)
843     {
844         if (!fCurrentDirectoryPIDL || IsControlWindowShown(FCW_TREE, NULL) == S_OK)
845             Flags |= SBSP_SAMEBROWSER; // Force if this is the first navigation or the folder tree is present
846         else
847             Flags |= (!!gCabinetState.fNewWindowMode) ^ (GetAsyncKeyState(VK_CONTROL) < 0) ? SBSP_NEWBROWSER : SBSP_SAMEBROWSER;
848     }
849     if (Flags & (SBSP_NAVIGATEBACK | SBSP_NAVIGATEFORWARD))
850         Flags = (Flags & ~SBSP_NEWBROWSER) | SBSP_SAMEBROWSER; // Force same browser for now
851     return Flags;
852 }
853 
OpenNewBrowserWindow(LPCITEMIDLIST pidl,UINT SbspFlags)854 HRESULT CShellBrowser::OpenNewBrowserWindow(LPCITEMIDLIST pidl, UINT SbspFlags)
855 {
856     SaveITBarLayout(); // Do this now so the new window inherits the current layout
857     // TODO: www.geoffchappell.com/studies/windows/ie/shdocvw/interfaces/inotifyappstart.htm
858     DWORD flags = (SbspFlags & SBSP_EXPLOREMODE) ? SH_EXPLORER_CMDLINE_FLAG_E : 0;
859     if ((SbspFlags & (SBSP_OPENMODE | SBSP_EXPLOREMODE)) == SBSP_DEFMODE)
860         flags |= IsControlWindowShown(FCW_TREE, NULL) == S_OK ? SH_EXPLORER_CMDLINE_FLAG_E : 0;
861     LPITEMIDLIST pidlDir;
862     HRESULT hr = SHILClone(pidl, &pidlDir);
863     if (FAILED(hr))
864         return hr;
865     // TODO: !SBSP_NOTRANSFERHIST means we are supposed to pass the history here somehow?
866     return SHOpenNewFrame(pidlDir, NULL, 0, flags | SH_EXPLORER_CMDLINE_FLAG_NEWWND | SH_EXPLORER_CMDLINE_FLAG_NOREUSE);
867 }
868 
CreateRelativeBrowsePIDL(LPCITEMIDLIST relative,UINT SbspFlags,LPITEMIDLIST * ppidl)869 HRESULT CShellBrowser::CreateRelativeBrowsePIDL(LPCITEMIDLIST relative, UINT SbspFlags, LPITEMIDLIST *ppidl)
870 {
871     if (SbspFlags & SBSP_RELATIVE)
872         return SHILCombine(fCurrentDirectoryPIDL, relative, ppidl);
873 
874     if (SbspFlags & SBSP_PARENT)
875     {
876         HRESULT hr = GetPidl(ppidl);
877         if (FAILED(hr))
878             return hr;
879         ILRemoveLastID(*ppidl);
880         return S_OK;
881     }
882     // TODO: SBSP_NAVIGATEBACK and SBSP_NAVIGATEFORWARD?
883     return E_UNEXPECTED;
884 }
885 
BrowseToPIDL(LPCITEMIDLIST pidl,long flags)886 HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags)
887 {
888     CComPtr<IShellFolder>   newFolder;
889     FOLDERSETTINGS          newFolderSettings = m_deffoldersettings.FolderSettings;
890     HRESULT                 hResult;
891     CLSID                   clsid;
892     BOOL                    HasIconViewType;
893 
894     // called by shell view to browse to new folder
895     // also called by explorer band to navigate to new folder
896     hResult = SHBindToFolder(pidl, &newFolder);
897     if (FAILED_UNEXPECTEDLY(hResult))
898         return hResult;
899     // HACK & FIXME: Get view mode from shellbag when fully implemented.
900     IUnknown_GetClassID(newFolder, &clsid);
901     HasIconViewType = clsid == CLSID_MyComputer || clsid == CLSID_ControlPanel ||
902                       clsid == CLSID_ShellDesktop;
903 
904     if (HasIconViewType)
905         newFolderSettings.ViewMode = FVM_ICON;
906     hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags);
907     if (FAILED_UNEXPECTEDLY(hResult))
908         return hResult;
909     return S_OK;
910 }
911 
_ILIsPidlSimple(LPCITEMIDLIST pidl)912 BOOL WINAPI _ILIsPidlSimple(LPCITEMIDLIST pidl)
913 {
914     LPCITEMIDLIST                           pidlnext;
915     WORD                                    length;
916     BOOL                                    ret;
917 
918     ret = TRUE;
919     if (! _ILIsDesktop(pidl))
920     {
921         length = pidl->mkid.cb;
922         pidlnext =
923             reinterpret_cast<LPCITEMIDLIST>(
924                 reinterpret_cast<const BYTE *>(pidl) + length);
925         if (pidlnext->mkid.cb != 0)
926             ret = FALSE;
927     }
928     return ret;
929 }
930 
SHBindToFolderIDListParent(IShellFolder * unused,LPCITEMIDLIST pidl,const IID * riid,LPVOID * ppv,LPITEMIDLIST * ppidlLast)931 HRESULT WINAPI SHBindToFolderIDListParent(IShellFolder *unused, LPCITEMIDLIST pidl,
932     const IID *riid, LPVOID *ppv, LPITEMIDLIST *ppidlLast)
933 {
934     CComPtr<IShellFolder>                   psf;
935     LPITEMIDLIST                            pidlChild;
936     LPITEMIDLIST                            pidlParent;
937     HRESULT                                 hResult;
938 
939     hResult = E_FAIL;
940     if (ppv == NULL)
941         return E_POINTER;
942     *ppv = NULL;
943     if (ppidlLast != NULL)
944         *ppidlLast = NULL;
945     if (_ILIsPidlSimple(pidl))
946     {
947         if (ppidlLast != NULL)
948             *ppidlLast = ILClone(pidl);
949         hResult = SHGetDesktopFolder((IShellFolder **)ppv);
950     }
951     else
952     {
953         pidlChild = ILClone(ILFindLastID(pidl));
954         pidlParent = ILClone(pidl);
955         ILRemoveLastID(pidlParent);
956         hResult = SHGetDesktopFolder(&psf);
957         if (SUCCEEDED(hResult))
958             hResult = psf->BindToObject(pidlParent, NULL, *riid, ppv);
959         if (SUCCEEDED(hResult) && ppidlLast != NULL)
960             *ppidlLast = pidlChild;
961         else
962             ILFree(pidlChild);
963         ILFree(pidlParent);
964     }
965     return hResult;
966 }
967 
IEGetNameAndFlagsEx(LPITEMIDLIST pidl,SHGDNF uFlags,long param10,LPWSTR pszBuf,UINT cchBuf,SFGAOF * rgfInOut)968 HRESULT IEGetNameAndFlagsEx(LPITEMIDLIST pidl, SHGDNF uFlags, long param10,
969     LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
970 {
971     CComPtr<IShellFolder>                   parentFolder;
972     LPITEMIDLIST                            childPIDL = NULL;
973     STRRET                                  L108;
974     HRESULT                                 hResult;
975 
976     hResult = SHBindToFolderIDListParent(NULL, pidl, &IID_PPV_ARG(IShellFolder, &parentFolder), &childPIDL);
977     if (FAILED(hResult))
978         goto cleanup;
979 
980     hResult = parentFolder->GetDisplayNameOf(childPIDL, uFlags, &L108);
981     if (FAILED(hResult))
982         goto cleanup;
983 
984     StrRetToBufW(&L108, childPIDL, pszBuf, cchBuf);
985     if (rgfInOut)
986     {
987         hResult = parentFolder->GetAttributesOf(1, const_cast<LPCITEMIDLIST *>(&childPIDL), rgfInOut);
988         if (FAILED(hResult))
989             goto cleanup;
990     }
991 
992     hResult = S_OK;
993 
994 cleanup:
995     if (childPIDL)
996         ILFree(childPIDL);
997     return hResult;
998 }
999 
IEGetNameAndFlags(LPITEMIDLIST pidl,SHGDNF uFlags,LPWSTR pszBuf,UINT cchBuf,SFGAOF * rgfInOut)1000 HRESULT IEGetNameAndFlags(LPITEMIDLIST pidl, SHGDNF uFlags, LPWSTR pszBuf, UINT cchBuf, SFGAOF *rgfInOut)
1001 {
1002     return IEGetNameAndFlagsEx(pidl, uFlags, 0, pszBuf, cchBuf, rgfInOut);
1003 }
1004 
SaveViewState()1005 void CShellBrowser::SaveViewState()
1006 {
1007     // TODO: Also respect EBO_NOPERSISTVIEWSTATE?
1008     if (gCabinetState.fSaveLocalView && fCurrentShellView && !SHRestricted(REST_NOSAVESET))
1009         fCurrentShellView->SaveViewState();
1010 }
1011 
BrowseToPath(IShellFolder * newShellFolder,LPCITEMIDLIST absolutePIDL,FOLDERSETTINGS * folderSettings,long flags)1012 HRESULT CShellBrowser::BrowseToPath(IShellFolder *newShellFolder,
1013     LPCITEMIDLIST absolutePIDL, FOLDERSETTINGS *folderSettings, long flags)
1014 {
1015     CComPtr<IShellFolder>                   saveCurrentShellFolder;
1016     CComPtr<IShellView>                     saveCurrentShellView;
1017     CComPtr<IShellView>                     newShellView;
1018     CComPtr<ITravelLog>                     travelLog;
1019     HWND                                    newShellViewWindow;
1020     BOOL                                    windowUpdateIsLocked;
1021     RECT                                    shellViewWindowBounds;
1022     HWND                                    previousView;
1023     HCURSOR                                 saveCursor;
1024     wchar_t                                 newTitle[MAX_PATH];
1025     SHGDNF                                  nameFlags;
1026     HRESULT                                 hResult;
1027     //TODO: BOOL                            nohistory = m_BrowserSvcFlags & BSF_NAVNOHISTORY;
1028 
1029     if (m_Destroyed)
1030         return S_FALSE;
1031 
1032     if (newShellFolder == NULL)
1033         return E_INVALIDARG;
1034 
1035     hResult = GetTravelLog(&travelLog);
1036     if (FAILED_UNEXPECTEDLY(hResult))
1037         return hResult;
1038 
1039     if (FAILED_UNEXPECTEDLY(hResult = SHILClone(absolutePIDL, &absolutePIDL)))
1040         return hResult;
1041     CComHeapPtr<ITEMIDLIST> pidlAbsoluteClone(const_cast<LPITEMIDLIST>(absolutePIDL));
1042 
1043     // update history
1044     if (flags & BTP_UPDATE_CUR_HISTORY)
1045     {
1046         if (travelLog->CountEntries(static_cast<IDropTarget *>(this)) > 0)
1047             hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
1048         // what to do with error? Do we want to halt browse because state save failed?
1049     }
1050 
1051     if (fCurrentShellView)
1052     {
1053         SaveViewState();
1054         fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
1055     }
1056 
1057     // create view object
1058     hResult = newShellFolder->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, &newShellView));
1059     if (FAILED_UNEXPECTEDLY(hResult))
1060         return hResult;
1061     previousView = fCurrentShellViewWindow;
1062 
1063     // enter updating section
1064     saveCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
1065     windowUpdateIsLocked = LockWindowUpdate(TRUE);
1066     if (fCurrentShellView != NULL)
1067         ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 0, 0);
1068 
1069     // set site
1070     hResult = IUnknown_SetSite(newShellView, static_cast<IDropTarget *>(this));
1071 
1072     // update folder and view
1073     saveCurrentShellFolder = fCurrentShellFolder;
1074     saveCurrentShellView = fCurrentShellView;
1075     fCurrentShellFolder = newShellFolder;
1076     fCurrentShellView = newShellView;
1077 
1078     // get boundary
1079     if (previousView != NULL)
1080         ::GetWindowRect(previousView, &shellViewWindowBounds);
1081     else
1082         ZeroMemory(&shellViewWindowBounds, sizeof(shellViewWindowBounds));
1083     ::MapWindowPoints(0, m_hWnd, reinterpret_cast<POINT *>(&shellViewWindowBounds), 2);
1084 
1085     // update current pidl
1086     ILFree(fCurrentDirectoryPIDL);
1087     fCurrentDirectoryPIDL = pidlAbsoluteClone.Detach();
1088     /* CORE-19697: CAddressEditBox::OnWinEvent(CBN_SELCHANGE) causes CAddressEditBox to
1089      * call BrowseObject(pidlLastParsed). As part of our browsing we call FireNavigateComplete
1090      * and this in turn causes CAddressEditBox::Invoke to ILFree(pidlLastParsed)!
1091      * We then call SHBindToParent on absolutePIDL (which is really (the now invalid) pidlLastParsed) and we
1092      * end up accessing invalid memory! We therefore set absolutePIDL to be our cloned PIDL here.
1093      */
1094     absolutePIDL = fCurrentDirectoryPIDL;
1095 
1096     // create view window
1097     hResult = newShellView->CreateViewWindow(saveCurrentShellView, folderSettings,
1098         this, &shellViewWindowBounds, &newShellViewWindow);
1099     if (FAILED_UNEXPECTEDLY(hResult) || newShellViewWindow == NULL)
1100     {
1101         fCurrentShellView = saveCurrentShellView;
1102         fCurrentShellFolder = saveCurrentShellFolder;
1103         ::SendMessage(fCurrentShellViewWindow, WM_SETREDRAW, 1, 0);
1104         if (windowUpdateIsLocked)
1105             LockWindowUpdate(FALSE);
1106         SetCursor(saveCursor);
1107         return hResult;
1108     }
1109 
1110     // update view window
1111     if (saveCurrentShellView != NULL)
1112         saveCurrentShellView->DestroyViewWindow();
1113     fCurrentShellViewWindow = newShellViewWindow;
1114 
1115     if (previousView == NULL)
1116     {
1117         RepositionBars();
1118     }
1119 
1120     // no use
1121     saveCurrentShellView.Release();
1122     saveCurrentShellFolder.Release();
1123 
1124     hResult = newShellView->UIActivate((flags & BTP_ACTIVATE_NOFOCUS) ? SVUIA_ACTIVATE_NOFOCUS : SVUIA_ACTIVATE_FOCUS);
1125 
1126     // leave updating section
1127     if (windowUpdateIsLocked)
1128         LockWindowUpdate(FALSE);
1129     SetCursor(saveCursor);
1130 
1131     // update history
1132     if (flags & BTP_UPDATE_NEXT_HISTORY)
1133     {
1134         hResult = travelLog->AddEntry(static_cast<IDropTarget *>(this), FALSE);
1135         hResult = travelLog->UpdateEntry(static_cast<IDropTarget *>(this), FALSE);
1136     }
1137 
1138     // completed
1139     nameFlags = SHGDN_FORADDRESSBAR | SHGDN_FORPARSING;
1140     hResult = IEGetNameAndFlags(fCurrentDirectoryPIDL, nameFlags, newTitle,
1141         sizeof(newTitle) / sizeof(wchar_t), NULL);
1142     if (SUCCEEDED(hResult))
1143     {
1144         FireNavigateComplete(newTitle);
1145     }
1146     else
1147     {
1148         FireNavigateComplete(L"ERROR");
1149     }
1150 
1151     UpdateWindowTitle();
1152 
1153     LPCITEMIDLIST pidlChild;
1154     INT index, indexOpen;
1155     HIMAGELIST himlSmall, himlLarge;
1156 
1157     CComPtr<IShellFolder> sf;
1158     hResult = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
1159     if (SUCCEEDED(hResult))
1160     {
1161         index = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
1162 
1163         Shell_GetImageLists(&himlLarge, &himlSmall);
1164 
1165         HICON icSmall = ImageList_GetIcon(himlSmall, indexOpen, 0);
1166         HICON icLarge = ImageList_GetIcon(himlLarge, indexOpen, 0);
1167 
1168         /* Hack to make it possible to release the old icons */
1169         /* Something seems to go wrong with WM_SETICON */
1170         HICON oldSmall = (HICON)SendMessage(WM_GETICON, ICON_SMALL, 0);
1171         HICON oldLarge = (HICON)SendMessage(WM_GETICON, ICON_BIG,   0);
1172 
1173         SendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(icSmall));
1174         SendMessage(WM_SETICON, ICON_BIG,   reinterpret_cast<LPARAM>(icLarge));
1175 
1176         DestroyIcon(oldSmall);
1177         DestroyIcon(oldLarge);
1178     }
1179 
1180     FireCommandStateChangeAll();
1181     hResult = UpdateForwardBackState();
1182     hResult = UpdateUpState();
1183     return S_OK;
1184 }
1185 
GetMenuBand(REFIID riid,void ** shellMenu)1186 HRESULT CShellBrowser::GetMenuBand(REFIID riid, void **shellMenu)
1187 {
1188     CComPtr<IBandSite>                      bandSite;
1189     CComPtr<IDeskBand>                      deskBand;
1190     HRESULT                                 hResult;
1191 
1192     if (!fClientBars[BIInternetToolbar].clientBar)
1193         return E_FAIL;
1194 
1195     hResult = IUnknown_QueryService(fClientBars[BIInternetToolbar].clientBar, SID_IBandSite, IID_PPV_ARG(IBandSite, &bandSite));
1196     if (FAILED_UNEXPECTEDLY(hResult))
1197         return hResult;
1198 
1199     hResult = bandSite->QueryBand(1, &deskBand, NULL, NULL, 0);
1200     if (FAILED_UNEXPECTEDLY(hResult))
1201         return hResult;
1202 
1203     return deskBand->QueryInterface(riid, shellMenu);
1204 }
1205 
GetBaseBar(bool vertical,REFIID riid,void ** theBaseBar)1206 HRESULT CShellBrowser::GetBaseBar(bool vertical, REFIID riid, void **theBaseBar)
1207 {
1208     CComPtr<IUnknown>                       newBaseBar;
1209     CComPtr<IDeskBar>                       deskBar;
1210     CComPtr<IUnknown>                       newBaseBarSite;
1211     CComPtr<IDeskBarClient>                 deskBarClient;
1212     IUnknown                                **cache;
1213     HRESULT                                 hResult;
1214 
1215     if (vertical)
1216         cache = &fClientBars[BIVerticalBaseBar].clientBar.p;
1217     else
1218         cache = &fClientBars[BIHorizontalBaseBar].clientBar.p;
1219     if (*cache == NULL)
1220     {
1221         hResult = CBaseBar_CreateInstance(IID_PPV_ARG(IUnknown, &newBaseBar), vertical);
1222         if (FAILED_UNEXPECTEDLY(hResult))
1223             return hResult;
1224         hResult = CBaseBarSite_CreateInstance(IID_PPV_ARG(IUnknown, &newBaseBarSite), vertical);
1225         if (FAILED_UNEXPECTEDLY(hResult))
1226             return hResult;
1227 
1228         // we have to store our basebar into cache now
1229         *cache = newBaseBar;
1230         (*cache)->AddRef();
1231 
1232         // tell the new base bar about the shell browser
1233         hResult = IUnknown_SetSite(newBaseBar, static_cast<IDropTarget *>(this));
1234         if (FAILED_UNEXPECTEDLY(hResult))
1235             return hResult;
1236 
1237         // tell the new base bar about the new base bar site
1238         hResult = newBaseBar->QueryInterface(IID_PPV_ARG(IDeskBar, &deskBar));
1239         if (FAILED_UNEXPECTEDLY(hResult))
1240             return hResult;
1241         hResult = deskBar->SetClient(newBaseBarSite);
1242         if (FAILED_UNEXPECTEDLY(hResult))
1243             return hResult;
1244 
1245         // tell the new base bar site about the new base bar
1246         hResult = newBaseBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &deskBarClient));
1247         if (FAILED_UNEXPECTEDLY(hResult))
1248             return hResult;
1249         hResult = deskBarClient->SetDeskBarSite(newBaseBar);
1250         if (FAILED_UNEXPECTEDLY(hResult))
1251             return hResult;
1252 
1253     }
1254     return (*cache)->QueryInterface(riid, theBaseBar);
1255 }
1256 
IsBandLoaded(const CLSID clsidBand,bool vertical,DWORD * pdwBandID)1257 BOOL CShellBrowser::IsBandLoaded(const CLSID clsidBand, bool vertical, DWORD *pdwBandID)
1258 {
1259     HRESULT                                 hResult;
1260     CComPtr<IDeskBar>                       deskBar;
1261     CComPtr<IUnknown>                       baseBarSite;
1262     CComPtr<IBandSite>                      bandSite;
1263     CLSID                                   clsidTmp;
1264     DWORD                                   numBands;
1265     DWORD                                   dwBandID;
1266     DWORD                                   i;
1267 
1268     /* Get our basebarsite to be able to enumerate bands */
1269     hResult = GetBaseBar(vertical, IID_PPV_ARG(IDeskBar, &deskBar));
1270     if (FAILED_UNEXPECTEDLY(hResult))
1271         return FALSE;
1272     hResult = deskBar->GetClient(&baseBarSite);
1273     if (FAILED_UNEXPECTEDLY(hResult))
1274         return FALSE;
1275     hResult = baseBarSite->QueryInterface(IID_PPV_ARG(IBandSite, &bandSite));
1276     if (FAILED_UNEXPECTEDLY(hResult))
1277         return FALSE;
1278 
1279     hResult = bandSite->EnumBands(-1, &numBands);
1280     if (FAILED_UNEXPECTEDLY(hResult))
1281         return FALSE;
1282 
1283     for(i = 0; i < numBands; i++)
1284     {
1285         CComPtr<IPersist> bandPersist;
1286 
1287         hResult = bandSite->EnumBands(i, &dwBandID);
1288         if (FAILED_UNEXPECTEDLY(hResult))
1289             return FALSE;
1290 
1291         hResult = bandSite->GetBandObject(dwBandID, IID_PPV_ARG(IPersist, &bandPersist));
1292         if (FAILED_UNEXPECTEDLY(hResult))
1293             return FALSE;
1294         hResult = bandPersist->GetClassID(&clsidTmp);
1295         if (FAILED_UNEXPECTEDLY(hResult))
1296             return FALSE;
1297         if (IsEqualGUID(clsidBand, clsidTmp))
1298         {
1299             if (pdwBandID) *pdwBandID = dwBandID;
1300             return TRUE;
1301         }
1302     }
1303     return FALSE;
1304 }
1305 
ShowBand(const CLSID & classID,bool vertical)1306 HRESULT CShellBrowser::ShowBand(const CLSID &classID, bool vertical)
1307 {
1308     CComPtr<IDockingWindow>                 dockingWindow;
1309     CComPtr<IUnknown>                       baseBarSite;
1310     CComPtr<IUnknown>                       newBand;
1311     CComPtr<IDeskBar>                       deskBar;
1312     VARIANT                                 vaIn;
1313     HRESULT                                 hResult;
1314     DWORD                                   dwBandID;
1315 
1316     hResult = GetBaseBar(vertical, IID_PPV_ARG(IDeskBar, &deskBar));
1317     if (FAILED_UNEXPECTEDLY(hResult))
1318         return hResult;
1319 
1320     hResult = deskBar->GetClient(&baseBarSite);
1321     if (FAILED_UNEXPECTEDLY(hResult))
1322         return hResult;
1323 
1324     hResult = deskBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
1325     if (FAILED_UNEXPECTEDLY(hResult))
1326         return hResult;
1327 
1328     if (!IsBandLoaded(classID, vertical, &dwBandID))
1329     {
1330         TRACE("ShowBand called for CLSID %s, vertical=%d...\n", wine_dbgstr_guid(&classID), vertical);
1331         if (IsEqualCLSID(CLSID_ExplorerBand, classID))
1332         {
1333             TRACE("CLSID_ExplorerBand requested, building internal band.\n");
1334             hResult = CExplorerBand_CreateInstance(IID_PPV_ARG(IUnknown, &newBand));
1335             if (FAILED_UNEXPECTEDLY(hResult))
1336                 return hResult;
1337         }
1338         else if (IsEqualCLSID(classID, CLSID_FileSearchBand))
1339         {
1340             TRACE("CLSID_FileSearchBand requested, building internal band.\n");
1341             hResult = CSearchBar_CreateInstance(IID_PPV_ARG(IUnknown, &newBand));
1342             if (FAILED_UNEXPECTEDLY(hResult))
1343                 return hResult;
1344         }
1345         else
1346         {
1347             TRACE("A different CLSID requested, using CoCreateInstance.\n");
1348             hResult = CoCreateInstance(classID, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &newBand));
1349             if (FAILED_UNEXPECTEDLY(hResult))
1350                 return hResult;
1351         }
1352     }
1353     else
1354     {
1355         CComPtr<IBandSite>                  pBandSite;
1356 
1357         hResult = baseBarSite->QueryInterface(IID_PPV_ARG(IBandSite, &pBandSite));
1358         if (!SUCCEEDED(hResult))
1359         {
1360             ERR("Can't get IBandSite interface\n");
1361             return E_FAIL;
1362         }
1363         hResult = pBandSite->GetBandObject(dwBandID, IID_PPV_ARG(IUnknown, &newBand));
1364         if (!SUCCEEDED(hResult))
1365         {
1366             ERR("Can't find band object\n");
1367             return E_FAIL;
1368         }
1369 
1370         // It's hackish, but we should be able to show the wanted band until we
1371         // find the proper way to do this (but it seems to work to add a new band)
1372         // Here we'll just re-add the existing band to the site, causing it to display.
1373     }
1374     V_VT(&vaIn) = VT_UNKNOWN;
1375     V_UNKNOWN(&vaIn) = newBand.p;
1376     hResult = IUnknown_Exec(baseBarSite, CGID_IDeskBand, 1, 1, &vaIn, NULL);
1377     if (FAILED_UNEXPECTEDLY(hResult))
1378     {
1379         return hResult;
1380     }
1381 
1382     hResult = dockingWindow->ShowDW(TRUE);
1383     if (FAILED_UNEXPECTEDLY(hResult))
1384         return hResult;
1385 
1386     if (vertical)
1387     {
1388         fCurrentVertBar = classID;
1389         FireCommandStateChangeAll();
1390     }
1391 
1392     return S_OK;
1393 }
1394 
NavigateToParent()1395 HRESULT CShellBrowser::NavigateToParent()
1396 {
1397     LPITEMIDLIST newDirectory = ILClone(fCurrentDirectoryPIDL);
1398     if (newDirectory == NULL)
1399         return E_OUTOFMEMORY;
1400     if (_ILIsDesktop(newDirectory))
1401     {
1402         ILFree(newDirectory);
1403         return E_INVALIDARG;
1404     }
1405     ILRemoveLastID(newDirectory);
1406     HRESULT hResult = BrowseToPIDL(newDirectory, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
1407     ILFree(newDirectory);
1408     if (FAILED_UNEXPECTEDLY(hResult))
1409         return hResult;
1410     return S_OK;
1411 }
1412 
AddFolderOptionsPage(HPROPSHEETPAGE thePage,LPARAM lParam)1413 BOOL CALLBACK AddFolderOptionsPage(HPROPSHEETPAGE thePage, LPARAM lParam)
1414 {
1415     PROPSHEETHEADER* sheetInfo = reinterpret_cast<PROPSHEETHEADER*>(lParam);
1416     if (sheetInfo->nPages >= folderOptionsPageCountMax)
1417         return FALSE;
1418     sheetInfo->phpage[sheetInfo->nPages] = thePage;
1419     sheetInfo->nPages++;
1420     return TRUE;
1421 }
1422 
DoFolderOptions()1423 HRESULT CShellBrowser::DoFolderOptions()
1424 {
1425     CComPtr<IShellPropSheetExt>             folderOptionsSheet;
1426     PROPSHEETHEADER                         m_PropSheet;
1427     HPROPSHEETPAGE                          m_psp[folderOptionsPageCountMax];
1428 //    CComPtr<IGlobalFolderSettings>          globalSettings;
1429 //    SHELLSTATE2                             shellState;
1430     HRESULT                                 hResult;
1431 
1432     memset(m_psp, 0, sizeof(m_psp));
1433     memset(&m_PropSheet, 0, sizeof(m_PropSheet));
1434 
1435     // create sheet object
1436     hResult = CoCreateInstance(CLSID_ShellFldSetExt, NULL, CLSCTX_INPROC_SERVER,
1437         IID_PPV_ARG(IShellPropSheetExt, &folderOptionsSheet));
1438     if (FAILED_UNEXPECTEDLY(hResult))
1439         return E_FAIL;
1440 
1441     // must set site in order for Apply to all Folders on Advanced page to be enabled
1442     hResult = IUnknown_SetSite(folderOptionsSheet, static_cast<IDispatch *>(this));
1443     m_PropSheet.phpage = m_psp;
1444 
1445 #if 0
1446     hResult = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IGlobalFolderSettings, &globalSettings));
1447     if (FAILED_UNEXPECTEDLY(hResult))
1448         return E_FAIL;
1449     hResult = globalSettings->Get(&shellState, sizeof(shellState));
1450     if (FAILED_UNEXPECTEDLY(hResult))
1451         return E_FAIL;
1452 #endif
1453 
1454     // add pages
1455     hResult = folderOptionsSheet->AddPages(AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
1456     if (FAILED_UNEXPECTEDLY(hResult))
1457         return E_FAIL;
1458 
1459     if (fCurrentShellView)
1460     {
1461         hResult = fCurrentShellView->AddPropertySheetPages(
1462             0, AddFolderOptionsPage, reinterpret_cast<LPARAM>(&m_PropSheet));
1463         if (FAILED_UNEXPECTEDLY(hResult))
1464             return E_FAIL;
1465     }
1466 
1467     // show sheet
1468     CStringW strFolderOptions(MAKEINTRESOURCEW(IDS_FOLDER_OPTIONS));
1469     m_PropSheet.dwSize = sizeof(PROPSHEETHEADER);
1470     m_PropSheet.dwFlags = 0;
1471     m_PropSheet.hwndParent = m_hWnd;
1472     m_PropSheet.hInstance = _AtlBaseModule.GetResourceInstance();
1473     m_PropSheet.pszCaption = strFolderOptions;
1474     m_PropSheet.nStartPage = 0;
1475     PropertySheet(&m_PropSheet);
1476     return S_OK;
1477 }
1478 
WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)1479 LRESULT CALLBACK CShellBrowser::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1480 {
1481     CShellBrowser                           *pThis = reinterpret_cast<CShellBrowser *>(hWnd);
1482     _ATL_MSG                                msg(pThis->m_hWnd, uMsg, wParam, lParam);
1483     LRESULT                                 lResult;
1484     const _ATL_MSG                          *previousMessage;
1485     BOOL                                    handled;
1486     WNDPROC                                 saveWindowProc;
1487     HRESULT                                 hResult;
1488 
1489     hWnd = pThis->m_hWnd;
1490     previousMessage = pThis->m_pCurrentMsg;
1491     pThis->m_pCurrentMsg = &msg;
1492 
1493     /* If the shell browser is initialized, let the menu band preprocess the messages */
1494     if (pThis->fCurrentDirectoryPIDL)
1495     {
1496         CComPtr<IMenuBand> menuBand;
1497         hResult = pThis->GetMenuBand(IID_PPV_ARG(IMenuBand, &menuBand));
1498         if (SUCCEEDED(hResult) && menuBand.p != NULL)
1499         {
1500             hResult = menuBand->TranslateMenuMessage(&msg, &lResult);
1501             if (hResult == S_OK)
1502                 return lResult;
1503             uMsg = msg.message;
1504             wParam = msg.wParam;
1505             lParam = msg.lParam;
1506         }
1507         menuBand.Release();
1508     }
1509 
1510     handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
1511     ATLASSERT(pThis->m_pCurrentMsg == &msg);
1512     if (handled == FALSE)
1513     {
1514         if (uMsg == WM_NCDESTROY)
1515         {
1516             saveWindowProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtr(hWnd, GWLP_WNDPROC));
1517             lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1518             if (saveWindowProc == reinterpret_cast<WNDPROC>(::GetWindowLongPtr(hWnd, GWLP_WNDPROC)))
1519                 ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
1520             pThis->m_dwState |= WINSTATE_DESTROYED;
1521         }
1522         else
1523             lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1524     }
1525     pThis->m_pCurrentMsg = previousMessage;
1526     if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
1527     {
1528         pThis->m_dwState &= ~WINSTATE_DESTROYED;
1529         pThis->m_hWnd = NULL;
1530         pThis->OnFinalMessage(hWnd);
1531     }
1532     return lResult;
1533 }
1534 
RepositionBars()1535 void CShellBrowser::RepositionBars()
1536 {
1537     RECT                                    clientRect;
1538     RECT                                    statusRect;
1539     int                                     x;
1540 
1541     GetClientRect(&clientRect);
1542 
1543     if (m_settings.fStatusBarVisible && fStatusBar)
1544     {
1545         ::GetWindowRect(fStatusBar, &statusRect);
1546         ::SetWindowPos(fStatusBar, NULL, clientRect.left, clientRect.bottom - (statusRect.bottom - statusRect.top),
1547                             clientRect.right - clientRect.left,
1548                             statusRect.bottom - statusRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
1549         clientRect.bottom -= statusRect.bottom - statusRect.top;
1550     }
1551 
1552     for (x = 0; x < 3; x++)
1553     {
1554         HWND hwnd = fClientBars[x].hwnd;
1555         RECT borderSpace = fClientBars[x].borderSpace;
1556         if (hwnd == NULL && fClientBars[x].clientBar != NULL)
1557         {
1558             IUnknown_GetWindow(fClientBars[x].clientBar, &hwnd);
1559             fClientBars[x].hwnd = hwnd;
1560         }
1561         if (hwnd != NULL)
1562         {
1563             RECT toolbarRect = clientRect;
1564             if (borderSpace.top != 0)
1565             {
1566                 toolbarRect.bottom = toolbarRect.top + borderSpace.top;
1567             }
1568             else if (borderSpace.bottom != 0)
1569             {
1570                 toolbarRect.top = toolbarRect.bottom - borderSpace.bottom;
1571             }
1572             else if (borderSpace.left != 0)
1573             {
1574                 toolbarRect.right = toolbarRect.left + borderSpace.left;
1575             }
1576             else if (borderSpace.right != 0)
1577             {
1578                 toolbarRect.left = toolbarRect.right - borderSpace.right;
1579             }
1580 
1581             ::SetWindowPos(hwnd, NULL,
1582                 toolbarRect.left,
1583                 toolbarRect.top,
1584                 toolbarRect.right - toolbarRect.left,
1585                 toolbarRect.bottom - toolbarRect.top,
1586                 SWP_NOOWNERZORDER | SWP_NOZORDER);
1587 
1588             if (borderSpace.top != 0)
1589             {
1590                 clientRect.top = toolbarRect.bottom;
1591             }
1592             else if (borderSpace.bottom != 0)
1593             {
1594                 clientRect.bottom = toolbarRect.top;
1595             }
1596             else if (borderSpace.left != 0)
1597             {
1598                 clientRect.left = toolbarRect.right;
1599             }
1600             else if (borderSpace.right != 0)
1601             {
1602                 clientRect.right = toolbarRect.left;
1603             }
1604         }
1605     }
1606     ::SetWindowPos(fCurrentShellViewWindow, NULL, clientRect.left, clientRect.top,
1607                         clientRect.right - clientRect.left,
1608                         clientRect.bottom - clientRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
1609 }
1610 
FireEvent(DISPID dispIdMember,int argCount,VARIANT * arguments)1611 HRESULT CShellBrowser::FireEvent(DISPID dispIdMember, int argCount, VARIANT *arguments)
1612 {
1613     DISPPARAMS                          params;
1614     CComDynamicUnkArray                 &vec = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents2>::m_vec;
1615     CComDynamicUnkArray                 &vec2 = IConnectionPointImpl<CShellBrowser, &DIID_DWebBrowserEvents>::m_vec;
1616     HRESULT                             hResult;
1617 
1618     params.rgvarg = arguments;
1619     params.rgdispidNamedArgs = NULL;
1620     params.cArgs = argCount;
1621     params.cNamedArgs = 0;
1622     IUnknown** pp = vec.begin();
1623     while (pp < vec.end())
1624     {
1625         if (*pp != NULL)
1626         {
1627             CComPtr<IDispatch>          theDispatch;
1628 
1629             hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
1630             hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
1631         }
1632         pp++;
1633     }
1634     pp = vec2.begin();
1635     while (pp < vec2.end())
1636     {
1637         if (*pp != NULL)
1638         {
1639             CComPtr<IDispatch>          theDispatch;
1640 
1641             hResult = (*pp)->QueryInterface(IID_PPV_ARG(IDispatch, &theDispatch));
1642             hResult = theDispatch->Invoke(dispIdMember, GUID_NULL, 0, DISPATCH_METHOD, &params, NULL, NULL, NULL);
1643         }
1644         pp++;
1645     }
1646     return S_OK;
1647 }
1648 
FireNavigateComplete(const wchar_t * newDirectory)1649 HRESULT CShellBrowser::FireNavigateComplete(const wchar_t *newDirectory)
1650 {
1651     // these two variants intentionally to do use CComVariant because it would double free/release
1652     // or does not need to dispose at all
1653     VARIANT                             varArg[2];
1654     VARIANT                             varArgs;
1655     CComBSTR                            tempString(newDirectory);
1656 
1657     V_VT(&varArgs) = VT_BSTR;
1658     V_BSTR(&varArgs) = tempString.m_str;
1659 
1660     V_VT(&varArg[0]) = VT_VARIANT | VT_BYREF;
1661     V_VARIANTREF(&varArg[0]) = &varArgs;
1662     V_VT(&varArg[1]) = VT_DISPATCH;
1663     V_DISPATCH(&varArg[1]) = (IDispatch *)this;
1664 
1665     return FireEvent(DISPID_NAVIGATECOMPLETE2, 2, varArg);
1666 }
1667 
FireCommandStateChange(bool newState,int commandID)1668 HRESULT CShellBrowser::FireCommandStateChange(bool newState, int commandID)
1669 {
1670     VARIANT                             varArg[2];
1671 
1672     V_VT(&varArg[0]) = VT_BOOL;
1673     V_BOOL(&varArg[0]) = newState ? VARIANT_TRUE : VARIANT_FALSE;
1674     V_VT(&varArg[1]) = VT_I4;
1675     V_I4(&varArg[1]) = commandID;
1676 
1677     return FireEvent(DISPID_COMMANDSTATECHANGE, 2, varArg);
1678 }
1679 
FireCommandStateChangeAll()1680 HRESULT CShellBrowser::FireCommandStateChangeAll()
1681 {
1682     return FireCommandStateChange(false, -1);
1683 }
1684 
UpdateForwardBackState()1685 HRESULT CShellBrowser::UpdateForwardBackState()
1686 {
1687     CComPtr<ITravelLog>                     travelLog;
1688     CComPtr<ITravelEntry>                   unusedEntry;
1689     bool                                    canGoBack;
1690     bool                                    canGoForward;
1691     HRESULT                                 hResult;
1692 
1693     canGoBack = false;
1694     canGoForward = false;
1695     hResult = GetTravelLog(&travelLog);
1696     if (FAILED_UNEXPECTEDLY(hResult))
1697         return hResult;
1698     hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_BACK, &unusedEntry);
1699     if (SUCCEEDED(hResult))
1700     {
1701         canGoBack = true;
1702         unusedEntry.Release();
1703     }
1704     hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this), TLOG_FORE, &unusedEntry);
1705     if (SUCCEEDED(hResult))
1706     {
1707         canGoForward = true;
1708         unusedEntry.Release();
1709     }
1710     hResult = FireCommandStateChange(canGoBack, 2);
1711     hResult = FireCommandStateChange(canGoForward, 1);
1712     return S_OK;
1713 }
1714 
UpdateUpState()1715 HRESULT CShellBrowser::UpdateUpState()
1716 {
1717     bool canGoUp;
1718     HRESULT hResult;
1719 
1720     canGoUp = true;
1721     if (_ILIsDesktop(fCurrentDirectoryPIDL))
1722         canGoUp = false;
1723     hResult = FireCommandStateChange(canGoUp, 3);
1724     return S_OK;
1725 }
1726 
UpdateGotoMenu(HMENU theMenu)1727 void CShellBrowser::UpdateGotoMenu(HMENU theMenu)
1728 {
1729     CComPtr<ITravelLog>                     travelLog;
1730     CComPtr<ITravelEntry>                   unusedEntry;
1731     int                                     position;
1732     MENUITEMINFO                            menuItemInfo;
1733     HRESULT                                 hResult;
1734 
1735     DeleteMenuItems(theMenu, IDM_GOTO_TRAVEL_FIRST, IDM_GOTO_TRAVEL_LAST);
1736 
1737     position = GetMenuItemCount(theMenu);
1738     hResult = GetTravelLog(&travelLog);
1739     if (FAILED_UNEXPECTEDLY(hResult))
1740         return;
1741 
1742     hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this),
1743                                         TLOG_BACK,
1744                                         &unusedEntry);
1745 
1746     if (SUCCEEDED(hResult))
1747     {
1748         SHEnableMenuItem(theMenu, IDM_GOTO_BACK, TRUE);
1749         unusedEntry.Release();
1750     }
1751     else
1752         SHEnableMenuItem(theMenu, IDM_GOTO_BACK, FALSE);
1753 
1754     hResult = travelLog->GetTravelEntry(static_cast<IDropTarget *>(this),
1755                                         TLOG_FORE,
1756                                         &unusedEntry);
1757 
1758     if (SUCCEEDED(hResult))
1759     {
1760         SHEnableMenuItem(theMenu, IDM_GOTO_FORWARD, TRUE);
1761         unusedEntry.Release();
1762     }
1763     else
1764         SHEnableMenuItem(theMenu, IDM_GOTO_FORWARD, FALSE);
1765 
1766     SHEnableMenuItem(theMenu,
1767                      IDM_GOTO_UPONELEVEL,
1768                      !_ILIsDesktop(fCurrentDirectoryPIDL));
1769 
1770     hResult = travelLog->InsertMenuEntries(static_cast<IDropTarget *>(this), theMenu, position,
1771         IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, TLMENUF_BACKANDFORTH | TLMENUF_CHECKCURRENT);
1772     if (SUCCEEDED(hResult))
1773     {
1774         menuItemInfo.cbSize = sizeof(menuItemInfo);
1775         menuItemInfo.fMask = MIIM_TYPE | MIIM_ID;
1776         menuItemInfo.fType = MF_SEPARATOR;
1777         menuItemInfo.wID = IDM_GOTO_TRAVEL_SEP;
1778         InsertMenuItem(theMenu, position, TRUE, &menuItemInfo);
1779     }
1780 }
1781 
UpdateViewMenu(HMENU theMenu)1782 void CShellBrowser::UpdateViewMenu(HMENU theMenu)
1783 {
1784     CComPtr<ITravelLog>                     travelLog;
1785     HMENU                                   gotoMenu;
1786     OLECMD                                  commandList[5];
1787     HMENU                                   toolbarMenuBar;
1788     HMENU                                   toolbarMenu;
1789     MENUITEMINFO                            menuItemInfo;
1790     HRESULT                                 hResult;
1791 
1792     gotoMenu = SHGetMenuFromID(theMenu, FCIDM_MENU_EXPLORE);
1793     if (gotoMenu != NULL)
1794         UpdateGotoMenu(gotoMenu);
1795 
1796     commandList[0].cmdID = ITID_TOOLBARBANDSHOWN;
1797     commandList[1].cmdID = ITID_ADDRESSBANDSHOWN;
1798     commandList[2].cmdID = ITID_LINKSBANDSHOWN;
1799     commandList[3].cmdID = ITID_TOOLBARLOCKED;
1800     commandList[4].cmdID = ITID_CUSTOMIZEENABLED;
1801 
1802     hResult = IUnknown_QueryStatus(fClientBars[BIInternetToolbar].clientBar,
1803                                    CGID_PrivCITCommands, 5, commandList, NULL);
1804     if (FAILED_UNEXPECTEDLY(hResult))
1805         DeleteMenu(theMenu, IDM_VIEW_TOOLBARS, MF_BYCOMMAND);
1806     else
1807     {
1808         menuItemInfo.cbSize = sizeof(menuItemInfo);
1809         menuItemInfo.fMask = MIIM_SUBMENU;
1810         GetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
1811         DestroyMenu(menuItemInfo.hSubMenu);
1812 
1813         toolbarMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1814         toolbarMenu = GetSubMenu(toolbarMenuBar, 0);
1815         RemoveMenu(toolbarMenuBar, 0, MF_BYPOSITION);
1816         DestroyMenu(toolbarMenuBar);
1817 
1818         // TODO: Implement
1819         SHEnableMenuItem(toolbarMenu, IDM_TOOLBARS_STANDARDBUTTONS, commandList[0].cmdf & OLECMDF_ENABLED);
1820         SHEnableMenuItem(toolbarMenu, IDM_TOOLBARS_ADDRESSBAR, commandList[1].cmdf & OLECMDF_ENABLED);
1821         SHEnableMenuItem(toolbarMenu, IDM_TOOLBARS_LINKSBAR, commandList[2].cmdf & OLECMDF_ENABLED);
1822         SHEnableMenuItem(toolbarMenu, IDM_TOOLBARS_CUSTOMIZE, commandList[4].cmdf & OLECMDF_ENABLED);
1823 
1824         SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_STANDARDBUTTONS, commandList[0].cmdf & OLECMDF_LATCHED);
1825         SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_ADDRESSBAR, commandList[1].cmdf & OLECMDF_LATCHED);
1826         SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LINKSBAR, commandList[2].cmdf & OLECMDF_LATCHED);
1827         SHCheckMenuItem(toolbarMenu, IDM_TOOLBARS_LOCKTOOLBARS, commandList[3].cmdf & OLECMDF_LATCHED);
1828         if ((commandList[4].cmdf & OLECMDF_ENABLED) == 0)
1829             DeleteMenu(toolbarMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1830         DeleteMenu(toolbarMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1831         DeleteMenu(toolbarMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1832 
1833         menuItemInfo.cbSize = sizeof(menuItemInfo);
1834         menuItemInfo.fMask = MIIM_SUBMENU;
1835         menuItemInfo.hSubMenu = toolbarMenu;
1836         SetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
1837     }
1838     SHCheckMenuItem(theMenu, IDM_VIEW_STATUSBAR, m_settings.fStatusBarVisible ? TRUE : FALSE);
1839 
1840     // Check the menu items for Explorer bar
1841     BOOL bSearchBand = (IsEqualCLSID(CLSID_SH_SearchBand, fCurrentVertBar) ||
1842                         IsEqualCLSID(CLSID_SearchBand, fCurrentVertBar) ||
1843                         IsEqualCLSID(CLSID_IE_SearchBand, fCurrentVertBar) ||
1844                         IsEqualCLSID(CLSID_FileSearchBand, fCurrentVertBar));
1845     BOOL bHistory = IsEqualCLSID(CLSID_SH_HistBand, fCurrentVertBar);
1846     BOOL bFavorites = IsEqualCLSID(CLSID_SH_FavBand, fCurrentVertBar);
1847     BOOL bFolders = IsEqualCLSID(CLSID_ExplorerBand, fCurrentVertBar);
1848     SHCheckMenuItem(theMenu, IDM_EXPLORERBAR_SEARCH, bSearchBand);
1849     SHCheckMenuItem(theMenu, IDM_EXPLORERBAR_HISTORY, bHistory);
1850     SHCheckMenuItem(theMenu, IDM_EXPLORERBAR_FAVORITES, bFavorites);
1851     SHCheckMenuItem(theMenu, IDM_EXPLORERBAR_FOLDERS, bFolders);
1852 }
1853 
BuildExplorerBandMenu()1854 HRESULT CShellBrowser::BuildExplorerBandMenu()
1855 {
1856     HMENU                                   hBandsMenu;
1857     UINT                                    nbFound;
1858 
1859     hBandsMenu = SHGetMenuFromID(fCurrentMenuBar, IDM_VIEW_EXPLORERBAR);
1860     if (!hBandsMenu)
1861     {
1862         OutputDebugString(L"No menu !\n");
1863         return E_FAIL;
1864     }
1865     DSA_DeleteAllItems(menuDsa);
1866     BuildExplorerBandCategory(hBandsMenu, CATID_InfoBand, 4, NULL);
1867     BuildExplorerBandCategory(hBandsMenu, CATID_CommBand, 20, &nbFound);
1868     if (!nbFound)
1869     {
1870         // Remove separator
1871         DeleteMenu(hBandsMenu, IDM_EXPLORERBAR_SEPARATOR, MF_BYCOMMAND);
1872     }
1873     // Remove media menu since XP does it (according to API Monitor)
1874     DeleteMenu(hBandsMenu, IDM_EXPLORERBAR_MEDIA, MF_BYCOMMAND);
1875     return S_OK;
1876 }
1877 
BuildExplorerBandCategory(HMENU hBandsMenu,CATID category,DWORD dwPos,UINT * nbFound)1878 HRESULT CShellBrowser::BuildExplorerBandCategory(HMENU hBandsMenu, CATID category, DWORD dwPos, UINT *nbFound)
1879 {
1880     HRESULT                                 hr;
1881     CComPtr<IEnumGUID>                      pEnumGUID;
1882     WCHAR                                   wszBandName[MAX_PATH];
1883     WCHAR                                   wszBandGUID[MAX_PATH];
1884     WCHAR                                   wRegKey[MAX_PATH];
1885     UINT                                    cBands;
1886     DWORD                                   dwRead;
1887     DWORD                                   dwDataSize;
1888     GUID                                    iter;
1889     MenuBandInfo                            mbi;
1890 
1891     mbi.fVertical = IsEqualGUID(category, CATID_InfoBand);
1892     cBands = 0;
1893     hr = SHEnumClassesOfCategories(1, &category, 0, NULL, &pEnumGUID);
1894     if (FAILED_UNEXPECTEDLY(hr))
1895     {
1896         return hr;
1897     }
1898     do
1899     {
1900         pEnumGUID->Next(1, &iter, &dwRead);
1901         if (dwRead)
1902         {
1903             // Get the band name
1904             if (IsBuiltinBand(iter))
1905                 continue;
1906             if (!StringFromGUID2(iter, wszBandGUID, MAX_PATH))
1907                 continue;
1908             StringCchPrintfW(wRegKey, MAX_PATH, L"CLSID\\%s", wszBandGUID);
1909             dwDataSize = MAX_PATH;
1910             SHGetValue(HKEY_CLASSES_ROOT, wRegKey, NULL, NULL, wszBandName, &dwDataSize);
1911 
1912             mbi.barGuid = iter;
1913             InsertMenu(hBandsMenu, dwPos + cBands, MF_BYPOSITION, IDM_EXPLORERBAND_BEGINCUSTOM + DSA_GetItemCount(menuDsa), wszBandName);
1914             DSA_AppendItem(menuDsa, &mbi);
1915             cBands++;
1916         }
1917     }
1918     while (dwRead > 0);
1919     if (nbFound)
1920         *nbFound = cBands;
1921     return S_OK;
1922 }
1923 
IsBuiltinBand(CLSID & bandID)1924 BOOL CShellBrowser::IsBuiltinBand(CLSID &bandID)
1925 {
1926     if (IsEqualCLSID(bandID, CLSID_ExplorerBand))
1927         return TRUE;
1928     if (IsEqualCLSID(bandID, CLSID_SH_SearchBand) || IsEqualCLSID(bandID, CLSID_SearchBand))
1929         return TRUE;
1930     if (IsEqualCLSID(bandID, CLSID_IE_SearchBand) || IsEqualCLSID(bandID, CLSID_FileSearchBand))
1931         return TRUE;
1932     if (IsEqualCLSID(bandID, CLSID_SH_HistBand))
1933         return TRUE;
1934     if (IsEqualCLSID(bandID, CLSID_SH_FavBand))
1935         return TRUE;
1936     if (IsEqualCLSID(bandID, CLSID_ChannelsBand))
1937         return TRUE;
1938     return FALSE;
1939 }
1940 
OnSearch()1941 HRESULT CShellBrowser::OnSearch()
1942 {
1943     CComPtr<IObjectWithSite>                objectWithSite;
1944     CComPtr<IContextMenu>                   contextMenu;
1945     CMINVOKECOMMANDINFO                     commandInfo;
1946     const char                              *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1947     HRESULT                                 hResult;
1948 
1949     // TODO: Query shell if this command is enabled first
1950 
1951     memset(&commandInfo, 0, sizeof(commandInfo));
1952     commandInfo.cbSize = sizeof(commandInfo);
1953     commandInfo.hwnd = m_hWnd;
1954     commandInfo.lpParameters = searchGUID;
1955     commandInfo.nShow = SW_SHOWNORMAL;
1956 
1957     hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1958         IID_PPV_ARG(IContextMenu, &contextMenu));
1959     if (FAILED_UNEXPECTEDLY(hResult))
1960         return 0;
1961     hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1962     if (FAILED_UNEXPECTEDLY(hResult))
1963         return 0;
1964     hResult = objectWithSite->SetSite(dynamic_cast<IShellBrowser*>(this));
1965     if (FAILED_UNEXPECTEDLY(hResult))
1966         return 0;
1967     hResult = contextMenu->InvokeCommand(&commandInfo);
1968     hResult = objectWithSite->SetSite(NULL);
1969     return hResult;
1970 }
1971 
IUnknownIsEqual(IUnknown * int1,IUnknown * int2)1972 bool IUnknownIsEqual(IUnknown *int1, IUnknown *int2)
1973 {
1974     CComPtr<IUnknown>                       int1Retry;
1975     CComPtr<IUnknown>                       int2Retry;
1976     HRESULT                                 hResult;
1977 
1978     if (int1 == int2)
1979         return true;
1980     if (int1 == NULL || int2 == NULL)
1981         return false;
1982     hResult = int1->QueryInterface(IID_PPV_ARG(IUnknown, &int1Retry));
1983     if (FAILED_UNEXPECTEDLY(hResult))
1984         return false;
1985     hResult = int2->QueryInterface(IID_PPV_ARG(IUnknown, &int2Retry));
1986     if (FAILED_UNEXPECTEDLY(hResult))
1987         return false;
1988     if (int1Retry == int2Retry)
1989         return true;
1990     return false;
1991 }
1992 
GetBorderDW(IUnknown * punkObj,LPRECT prcBorder)1993 HRESULT STDMETHODCALLTYPE CShellBrowser::GetBorderDW(IUnknown *punkObj, LPRECT prcBorder)
1994 {
1995     static const INT excludeItems[] = { 1, 1, 1, IDC_STATUSBAR, 0, 0 };
1996 
1997     RECT availableBounds;
1998 
1999     GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
2000     for (INT x = 0; x < 3; x++)
2001     {
2002         if (fClientBars[x].clientBar.p != NULL && !IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
2003         {
2004             availableBounds.top += fClientBars[x].borderSpace.top;
2005             availableBounds.left += fClientBars[x].borderSpace.left;
2006             availableBounds.bottom -= fClientBars[x].borderSpace.bottom;
2007             availableBounds.right -= fClientBars[x].borderSpace.right;
2008         }
2009     }
2010     *prcBorder = availableBounds;
2011     return S_OK;
2012 }
2013 
RequestBorderSpaceDW(IUnknown * punkObj,LPCBORDERWIDTHS pbw)2014 HRESULT STDMETHODCALLTYPE CShellBrowser::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
2015 {
2016     return S_OK;
2017 }
2018 
SetBorderSpaceDW(IUnknown * punkObj,LPCBORDERWIDTHS pbw)2019 HRESULT STDMETHODCALLTYPE CShellBrowser::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
2020 {
2021     for (INT x = 0; x < 3; x++)
2022     {
2023         if (IUnknownIsEqual(fClientBars[x].clientBar, punkObj))
2024         {
2025             fClientBars[x].borderSpace = *pbw;
2026             // if this bar changed size, it cascades and forces all subsequent bars to resize
2027             RepositionBars();
2028             return S_OK;
2029         }
2030     }
2031     return E_INVALIDARG;
2032 }
2033 
QueryStatus(const GUID * pguidCmdGroup,ULONG cCmds,OLECMD prgCmds[],OLECMDTEXT * pCmdText)2034 HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatus(const GUID *pguidCmdGroup,
2035     ULONG cCmds, OLECMD prgCmds[  ], OLECMDTEXT *pCmdText)
2036 {
2037     CComPtr<IOleCommandTarget>              commandTarget;
2038     HRESULT                                 hResult;
2039 
2040     if (prgCmds == NULL)
2041         return E_INVALIDARG;
2042     if (pguidCmdGroup == NULL)
2043     {
2044         if (fCurrentShellView.p != NULL)
2045         {
2046             hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
2047             if (SUCCEEDED(hResult) && commandTarget.p != NULL)
2048                 return commandTarget->QueryStatus(NULL, 1, prgCmds, pCmdText);
2049         }
2050         while (cCmds != 0)
2051         {
2052             prgCmds->cmdf = 0;
2053             prgCmds++;
2054             cCmds--;
2055         }
2056     }
2057     else if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
2058     {
2059         while (cCmds != 0)
2060         {
2061             switch (prgCmds->cmdID)
2062             {
2063                 case 0x1c:  // search
2064                     prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
2065                     if (IsEqualCLSID(CLSID_SH_SearchBand, fCurrentVertBar) ||
2066                         IsEqualCLSID(CLSID_SearchBand, fCurrentVertBar) ||
2067                         IsEqualCLSID(CLSID_IE_SearchBand, fCurrentVertBar) ||
2068                         IsEqualCLSID(CLSID_FileSearchBand, fCurrentVertBar))
2069                     {
2070                         prgCmds->cmdf |= OLECMDF_LATCHED;
2071                     }
2072                     break;
2073                 case 0x1d:  // history
2074                     prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
2075                     if (IsEqualCLSID(CLSID_SH_HistBand, fCurrentVertBar))
2076                         prgCmds->cmdf |= OLECMDF_LATCHED;
2077                     break;
2078                 case 0x1e:  // favorites
2079                     prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
2080                     if (IsEqualCLSID(CLSID_SH_FavBand, fCurrentVertBar))
2081                         prgCmds->cmdf |= OLECMDF_LATCHED;
2082                     break;
2083                 case SBCMDID_EXPLORERBARFOLDERS:  // folders
2084                     prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
2085                     if (IsEqualCLSID(CLSID_ExplorerBand, fCurrentVertBar))
2086                         prgCmds->cmdf |= OLECMDF_LATCHED;
2087                     break;
2088                 default:
2089                     prgCmds->cmdf = 0;
2090                     break;
2091             }
2092             prgCmds++;
2093             cCmds--;
2094         }
2095     }
2096     else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
2097     {
2098         while (cCmds != 0)
2099         {
2100             switch (prgCmds->cmdID)
2101             {
2102                 case IDM_GOTO_UPONELEVEL:
2103                     prgCmds->cmdf = OLECMDF_SUPPORTED;
2104                     if (fCurrentDirectoryPIDL->mkid.cb != 0)
2105                         prgCmds->cmdf |= OLECMDF_ENABLED;
2106                     break;
2107             }
2108             prgCmds++;
2109             cCmds--;
2110         }
2111     }
2112     return S_OK;
2113 }
2114 
Exec(const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)2115 HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
2116     DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
2117 {
2118     HRESULT                                 hResult;
2119 
2120     if (!pguidCmdGroup)
2121     {
2122         TRACE("Unhandled null CGID %d %d %p %p\n", nCmdID, nCmdexecopt, pvaIn, pvaOut);
2123         return E_NOTIMPL;
2124     }
2125     if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
2126     {
2127         switch (nCmdID)
2128         {
2129             case 0x1c: //Toggle Search
2130             case 0x1d: //Toggle History
2131             case 0x1e: //Toggle Favorites
2132             case SBCMDID_EXPLORERBARFOLDERS: //Toggle Folders
2133                 const GUID* pclsid;
2134                 if (nCmdID == 0x1c) pclsid = &CLSID_FileSearchBand;
2135                 else if (nCmdID == 0x1d) pclsid = &CLSID_SH_HistBand;
2136                 else if (nCmdID == 0x1e) pclsid = &CLSID_SH_FavBand;
2137                 else pclsid = &CLSID_ExplorerBand;
2138 
2139                 if (IsEqualCLSID(*pclsid, fCurrentVertBar))
2140                 {
2141                     hResult = IUnknown_ShowDW(fClientBars[BIVerticalBaseBar].clientBar.p, FALSE);
2142                     memset(&fCurrentVertBar, 0, sizeof(fCurrentVertBar));
2143                     FireCommandStateChangeAll();
2144                 }
2145                 else
2146                 {
2147                     hResult = ShowBand(*pclsid, true);
2148                 }
2149                 return S_OK;
2150             case 0x22:
2151                 //Sent when a band closes
2152                 if (V_VT(pvaIn) != VT_UNKNOWN)
2153                     return E_INVALIDARG;
2154 
2155                 if (IUnknownIsEqual(V_UNKNOWN(pvaIn), fClientBars[BIVerticalBaseBar].clientBar.p))
2156                 {
2157                     memset(&fCurrentVertBar, 0, sizeof(fCurrentVertBar));
2158                     FireCommandStateChangeAll();
2159                 }
2160                 return S_OK;
2161             case 0x27:
2162                 if (nCmdexecopt == 1)
2163                 {
2164                     // pvaIn is a VT_UNKNOWN with a band that is being hidden
2165                 }
2166                 else
2167                 {
2168                     // update zones part of the status bar
2169                 }
2170                 return S_OK;
2171             case 0x35: // don't do this, and the internet toolbar doesn't create a menu band
2172                 V_VT(pvaOut) = VT_INT_PTR;
2173                 V_INTREF(pvaOut) = reinterpret_cast<INT *>(
2174                     LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU)));
2175                 return S_OK;
2176             case 0x38:
2177                 // indicate if this cabinet was opened as a browser
2178                 return S_FALSE;
2179             default:
2180                 return E_NOTIMPL;
2181         }
2182     }
2183     else if (IsEqualIID(*pguidCmdGroup, CGID_InternetButtons))
2184     {
2185         switch (nCmdID)
2186         {
2187             case 0x23:
2188                 // placeholder
2189                 return S_OK;
2190         }
2191     }
2192     else if (IsEqualIID(*pguidCmdGroup, CGID_Theater))
2193     {
2194         switch (nCmdID)
2195         {
2196             case 6:
2197                 // what is theater mode and why do we receive this?
2198                 return E_NOTIMPL;
2199         }
2200     }
2201     else if (IsEqualIID(*pguidCmdGroup, CGID_MenuBand))
2202     {
2203         switch (nCmdID)
2204         {
2205             case 14:
2206                 // initialize favorites menu
2207                 return S_OK;
2208         }
2209     }
2210     else if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView))
2211     {
2212         switch (nCmdID)
2213         {
2214             case 0x12:
2215                 // refresh on toolbar clicked
2216                 return S_OK;
2217             case 0x26:
2218                 // called for unknown bands ?
2219                 return S_OK;
2220             case 0x4d:
2221                 // tell the view if it should hide the task pane or not
2222                 return (fClientBars[BIVerticalBaseBar].clientBar.p == NULL) ? S_FALSE : S_OK;
2223         }
2224     }
2225     else if (IsEqualIID(*pguidCmdGroup, CGID_ShellBrowser))
2226     {
2227         switch (nCmdID)
2228         {
2229             case 40994:
2230                 return NavigateToParent();
2231             case IDM_NOTIFYITBARDIRTY:
2232                 SaveITBarLayout();
2233                 break;
2234         }
2235     }
2236     else if (IsEqualIID(*pguidCmdGroup, CGID_IExplorerToolbar))
2237     {
2238         switch (nCmdID)
2239         {
2240             case 0x7063:
2241                 return DoFolderOptions();
2242         }
2243     }
2244     else if (IsEqualIID(*pguidCmdGroup, CGID_DefView))
2245     {
2246         switch (nCmdID)
2247         {
2248             case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS:
2249                 ApplyBrowserDefaultFolderSettings(NULL);
2250                 IUnknown_Exec(fCurrentShellView, CGID_DefView, nCmdID, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2251                 break;
2252         }
2253     }
2254     else
2255     {
2256         return E_NOTIMPL;
2257     }
2258     return E_NOTIMPL;
2259 }
2260 
GetWindow(HWND * lphwnd)2261 HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindow(HWND *lphwnd)
2262 {
2263     if (lphwnd == NULL)
2264         return E_POINTER;
2265     *lphwnd = m_hWnd;
2266     return S_OK;
2267 }
2268 
ContextSensitiveHelp(BOOL fEnterMode)2269 HRESULT STDMETHODCALLTYPE CShellBrowser::ContextSensitiveHelp(BOOL fEnterMode)
2270 {
2271     return E_NOTIMPL;
2272 }
2273 
InsertMenusSB(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths)2274 HRESULT STDMETHODCALLTYPE CShellBrowser::InsertMenusSB(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
2275 {
2276     HMENU mainMenu = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU));
2277 
2278     Shell_MergeMenus(hmenuShared, mainMenu, 0, 0, FCIDM_BROWSERLAST, MM_SUBMENUSHAVEIDS);
2279 
2280     int GCCU(itemCount3) = GetMenuItemCount(hmenuShared);
2281     Unused(itemCount3);
2282 
2283     DestroyMenu(mainMenu);
2284 
2285     lpMenuWidths->width[0] = 2;
2286     lpMenuWidths->width[2] = 3;
2287     lpMenuWidths->width[4] = 1;
2288     return S_OK;
2289 }
2290 
SetMenuSB(HMENU hmenuShared,HOLEMENU holemenuRes,HWND hwndActiveObject)2291 HRESULT STDMETHODCALLTYPE CShellBrowser::SetMenuSB(HMENU hmenuShared, HOLEMENU holemenuRes, HWND hwndActiveObject)
2292 {
2293     CComPtr<IShellMenu>                     shellMenu;
2294     HRESULT                                 hResult;
2295 
2296     if (hmenuShared && IsMenu(hmenuShared) == FALSE)
2297         return E_FAIL;
2298     hResult = GetMenuBand(IID_PPV_ARG(IShellMenu, &shellMenu));
2299     if (FAILED_UNEXPECTEDLY(hResult))
2300         return hResult;
2301 
2302     if (!hmenuShared)
2303     {
2304         hmenuShared = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_MAINMENU));
2305     }
2306     // FIXME: Figure out the proper way to do this.
2307     HMENU hMenuFavs = GetSubMenu(hmenuShared, 3);
2308     if (hMenuFavs)
2309     {
2310         DeleteMenu(hMenuFavs, IDM_FAVORITES_EMPTY, MF_BYCOMMAND);
2311     }
2312 
2313     hResult = shellMenu->SetMenu(hmenuShared, m_hWnd, SMSET_DONTOWN);
2314     if (FAILED_UNEXPECTEDLY(hResult))
2315         return hResult;
2316     fCurrentMenuBar = hmenuShared;
2317     BuildExplorerBandMenu();
2318     return S_OK;
2319 }
2320 
RemoveMenusSB(HMENU hmenuShared)2321 HRESULT STDMETHODCALLTYPE CShellBrowser::RemoveMenusSB(HMENU hmenuShared)
2322 {
2323     if (hmenuShared == fCurrentMenuBar)
2324     {
2325         //DestroyMenu(fCurrentMenuBar);
2326         SetMenuSB(NULL, NULL, NULL);
2327     }
2328     return S_OK;
2329 }
2330 
SetStatusTextSB(LPCOLESTR pszStatusText)2331 HRESULT STDMETHODCALLTYPE CShellBrowser::SetStatusTextSB(LPCOLESTR pszStatusText)
2332 {
2333     //
2334     if (pszStatusText)
2335     {
2336         ::SetWindowText(fStatusBar, pszStatusText);
2337     }
2338     else
2339     {
2340 
2341     }
2342     return S_OK;
2343 }
2344 
EnableModelessSB(BOOL fEnable)2345 HRESULT STDMETHODCALLTYPE CShellBrowser::EnableModelessSB(BOOL fEnable)
2346 {
2347     return E_NOTIMPL;
2348 }
2349 
TranslateAcceleratorSB(MSG * pmsg,WORD wID)2350 HRESULT STDMETHODCALLTYPE CShellBrowser::TranslateAcceleratorSB(MSG *pmsg, WORD wID)
2351 {
2352     if (!::TranslateAcceleratorW(m_hWnd, m_hAccel, pmsg))
2353         return S_FALSE;
2354     return S_OK;
2355 }
2356 
BrowseObject(LPCITEMIDLIST pidl,UINT wFlags)2357 HRESULT STDMETHODCALLTYPE CShellBrowser::BrowseObject(LPCITEMIDLIST pidl, UINT wFlags)
2358 {
2359     wFlags = ApplyNewBrowserFlag(wFlags);
2360     // FIXME: Should not automatically show the Explorer band
2361     if ((wFlags & SBSP_EXPLOREMODE) && !(wFlags & SBSP_NEWBROWSER))
2362         ShowBand(CLSID_ExplorerBand, true);
2363 
2364     CComHeapPtr<ITEMIDLIST> pidlResolved;
2365     if (wFlags & (SBSP_RELATIVE | SBSP_PARENT))
2366     {
2367         HRESULT hr = CreateRelativeBrowsePIDL(pidl, wFlags, &pidlResolved);
2368         if (FAILED(hr))
2369             return hr;
2370         pidl = pidlResolved;
2371     }
2372 
2373     if (wFlags & SBSP_NEWBROWSER)
2374         return OpenNewBrowserWindow(pidl, wFlags);
2375 
2376     switch (wFlags & (SBSP_ABSOLUTE | SBSP_RELATIVE | SBSP_PARENT | SBSP_NAVIGATEBACK | SBSP_NAVIGATEFORWARD))
2377     {
2378         case SBSP_PARENT:
2379             return NavigateToParent();
2380         case SBSP_NAVIGATEBACK:
2381             return GoBack();
2382         case SBSP_NAVIGATEFORWARD:
2383             return GoForward();
2384     }
2385 
2386     // TODO: SBSP_WRITENOHISTORY? SBSP_CREATENOHISTORY?
2387     long flags = BTP_UPDATE_NEXT_HISTORY;
2388     if (fTravelLog)
2389         flags |= BTP_UPDATE_CUR_HISTORY;
2390     if (wFlags & SBSP_ACTIVATE_NOFOCUS)
2391         flags |= BTP_ACTIVATE_NOFOCUS;
2392     return BrowseToPIDL(pidl, flags);
2393 }
2394 
GetViewStateStream(DWORD grfMode,IStream ** ppStrm)2395 HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewStateStream(DWORD grfMode, IStream **ppStrm)
2396 {
2397     return E_NOTIMPL;
2398 }
2399 
GetControlWindow(UINT id,HWND * lphwnd)2400 HRESULT STDMETHODCALLTYPE CShellBrowser::GetControlWindow(UINT id, HWND *lphwnd)
2401 {
2402     if (lphwnd == NULL)
2403         return E_POINTER;
2404     *lphwnd = NULL;
2405     switch (id)
2406     {
2407         case FCW_TOOLBAR:
2408             *lphwnd = fToolbarProxy.m_hWnd;
2409             return S_OK;
2410         case FCW_STATUS:
2411             *lphwnd = fStatusBar;
2412             return S_OK;
2413         case FCW_TREE:
2414         {
2415             BOOL shown;
2416             if (SUCCEEDED(IsControlWindowShown(id, &shown)) && shown)
2417                 return IUnknown_GetWindow(fClientBars[BIVerticalBaseBar].clientBar.p, lphwnd);
2418             return S_FALSE;
2419         }
2420         case FCW_PROGRESS:
2421             // is this a progress dialog?
2422             return S_OK;
2423     }
2424     return S_OK;
2425 }
2426 
SendControlMsg(UINT id,UINT uMsg,WPARAM wParam,LPARAM lParam,LRESULT * pret)2427 HRESULT STDMETHODCALLTYPE CShellBrowser::SendControlMsg(
2428     UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret)
2429 {
2430     LPARAM                                  result;
2431 
2432     if (pret != NULL)
2433         *pret = 0;
2434     switch (id)
2435     {
2436         case FCW_TOOLBAR:
2437             result = fToolbarProxy.SendMessage(uMsg, wParam, lParam);
2438             if (pret != NULL)
2439                 *pret = result;
2440             break;
2441         case FCW_STATUS:
2442             result = SendMessage(fStatusBar, uMsg, wParam, lParam);
2443             if (pret != NULL)
2444                 *pret = result;
2445             break;
2446     }
2447     return S_OK;
2448 }
2449 
QueryActiveShellView(IShellView ** ppshv)2450 HRESULT STDMETHODCALLTYPE CShellBrowser::QueryActiveShellView(IShellView **ppshv)
2451 {
2452     if (ppshv == NULL)
2453         return E_POINTER;
2454     *ppshv = fCurrentShellView;
2455     if (fCurrentShellView.p != NULL)
2456     {
2457         fCurrentShellView.p->AddRef();
2458         return S_OK;
2459     }
2460     return E_FAIL;
2461 }
2462 
OnViewWindowActive(IShellView * ppshv)2463 HRESULT STDMETHODCALLTYPE CShellBrowser::OnViewWindowActive(IShellView *ppshv)
2464 {
2465     return E_NOTIMPL;
2466 }
2467 
SetToolbarItems(LPTBBUTTON lpButtons,UINT nButtons,UINT uFlags)2468 HRESULT STDMETHODCALLTYPE CShellBrowser::SetToolbarItems(LPTBBUTTON lpButtons, UINT nButtons, UINT uFlags)
2469 {
2470     return E_NOTIMPL;
2471 }
2472 
DragEnter(IDataObject * pDataObj,DWORD grfKeyState,POINTL pt,DWORD * pdwEffect)2473 HRESULT STDMETHODCALLTYPE CShellBrowser::DragEnter(
2474     IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2475 {
2476     return E_NOTIMPL;
2477 }
2478 
DragOver(DWORD grfKeyState,POINTL pt,DWORD * pdwEffect)2479 HRESULT STDMETHODCALLTYPE CShellBrowser::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2480 {
2481     return E_NOTIMPL;
2482 }
2483 
DragLeave()2484 HRESULT STDMETHODCALLTYPE CShellBrowser::DragLeave()
2485 {
2486     return E_NOTIMPL;
2487 }
2488 
Drop(IDataObject * pDataObj,DWORD grfKeyState,POINTL pt,DWORD * pdwEffect)2489 HRESULT STDMETHODCALLTYPE CShellBrowser::Drop(
2490     IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2491 {
2492     return E_NOTIMPL;
2493 }
2494 
QueryService(REFGUID guidService,REFIID riid,void ** ppvObject)2495 HRESULT STDMETHODCALLTYPE CShellBrowser::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
2496 {
2497     // view does a query for SID_STopLevelBrowser, IID_IShellBrowserService
2498     // the returned interface has a method GetPropertyBag on it
2499     if (IsEqualIID(guidService, SID_STopLevelBrowser))
2500         return this->QueryInterface(riid, ppvObject);
2501     if (IsEqualIID(guidService, SID_SShellBrowser))
2502         return this->QueryInterface(riid, ppvObject);
2503     if (IsEqualIID(guidService, SID_ITargetFrame2))
2504         return this->QueryInterface(riid, ppvObject);
2505     if (IsEqualIID(guidService, SID_IWebBrowserApp))        // without this, the internet toolbar won't reflect notifications
2506         return this->QueryInterface(riid, ppvObject);
2507     if (IsEqualIID(guidService, SID_SProxyBrowser))
2508         return this->QueryInterface(riid, ppvObject);
2509     if (IsEqualIID(guidService, SID_IExplorerToolbar) && fClientBars[BIInternetToolbar].clientBar.p)
2510         return fClientBars[BIInternetToolbar].clientBar->QueryInterface(riid, ppvObject);
2511     if (IsEqualIID(riid, IID_IShellBrowser))
2512         return this->QueryInterface(riid, ppvObject);
2513     return E_NOINTERFACE;
2514 }
2515 
_ILIsNetworkPlace(LPCITEMIDLIST pidl)2516 static BOOL _ILIsNetworkPlace(LPCITEMIDLIST pidl)
2517 {
2518     WCHAR szPath[MAX_PATH];
2519     return SHGetPathFromIDListWrapW(pidl, szPath) && PathIsUNCW(szPath);
2520 }
2521 
GetPropertyBag(long flags,REFIID riid,void ** ppvObject)2522 HRESULT STDMETHODCALLTYPE CShellBrowser::GetPropertyBag(long flags, REFIID riid, void **ppvObject)
2523 {
2524     if (ppvObject == NULL)
2525         return E_POINTER;
2526 
2527     *ppvObject = NULL;
2528 
2529     LPITEMIDLIST pidl;
2530     HRESULT hr = GetPidl(&pidl);
2531     if (FAILED_UNEXPECTEDLY(hr))
2532         return E_FAIL;
2533 
2534     // FIXME: pidl for Internet etc.
2535 
2536     if (_ILIsNetworkPlace(pidl))
2537         flags |= SHGVSPB_ROAM;
2538 
2539     hr = SHGetViewStatePropertyBag(pidl, L"Shell", flags, riid, ppvObject);
2540 
2541     ILFree(pidl);
2542     return hr;
2543 }
2544 
GetTypeInfoCount(UINT * pctinfo)2545 HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfoCount(UINT *pctinfo)
2546 {
2547     return E_NOTIMPL;
2548 }
2549 
GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)2550 HRESULT STDMETHODCALLTYPE CShellBrowser::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
2551 {
2552     return E_NOTIMPL;
2553 }
2554 
GetIDsOfNames(REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)2555 HRESULT STDMETHODCALLTYPE CShellBrowser::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames,
2556     UINT cNames, LCID lcid, DISPID *rgDispId)
2557 {
2558     return E_NOTIMPL;
2559 }
2560 
Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)2561 HRESULT STDMETHODCALLTYPE CShellBrowser::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
2562     WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2563 {
2564     return E_NOTIMPL;
2565 }
2566 
GetParentSite(IOleInPlaceSite ** ppipsite)2567 HRESULT STDMETHODCALLTYPE CShellBrowser::GetParentSite(IOleInPlaceSite **ppipsite)
2568 {
2569     return E_NOTIMPL;
2570 }
2571 
SetTitle(IShellView * psv,LPCWSTR pszName)2572 HRESULT STDMETHODCALLTYPE CShellBrowser::SetTitle(IShellView *psv, LPCWSTR pszName)
2573 {
2574     return E_NOTIMPL;
2575 }
2576 
GetTitle(IShellView * psv,LPWSTR pszName,DWORD cchName)2577 HRESULT STDMETHODCALLTYPE CShellBrowser::GetTitle(IShellView *psv, LPWSTR pszName, DWORD cchName)
2578 {
2579     return E_NOTIMPL;
2580 }
2581 
GetOleObject(IOleObject ** ppobjv)2582 HRESULT STDMETHODCALLTYPE CShellBrowser::GetOleObject(IOleObject **ppobjv)
2583 {
2584     return E_NOTIMPL;
2585 }
2586 
GetTravelLog(ITravelLog ** pptl)2587 HRESULT STDMETHODCALLTYPE CShellBrowser::GetTravelLog(ITravelLog **pptl)
2588 {
2589     HRESULT                                 hResult;
2590 
2591     // called by toolbar when displaying tooltips
2592     if (pptl == NULL)
2593         return E_FAIL;
2594 
2595     *pptl = NULL;
2596     if (fTravelLog.p == NULL)
2597     {
2598         hResult = CTravelLog_CreateInstance(IID_PPV_ARG(ITravelLog, &fTravelLog));
2599         if (FAILED_UNEXPECTEDLY(hResult))
2600             return hResult;
2601     }
2602     *pptl = fTravelLog.p;
2603     fTravelLog.p->AddRef();
2604     return S_OK;
2605 }
2606 
ShowControlWindow(UINT id,BOOL fShow)2607 HRESULT STDMETHODCALLTYPE CShellBrowser::ShowControlWindow(UINT id, BOOL fShow)
2608 {
2609     BOOL shown;
2610     if (FAILED(IsControlWindowShown(id, &shown)))
2611         return E_NOTIMPL;
2612     else if (!shown == !fShow) // Negated for true boolean comparison
2613         return S_OK;
2614     else switch (id)
2615     {
2616         case FCW_STATUS:
2617             OnToggleStatusBarVisible(0, 0, NULL, shown);
2618             return S_OK;
2619         case FCW_TREE:
2620             return Exec(&CGID_Explorer, SBCMDID_EXPLORERBARFOLDERS, 0, NULL, NULL);
2621         case FCW_ADDRESSBAR:
2622             return IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
2623                                  CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
2624     }
2625     return E_NOTIMPL;
2626 }
2627 
IsControlWindowShown(UINT id,BOOL * pfShown)2628 HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfShown)
2629 {
2630     HRESULT hr = S_OK;
2631     BOOL shown = FALSE;
2632     switch (id)
2633     {
2634         case FCW_STATUS:
2635             shown = m_settings.fStatusBarVisible;
2636             break;
2637         case FCW_TREE:
2638         {
2639             OLECMD cmd = { SBCMDID_EXPLORERBARFOLDERS };
2640             hr = QueryStatus(&CGID_Explorer, 1, &cmd, NULL);
2641             shown = cmd.cmdf & OLECMDF_LATCHED;
2642             break;
2643         }
2644         case FCW_ADDRESSBAR:
2645             hr = IsInternetToolbarBandShown(ITID_ADDRESSBANDSHOWN);
2646             shown = hr == S_OK;
2647             break;
2648         default:
2649             hr = E_NOTIMPL;
2650     }
2651     if (pfShown)
2652     {
2653         *pfShown = shown;
2654         return hr;
2655     }
2656     return SUCCEEDED(hr) ? (shown ? S_OK : S_FALSE) : hr;
2657 }
2658 
IsInternetToolbarBandShown(UINT ITId)2659 HRESULT CShellBrowser::IsInternetToolbarBandShown(UINT ITId)
2660 {
2661     OLECMD cmd = { ITId };
2662     HRESULT hr = IUnknown_QueryStatus(fClientBars[BIInternetToolbar].clientBar,
2663                                       CGID_PrivCITCommands, 1, &cmd, NULL);
2664     return SUCCEEDED(hr) ? (cmd.cmdf & OLECMDF_LATCHED) ? S_OK : S_FALSE : hr;
2665 }
2666 
IEGetDisplayName(LPCITEMIDLIST pidl,LPWSTR pwszName,UINT uFlags)2667 HRESULT STDMETHODCALLTYPE CShellBrowser::IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags)
2668 {
2669     return E_NOTIMPL;
2670 }
2671 
IEParseDisplayName(UINT uiCP,LPCWSTR pwszPath,LPITEMIDLIST * ppidlOut)2672 HRESULT STDMETHODCALLTYPE CShellBrowser::IEParseDisplayName(UINT uiCP, LPCWSTR pwszPath, LPITEMIDLIST *ppidlOut)
2673 {
2674     return E_NOTIMPL;
2675 }
2676 
DisplayParseError(HRESULT hres,LPCWSTR pwszPath)2677 HRESULT STDMETHODCALLTYPE CShellBrowser::DisplayParseError(HRESULT hres, LPCWSTR pwszPath)
2678 {
2679     return E_NOTIMPL;
2680 }
2681 
NavigateToPidl(LPCITEMIDLIST pidl,DWORD grfHLNF)2682 HRESULT STDMETHODCALLTYPE CShellBrowser::NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF)
2683 {
2684     return _NavigateToPidl(pidl, grfHLNF, 0);
2685 }
2686 
SetNavigateState(BNSTATE bnstate)2687 HRESULT STDMETHODCALLTYPE CShellBrowser::SetNavigateState(BNSTATE bnstate)
2688 {
2689     return E_NOTIMPL;
2690 }
2691 
GetNavigateState(BNSTATE * pbnstate)2692 HRESULT STDMETHODCALLTYPE CShellBrowser::GetNavigateState(BNSTATE *pbnstate)
2693 {
2694     return E_NOTIMPL;
2695 }
2696 
NotifyRedirect(IShellView * psv,LPCITEMIDLIST pidl,BOOL * pfDidBrowse)2697 HRESULT STDMETHODCALLTYPE CShellBrowser::NotifyRedirect(IShellView *psv, LPCITEMIDLIST pidl, BOOL *pfDidBrowse)
2698 {
2699     return E_NOTIMPL;
2700 }
2701 
UpdateWindowList()2702 HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateWindowList()
2703 {
2704     return E_NOTIMPL;
2705 }
2706 
UpdateBackForwardState()2707 HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateBackForwardState()
2708 {
2709     return E_NOTIMPL;
2710 }
2711 
SetFlags(DWORD dwFlags,DWORD dwFlagMask)2712 HRESULT STDMETHODCALLTYPE CShellBrowser::SetFlags(DWORD dwFlags, DWORD dwFlagMask)
2713 {
2714     m_BrowserSvcFlags = (m_BrowserSvcFlags & ~dwFlagMask) | (dwFlags & dwFlagMask);
2715     return S_OK;
2716 }
2717 
GetFlags(DWORD * pdwFlags)2718 HRESULT STDMETHODCALLTYPE CShellBrowser::GetFlags(DWORD *pdwFlags)
2719 {
2720     *pdwFlags = m_BrowserSvcFlags;
2721     return S_OK;
2722 }
2723 
CanNavigateNow()2724 HRESULT STDMETHODCALLTYPE CShellBrowser::CanNavigateNow()
2725 {
2726     return E_NOTIMPL;
2727 }
2728 
GetPidl(LPITEMIDLIST * ppidl)2729 HRESULT STDMETHODCALLTYPE CShellBrowser::GetPidl(LPITEMIDLIST *ppidl)
2730 {
2731     // called by explorer bar to get current pidl
2732     return ppidl ? SHILClone(fCurrentDirectoryPIDL, ppidl) : E_POINTER;
2733 }
2734 
SetReferrer(LPCITEMIDLIST pidl)2735 HRESULT STDMETHODCALLTYPE CShellBrowser::SetReferrer(LPCITEMIDLIST pidl)
2736 {
2737     return E_NOTIMPL;
2738 }
2739 
GetBrowserIndex()2740 DWORD STDMETHODCALLTYPE CShellBrowser::GetBrowserIndex()
2741 {
2742     return -1;
2743 }
2744 
GetBrowserByIndex(DWORD dwID,IUnknown ** ppunk)2745 HRESULT STDMETHODCALLTYPE CShellBrowser::GetBrowserByIndex(DWORD dwID, IUnknown **ppunk)
2746 {
2747     return E_NOTIMPL;
2748 }
2749 
GetHistoryObject(IOleObject ** ppole,IStream ** pstm,IBindCtx ** ppbc)2750 HRESULT STDMETHODCALLTYPE CShellBrowser::GetHistoryObject(IOleObject **ppole, IStream **pstm, IBindCtx **ppbc)
2751 {
2752     if (ppole == NULL || pstm == NULL || ppbc == NULL)
2753         return E_INVALIDARG;
2754     *ppole = fHistoryObject;
2755     if (fHistoryObject != NULL)
2756         fHistoryObject->AddRef();
2757     *pstm = fHistoryStream;
2758     if (fHistoryStream != NULL)
2759         fHistoryStream->AddRef();
2760     *ppbc = fHistoryBindContext;
2761     if (fHistoryBindContext != NULL)
2762         fHistoryBindContext->AddRef();
2763     fHistoryObject = NULL;
2764     fHistoryStream = NULL;
2765     fHistoryBindContext = NULL;
2766     if (*ppole == NULL)
2767         return E_FAIL;
2768     return S_OK;
2769 }
2770 
SetHistoryObject(IOleObject * pole,BOOL fIsLocalAnchor)2771 HRESULT STDMETHODCALLTYPE CShellBrowser::SetHistoryObject(IOleObject *pole, BOOL fIsLocalAnchor)
2772 {
2773     return E_NOTIMPL;
2774 }
2775 
CacheOLEServer(IOleObject * pole)2776 HRESULT STDMETHODCALLTYPE CShellBrowser::CacheOLEServer(IOleObject *pole)
2777 {
2778     return E_NOTIMPL;
2779 }
2780 
GetSetCodePage(VARIANT * pvarIn,VARIANT * pvarOut)2781 HRESULT STDMETHODCALLTYPE CShellBrowser::GetSetCodePage(VARIANT *pvarIn, VARIANT *pvarOut)
2782 {
2783     return E_NOTIMPL;
2784 }
2785 
OnHttpEquiv(IShellView * psv,BOOL fDone,VARIANT * pvarargIn,VARIANT * pvarargOut)2786 HRESULT STDMETHODCALLTYPE CShellBrowser::OnHttpEquiv(
2787     IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut)
2788 {
2789     return E_NOTIMPL;
2790 }
2791 
GetPalette(HPALETTE * hpal)2792 HRESULT STDMETHODCALLTYPE CShellBrowser::GetPalette(HPALETTE *hpal)
2793 {
2794     return E_NOTIMPL;
2795 }
2796 
RegisterWindow(BOOL fForceRegister,int swc)2797 HRESULT STDMETHODCALLTYPE CShellBrowser::RegisterWindow(BOOL fForceRegister, int swc)
2798 {
2799     return E_NOTIMPL;
2800 }
2801 
WndProcBS(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)2802 LRESULT STDMETHODCALLTYPE CShellBrowser::WndProcBS(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2803 {
2804     return E_NOTIMPL;
2805 }
2806 
SetAsDefFolderSettings()2807 HRESULT STDMETHODCALLTYPE CShellBrowser::SetAsDefFolderSettings()
2808 {
2809     HRESULT hr = E_FAIL;
2810     if (fCurrentShellView)
2811     {
2812         hr = ApplyBrowserDefaultFolderSettings(fCurrentShellView);
2813         IUnknown_Exec(fCurrentShellView, CGID_DefView, DVCMDID_SET_DEFAULTFOLDER_SETTINGS, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
2814     }
2815     return hr;
2816 }
2817 
GetViewRect(RECT * prc)2818 HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewRect(RECT *prc)
2819 {
2820     return E_NOTIMPL;
2821 }
2822 
OnSize(WPARAM wParam)2823 HRESULT STDMETHODCALLTYPE CShellBrowser::OnSize(WPARAM wParam)
2824 {
2825     return E_NOTIMPL;
2826 }
2827 
OnCreate(struct tagCREATESTRUCTW * pcs)2828 HRESULT STDMETHODCALLTYPE CShellBrowser::OnCreate(struct tagCREATESTRUCTW *pcs)
2829 {
2830     m_hAccel = LoadAcceleratorsW(GetModuleHandle(L"browseui.dll"), MAKEINTRESOURCEW(256));
2831     return S_OK;
2832 }
2833 
OnCommand(WPARAM wParam,LPARAM lParam)2834 LRESULT STDMETHODCALLTYPE CShellBrowser::OnCommand(WPARAM wParam, LPARAM lParam)
2835 {
2836     return 0;
2837 }
2838 
OnDestroy()2839 HRESULT STDMETHODCALLTYPE CShellBrowser::OnDestroy()
2840 {
2841     return E_NOTIMPL;
2842 }
2843 
OnNotify(struct tagNMHDR * pnm)2844 LRESULT STDMETHODCALLTYPE CShellBrowser::OnNotify(struct tagNMHDR *pnm)
2845 {
2846     return 0;
2847 }
2848 
OnSetFocus()2849 HRESULT STDMETHODCALLTYPE CShellBrowser::OnSetFocus()
2850 {
2851     return E_NOTIMPL;
2852 }
2853 
OnFrameWindowActivateBS(BOOL fActive)2854 HRESULT STDMETHODCALLTYPE CShellBrowser::OnFrameWindowActivateBS(BOOL fActive)
2855 {
2856     return E_NOTIMPL;
2857 }
2858 
ReleaseShellView()2859 HRESULT STDMETHODCALLTYPE CShellBrowser::ReleaseShellView()
2860 {
2861     return E_NOTIMPL;
2862 }
2863 
ActivatePendingView()2864 HRESULT STDMETHODCALLTYPE CShellBrowser::ActivatePendingView()
2865 {
2866     return E_NOTIMPL;
2867 }
2868 
CreateViewWindow(IShellView * psvNew,IShellView * psvOld,LPRECT prcView,HWND * phwnd)2869 HRESULT STDMETHODCALLTYPE CShellBrowser::CreateViewWindow(
2870     IShellView *psvNew, IShellView *psvOld, LPRECT prcView, HWND *phwnd)
2871 {
2872     return E_NOTIMPL;
2873 }
2874 
CreateBrowserPropSheetExt(REFIID riid,void ** ppv)2875 HRESULT STDMETHODCALLTYPE CShellBrowser::CreateBrowserPropSheetExt(REFIID riid, void **ppv)
2876 {
2877     return E_NOTIMPL;
2878 }
2879 
GetViewWindow(HWND * phwndView)2880 HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewWindow(HWND *phwndView)
2881 {
2882     return E_NOTIMPL;
2883 }
2884 
GetBaseBrowserData(LPCBASEBROWSERDATA * pbbd)2885 HRESULT STDMETHODCALLTYPE CShellBrowser::GetBaseBrowserData(LPCBASEBROWSERDATA *pbbd)
2886 {
2887     return E_NOTIMPL;
2888 }
2889 
PutBaseBrowserData()2890 LPBASEBROWSERDATA STDMETHODCALLTYPE CShellBrowser::PutBaseBrowserData()
2891 {
2892     return NULL;
2893 }
2894 
InitializeTravelLog(ITravelLog * ptl,DWORD dw)2895 HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTravelLog(ITravelLog *ptl, DWORD dw)
2896 {
2897     return E_NOTIMPL;
2898 }
2899 
SetTopBrowser()2900 HRESULT STDMETHODCALLTYPE CShellBrowser::SetTopBrowser()
2901 {
2902     m_BrowserSvcFlags |= BSF_TOPBROWSER;
2903     return S_OK;
2904 }
2905 
Offline(int iCmd)2906 HRESULT STDMETHODCALLTYPE CShellBrowser::Offline(int iCmd)
2907 {
2908     return E_NOTIMPL;
2909 }
2910 
AllowViewResize(BOOL f)2911 HRESULT STDMETHODCALLTYPE CShellBrowser::AllowViewResize(BOOL f)
2912 {
2913     return E_NOTIMPL;
2914 }
2915 
SetActivateState(UINT u)2916 HRESULT STDMETHODCALLTYPE CShellBrowser::SetActivateState(UINT u)
2917 {
2918     return E_NOTIMPL;
2919 }
2920 
UpdateSecureLockIcon(int eSecureLock)2921 HRESULT STDMETHODCALLTYPE CShellBrowser::UpdateSecureLockIcon(int eSecureLock)
2922 {
2923     return E_NOTIMPL;
2924 }
2925 
InitializeDownloadManager()2926 HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeDownloadManager()
2927 {
2928     return E_NOTIMPL;
2929 }
2930 
InitializeTransitionSite()2931 HRESULT STDMETHODCALLTYPE CShellBrowser::InitializeTransitionSite()
2932 {
2933     return E_NOTIMPL;
2934 }
2935 
_Initialize(HWND hwnd,IUnknown * pauto)2936 HRESULT STDMETHODCALLTYPE CShellBrowser::_Initialize(HWND hwnd, IUnknown *pauto)
2937 {
2938     return E_NOTIMPL;
2939 }
2940 
_CancelPendingNavigationAsync()2941 HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingNavigationAsync()
2942 {
2943     return E_NOTIMPL;
2944 }
2945 
_CancelPendingView()2946 HRESULT STDMETHODCALLTYPE CShellBrowser::_CancelPendingView()
2947 {
2948     return E_NOTIMPL;
2949 }
2950 
_MaySaveChanges()2951 HRESULT STDMETHODCALLTYPE CShellBrowser::_MaySaveChanges()
2952 {
2953     return E_NOTIMPL;
2954 }
2955 
_PauseOrResumeView(BOOL fPaused)2956 HRESULT STDMETHODCALLTYPE CShellBrowser::_PauseOrResumeView(BOOL fPaused)
2957 {
2958     return E_NOTIMPL;
2959 }
2960 
_DisableModeless()2961 HRESULT STDMETHODCALLTYPE CShellBrowser::_DisableModeless()
2962 {
2963     return E_NOTIMPL;
2964 }
2965 
_NavigateToPidl(LPCITEMIDLIST pidl,DWORD grfHLNF,DWORD dwFlags)2966 HRESULT STDMETHODCALLTYPE CShellBrowser::_NavigateToPidl(LPCITEMIDLIST pidl, DWORD grfHLNF, DWORD dwFlags)
2967 {
2968     const UINT navflags = HLNF_NAVIGATINGBACK | HLNF_NAVIGATINGFORWARD;
2969     if ((grfHLNF & navflags) && grfHLNF != ~0ul)
2970     {
2971         UINT SbspFlags = (grfHLNF & HLNF_NAVIGATINGBACK) ? SBSP_NAVIGATEBACK : SBSP_NAVIGATEFORWARD;
2972         if (grfHLNF & SHHLNF_WRITENOHISTORY)
2973             SbspFlags |= SBSP_WRITENOHISTORY;
2974         if (grfHLNF & SHHLNF_NOAUTOSELECT)
2975             SbspFlags |= SBSP_NOAUTOSELECT;
2976         return BrowseObject(pidl, SbspFlags);
2977     }
2978     return E_NOTIMPL;
2979 }
2980 
_TryShell2Rename(IShellView * psv,LPCITEMIDLIST pidlNew)2981 HRESULT STDMETHODCALLTYPE CShellBrowser::_TryShell2Rename(IShellView *psv, LPCITEMIDLIST pidlNew)
2982 {
2983     return E_NOTIMPL;
2984 }
2985 
_SwitchActivationNow()2986 HRESULT STDMETHODCALLTYPE CShellBrowser::_SwitchActivationNow()
2987 {
2988     return E_NOTIMPL;
2989 }
2990 
_ExecChildren(IUnknown * punkBar,BOOL fBroadcast,const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdexecopt,VARIANTARG * pvarargIn,VARIANTARG * pvarargOut)2991 HRESULT STDMETHODCALLTYPE CShellBrowser::_ExecChildren(IUnknown *punkBar, BOOL fBroadcast,
2992     const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut)
2993 {
2994     return E_NOTIMPL;
2995 }
2996 
_SendChildren(HWND hwndBar,BOOL fBroadcast,UINT uMsg,WPARAM wParam,LPARAM lParam)2997 HRESULT STDMETHODCALLTYPE CShellBrowser::_SendChildren(
2998     HWND hwndBar, BOOL fBroadcast, UINT uMsg, WPARAM wParam, LPARAM lParam)
2999 {
3000     return E_NOTIMPL;
3001 }
3002 
GetFolderSetData(struct tagFolderSetData * pfsd)3003 HRESULT STDMETHODCALLTYPE CShellBrowser::GetFolderSetData(struct tagFolderSetData *pfsd)
3004 {
3005     return E_NOTIMPL;
3006 }
3007 
_OnFocusChange(UINT itb)3008 HRESULT STDMETHODCALLTYPE CShellBrowser::_OnFocusChange(UINT itb)
3009 {
3010     return E_NOTIMPL;
3011 }
3012 
v_ShowHideChildWindows(BOOL fChildOnly)3013 HRESULT STDMETHODCALLTYPE CShellBrowser::v_ShowHideChildWindows(BOOL fChildOnly)
3014 {
3015     return E_NOTIMPL;
3016 }
3017 
_get_itbLastFocus()3018 UINT STDMETHODCALLTYPE CShellBrowser::_get_itbLastFocus()
3019 {
3020     return 0;
3021 }
3022 
_put_itbLastFocus(UINT itbLastFocus)3023 HRESULT STDMETHODCALLTYPE CShellBrowser::_put_itbLastFocus(UINT itbLastFocus)
3024 {
3025     return E_NOTIMPL;
3026 }
3027 
_UIActivateView(UINT uState)3028 HRESULT STDMETHODCALLTYPE CShellBrowser::_UIActivateView(UINT uState)
3029 {
3030     return E_NOTIMPL;
3031 }
3032 
_GetViewBorderRect(RECT * prc)3033 HRESULT STDMETHODCALLTYPE CShellBrowser::_GetViewBorderRect(RECT *prc)
3034 {
3035     return E_NOTIMPL;
3036 }
3037 
_UpdateViewRectSize()3038 HRESULT STDMETHODCALLTYPE CShellBrowser::_UpdateViewRectSize()
3039 {
3040     return E_NOTIMPL;
3041 }
3042 
_ResizeNextBorder(UINT itb)3043 HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorder(UINT itb)
3044 {
3045     return E_NOTIMPL;
3046 }
3047 
_ResizeView()3048 HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeView()
3049 {
3050     return E_NOTIMPL;
3051 }
3052 
_GetEffectiveClientArea(LPRECT lprectBorder,HMONITOR hmon)3053 HRESULT STDMETHODCALLTYPE CShellBrowser::_GetEffectiveClientArea(LPRECT lprectBorder, HMONITOR hmon)
3054 {
3055     return E_NOTIMPL;
3056 }
3057 
v_GetViewStream(LPCITEMIDLIST pidl,DWORD grfMode,LPCWSTR pwszName)3058 IStream *STDMETHODCALLTYPE CShellBrowser::v_GetViewStream(LPCITEMIDLIST pidl, DWORD grfMode, LPCWSTR pwszName)
3059 {
3060     return NULL;
3061 }
3062 
ForwardViewMsg(UINT uMsg,WPARAM wParam,LPARAM lParam)3063 LRESULT STDMETHODCALLTYPE CShellBrowser::ForwardViewMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
3064 {
3065     return 0;
3066 }
3067 
SetAcceleratorMenu(HACCEL hacc)3068 HRESULT STDMETHODCALLTYPE CShellBrowser::SetAcceleratorMenu(HACCEL hacc)
3069 {
3070     return E_NOTIMPL;
3071 }
3072 
_GetToolbarCount()3073 int STDMETHODCALLTYPE CShellBrowser::_GetToolbarCount()
3074 {
3075     return 0;
3076 }
3077 
_GetToolbarItem(int itb)3078 LPTOOLBARITEM STDMETHODCALLTYPE CShellBrowser::_GetToolbarItem(int itb)
3079 {
3080     return NULL;
3081 }
3082 
_SaveToolbars(IStream * pstm)3083 HRESULT STDMETHODCALLTYPE CShellBrowser::_SaveToolbars(IStream *pstm)
3084 {
3085     return E_NOTIMPL;
3086 }
3087 
_LoadToolbars(IStream * pstm)3088 HRESULT STDMETHODCALLTYPE CShellBrowser::_LoadToolbars(IStream *pstm)
3089 {
3090     return E_NOTIMPL;
3091 }
3092 
_CloseAndReleaseToolbars(BOOL fClose)3093 HRESULT STDMETHODCALLTYPE CShellBrowser::_CloseAndReleaseToolbars(BOOL fClose)
3094 {
3095     return E_NOTIMPL;
3096 }
3097 
v_MayGetNextToolbarFocus(LPMSG lpMsg,UINT itbNext,int citb,LPTOOLBARITEM * pptbi,HWND * phwnd)3098 HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayGetNextToolbarFocus(
3099     LPMSG lpMsg, UINT itbNext, int citb, LPTOOLBARITEM *pptbi, HWND *phwnd)
3100 {
3101     return E_NOTIMPL;
3102 }
3103 
_ResizeNextBorderHelper(UINT itb,BOOL bUseHmonitor)3104 HRESULT STDMETHODCALLTYPE CShellBrowser::_ResizeNextBorderHelper(UINT itb, BOOL bUseHmonitor)
3105 {
3106     return E_NOTIMPL;
3107 }
3108 
_FindTBar(IUnknown * punkSrc)3109 UINT STDMETHODCALLTYPE CShellBrowser::_FindTBar(IUnknown *punkSrc)
3110 {
3111     return 0;
3112 }
3113 
_SetFocus(LPTOOLBARITEM ptbi,HWND hwnd,LPMSG lpMsg)3114 HRESULT STDMETHODCALLTYPE CShellBrowser::_SetFocus(LPTOOLBARITEM ptbi, HWND hwnd, LPMSG lpMsg)
3115 {
3116     return E_NOTIMPL;
3117 }
3118 
v_MayTranslateAccelerator(MSG * pmsg)3119 HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg)
3120 {
3121     for (int i = 0; i < 3; i++)
3122     {
3123         if (IUnknown_TranslateAcceleratorIO(fClientBars[i].clientBar, pmsg) == S_OK)
3124             return S_OK;
3125     }
3126 
3127     if (!fCurrentShellView)
3128         return S_FALSE;
3129 
3130     return fCurrentShellView->TranslateAcceleratorW(pmsg);
3131 }
3132 
_GetBorderDWHelper(IUnknown * punkSrc,LPRECT lprectBorder,BOOL bUseHmonitor)3133 HRESULT STDMETHODCALLTYPE CShellBrowser::_GetBorderDWHelper(IUnknown *punkSrc, LPRECT lprectBorder, BOOL bUseHmonitor)
3134 {
3135     return E_NOTIMPL;
3136 }
3137 
v_CheckZoneCrossing(LPCITEMIDLIST pidl)3138 HRESULT STDMETHODCALLTYPE CShellBrowser::v_CheckZoneCrossing(LPCITEMIDLIST pidl)
3139 {
3140     return E_NOTIMPL;
3141 }
3142 
GoBack()3143 HRESULT STDMETHODCALLTYPE CShellBrowser::GoBack()
3144 {
3145     CComPtr<ITravelLog> travelLog;
3146     HRESULT hResult = GetTravelLog(&travelLog);
3147     if (FAILED_UNEXPECTEDLY(hResult))
3148         return hResult;
3149     return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_BACK);
3150 }
3151 
GoForward()3152 HRESULT STDMETHODCALLTYPE CShellBrowser::GoForward()
3153 {
3154     CComPtr<ITravelLog> travelLog;
3155     HRESULT hResult = GetTravelLog(&travelLog);
3156     if (FAILED_UNEXPECTEDLY(hResult))
3157         return hResult;
3158     return travelLog->Travel(static_cast<IDropTarget *>(this), TLOG_FORE);
3159 }
3160 
GoHome()3161 HRESULT STDMETHODCALLTYPE CShellBrowser::GoHome()
3162 {
3163     return E_NOTIMPL;
3164 }
3165 
GoSearch()3166 HRESULT STDMETHODCALLTYPE CShellBrowser::GoSearch()
3167 {
3168     return E_NOTIMPL;
3169 }
3170 
Navigate(BSTR URL,VARIANT * Flags,VARIANT * TargetFrameName,VARIANT * PostData,VARIANT * Headers)3171 HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate(BSTR URL, VARIANT *Flags,
3172     VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
3173 {
3174     CComHeapPtr<ITEMIDLIST> pidl;
3175     HRESULT hResult;
3176     CComPtr<IShellFolder> pDesktop;
3177 
3178     hResult = SHGetDesktopFolder(&pDesktop);
3179     if (FAILED_UNEXPECTEDLY(hResult))
3180         return hResult;
3181     hResult = pDesktop->ParseDisplayName(NULL, NULL, URL, NULL, &pidl, NULL);
3182     if (FAILED_UNEXPECTEDLY(hResult))
3183         return hResult;
3184     return BrowseObject(pidl, 1);
3185 }
3186 
Refresh()3187 HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh()
3188 {
3189     VARIANT                                 level;
3190 
3191     V_VT(&level) = VT_I4;
3192     V_I4(&level) = 4;
3193     return Refresh2(&level);
3194 }
3195 
Refresh2(VARIANT * Level)3196 HRESULT STDMETHODCALLTYPE CShellBrowser::Refresh2(VARIANT *Level)
3197 {
3198     CComPtr<IOleCommandTarget>              oleCommandTarget;
3199     HRESULT                                 hResult;
3200 
3201     hResult = fCurrentShellView->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
3202     if (FAILED_UNEXPECTEDLY(hResult))
3203         return hResult;
3204     return oleCommandTarget->Exec(NULL, 22, 1, Level, NULL);
3205 }
3206 
Stop()3207 HRESULT STDMETHODCALLTYPE CShellBrowser::Stop()
3208 {
3209     return E_NOTIMPL;
3210 }
3211 
get_Application(IDispatch ** ppDisp)3212 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Application(IDispatch **ppDisp)
3213 {
3214     return E_NOTIMPL;
3215 }
3216 
get_Parent(IDispatch ** ppDisp)3217 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Parent(IDispatch **ppDisp)
3218 {
3219     return E_NOTIMPL;
3220 }
3221 
get_Container(IDispatch ** ppDisp)3222 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Container(IDispatch **ppDisp)
3223 {
3224     return E_NOTIMPL;
3225 }
3226 
get_Document(IDispatch ** ppDisp)3227 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Document(IDispatch **ppDisp)
3228 {
3229     return E_NOTIMPL;
3230 }
3231 
get_TopLevelContainer(VARIANT_BOOL * pBool)3232 HRESULT STDMETHODCALLTYPE CShellBrowser::get_TopLevelContainer(VARIANT_BOOL *pBool)
3233 {
3234     return E_NOTIMPL;
3235 }
3236 
get_Type(BSTR * Type)3237 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Type(BSTR *Type)
3238 {
3239     return E_NOTIMPL;
3240 }
3241 #ifdef __exdisp_h__
3242 #define long LONG
3243 #endif
get_Left(long * pl)3244 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Left(long *pl)
3245 {
3246     return E_NOTIMPL;
3247 }
3248 
put_Left(long Left)3249 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Left(long Left)
3250 {
3251     return E_NOTIMPL;
3252 }
3253 
get_Top(long * pl)3254 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Top(long *pl)
3255 {
3256     return E_NOTIMPL;
3257 }
3258 
put_Top(long Top)3259 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Top(long Top)
3260 {
3261     return E_NOTIMPL;
3262 }
3263 
get_Width(long * pl)3264 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Width(long *pl)
3265 {
3266     return E_NOTIMPL;
3267 }
3268 
put_Width(long Width)3269 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Width(long Width)
3270 {
3271     return E_NOTIMPL;
3272 }
3273 
get_Height(long * pl)3274 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Height(long *pl)
3275 {
3276     return E_NOTIMPL;
3277 }
3278 
put_Height(long Height)3279 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Height(long Height)
3280 {
3281     return E_NOTIMPL;
3282 }
3283 #ifdef __exdisp_h__
3284 #undef long
3285 #endif
get_LocationName(BSTR * LocationName)3286 HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationName(BSTR *LocationName)
3287 {
3288     return E_NOTIMPL;
3289 }
3290 
get_LocationURL(BSTR * LocationURL)3291 HRESULT STDMETHODCALLTYPE CShellBrowser::get_LocationURL(BSTR *LocationURL)
3292 {
3293     return E_NOTIMPL;
3294 }
3295 
get_Busy(VARIANT_BOOL * pBool)3296 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Busy(VARIANT_BOOL *pBool)
3297 {
3298     return E_NOTIMPL;
3299 }
3300 
Quit()3301 HRESULT STDMETHODCALLTYPE CShellBrowser::Quit()
3302 {
3303     return E_NOTIMPL;
3304 }
3305 
ClientToWindow(int * pcx,int * pcy)3306 HRESULT STDMETHODCALLTYPE CShellBrowser::ClientToWindow(int *pcx, int *pcy)
3307 {
3308     return E_NOTIMPL;
3309 }
3310 
PutProperty(BSTR Property,VARIANT vtValue)3311 HRESULT STDMETHODCALLTYPE CShellBrowser::PutProperty(BSTR Property, VARIANT vtValue)
3312 {
3313     return E_NOTIMPL;
3314 }
3315 
GetProperty(BSTR Property,VARIANT * pvtValue)3316 HRESULT STDMETHODCALLTYPE CShellBrowser::GetProperty(BSTR Property, VARIANT *pvtValue)
3317 {
3318     return E_NOTIMPL;
3319 }
3320 
get_Name(BSTR * Name)3321 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Name(BSTR *Name)
3322 {
3323     return E_NOTIMPL;
3324 }
3325 
get_HWND(SHANDLE_PTR * pHWND)3326 HRESULT STDMETHODCALLTYPE CShellBrowser::get_HWND(SHANDLE_PTR *pHWND)
3327 {
3328     return E_NOTIMPL;
3329 }
3330 
get_FullName(BSTR * FullName)3331 HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullName(BSTR *FullName)
3332 {
3333     return E_NOTIMPL;
3334 }
3335 
get_Path(BSTR * Path)3336 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Path(BSTR *Path)
3337 {
3338     return E_NOTIMPL;
3339 }
3340 
get_Visible(VARIANT_BOOL * pBool)3341 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Visible(VARIANT_BOOL *pBool)
3342 {
3343     return E_NOTIMPL;
3344 }
3345 
put_Visible(VARIANT_BOOL Value)3346 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Visible(VARIANT_BOOL Value)
3347 {
3348     return E_NOTIMPL;
3349 }
3350 
get_StatusBar(VARIANT_BOOL * pBool)3351 HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusBar(VARIANT_BOOL *pBool)
3352 {
3353     return E_NOTIMPL;
3354 }
3355 
put_StatusBar(VARIANT_BOOL Value)3356 HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusBar(VARIANT_BOOL Value)
3357 {
3358     return E_NOTIMPL;
3359 }
3360 
get_StatusText(BSTR * StatusText)3361 HRESULT STDMETHODCALLTYPE CShellBrowser::get_StatusText(BSTR *StatusText)
3362 {
3363     return E_NOTIMPL;
3364 }
3365 
put_StatusText(BSTR StatusText)3366 HRESULT STDMETHODCALLTYPE CShellBrowser::put_StatusText(BSTR StatusText)
3367 {
3368     return E_NOTIMPL;
3369 }
3370 
get_ToolBar(int * Value)3371 HRESULT STDMETHODCALLTYPE CShellBrowser::get_ToolBar(int *Value)
3372 {
3373     return E_NOTIMPL;
3374 }
3375 
put_ToolBar(int Value)3376 HRESULT STDMETHODCALLTYPE CShellBrowser::put_ToolBar(int Value)
3377 {
3378     return E_NOTIMPL;
3379 }
3380 
get_MenuBar(VARIANT_BOOL * Value)3381 HRESULT STDMETHODCALLTYPE CShellBrowser::get_MenuBar(VARIANT_BOOL *Value)
3382 {
3383     return E_NOTIMPL;
3384 }
3385 
put_MenuBar(VARIANT_BOOL Value)3386 HRESULT STDMETHODCALLTYPE CShellBrowser::put_MenuBar(VARIANT_BOOL Value)
3387 {
3388     return E_NOTIMPL;
3389 }
3390 
get_FullScreen(VARIANT_BOOL * pbFullScreen)3391 HRESULT STDMETHODCALLTYPE CShellBrowser::get_FullScreen(VARIANT_BOOL *pbFullScreen)
3392 {
3393     return E_NOTIMPL;
3394 }
3395 
put_FullScreen(VARIANT_BOOL bFullScreen)3396 HRESULT STDMETHODCALLTYPE CShellBrowser::put_FullScreen(VARIANT_BOOL bFullScreen)
3397 {
3398     return E_NOTIMPL;
3399 }
3400 
Navigate2(VARIANT * URL,VARIANT * Flags,VARIANT * TargetFrameName,VARIANT * PostData,VARIANT * Headers)3401 HRESULT STDMETHODCALLTYPE CShellBrowser::Navigate2(VARIANT *URL, VARIANT *Flags,
3402     VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers)
3403 {
3404     LPITEMIDLIST pidl = NULL;
3405     HRESULT hResult;
3406     // called from drive combo box to navigate to a directory
3407     // Also called by search band to display shell results folder view
3408 
3409     if (V_VT(URL) == VT_BSTR)
3410     {
3411         return this->Navigate(V_BSTR(URL), Flags, TargetFrameName, PostData, Headers);
3412     }
3413     if (V_VT(URL) == (VT_ARRAY | VT_UI1))
3414     {
3415         if (V_ARRAY(URL)->cDims != 1 || V_ARRAY(URL)->cbElements != 1)
3416             return E_INVALIDARG;
3417 
3418         pidl = static_cast<LPITEMIDLIST>(V_ARRAY(URL)->pvData);
3419     }
3420     hResult = BrowseToPIDL(pidl, BTP_UPDATE_CUR_HISTORY | BTP_UPDATE_NEXT_HISTORY);
3421     if (FAILED_UNEXPECTEDLY(hResult))
3422         return hResult;
3423     return S_OK;
3424 }
3425 
QueryStatusWB(OLECMDID cmdID,OLECMDF * pcmdf)3426 HRESULT STDMETHODCALLTYPE CShellBrowser::QueryStatusWB(OLECMDID cmdID, OLECMDF *pcmdf)
3427 {
3428     return E_NOTIMPL;
3429 }
3430 
ExecWB(OLECMDID cmdID,OLECMDEXECOPT cmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)3431 HRESULT STDMETHODCALLTYPE CShellBrowser::ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt,
3432     VARIANT *pvaIn, VARIANT *pvaOut)
3433 {
3434     return E_NOTIMPL;
3435 }
3436 
ShowBrowserBar(VARIANT * pvaClsid,VARIANT * pvarShow,VARIANT * pvarSize)3437 HRESULT STDMETHODCALLTYPE CShellBrowser::ShowBrowserBar(VARIANT *pvaClsid, VARIANT *pvarShow, VARIANT *pvarSize)
3438 {
3439     CLSID                                   classID;
3440     bool                                    vertical;
3441 
3442     // called to show search bar
3443     if (V_VT(pvaClsid) != VT_BSTR)
3444         return E_INVALIDARG;
3445     CLSIDFromString(V_BSTR(pvaClsid), &classID);
3446     // TODO: properly compute the value of vertical
3447     vertical = true;
3448     return ShowBand(classID, vertical);
3449 }
3450 
get_ReadyState(READYSTATE * plReadyState)3451 HRESULT STDMETHODCALLTYPE CShellBrowser::get_ReadyState(READYSTATE *plReadyState)
3452 {
3453     return E_NOTIMPL;
3454 }
3455 
get_Offline(VARIANT_BOOL * pbOffline)3456 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Offline(VARIANT_BOOL *pbOffline)
3457 {
3458     return E_NOTIMPL;
3459 }
3460 
put_Offline(VARIANT_BOOL bOffline)3461 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Offline(VARIANT_BOOL bOffline)
3462 {
3463     return E_NOTIMPL;
3464 }
3465 
get_Silent(VARIANT_BOOL * pbSilent)3466 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Silent(VARIANT_BOOL *pbSilent)
3467 {
3468     return E_NOTIMPL;
3469 }
3470 
put_Silent(VARIANT_BOOL bSilent)3471 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Silent(VARIANT_BOOL bSilent)
3472 {
3473     return E_NOTIMPL;
3474 }
3475 
get_RegisterAsBrowser(VARIANT_BOOL * pbRegister)3476 HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsBrowser(VARIANT_BOOL *pbRegister)
3477 {
3478     return E_NOTIMPL;
3479 }
3480 
put_RegisterAsBrowser(VARIANT_BOOL bRegister)3481 HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsBrowser(VARIANT_BOOL bRegister)
3482 {
3483     return E_NOTIMPL;
3484 }
3485 
get_RegisterAsDropTarget(VARIANT_BOOL * pbRegister)3486 HRESULT STDMETHODCALLTYPE CShellBrowser::get_RegisterAsDropTarget(VARIANT_BOOL *pbRegister)
3487 {
3488     return E_NOTIMPL;
3489 }
3490 
put_RegisterAsDropTarget(VARIANT_BOOL bRegister)3491 HRESULT STDMETHODCALLTYPE CShellBrowser::put_RegisterAsDropTarget(VARIANT_BOOL bRegister)
3492 {
3493     return E_NOTIMPL;
3494 }
3495 
get_TheaterMode(VARIANT_BOOL * pbRegister)3496 HRESULT STDMETHODCALLTYPE CShellBrowser::get_TheaterMode(VARIANT_BOOL *pbRegister)
3497 {
3498     return E_NOTIMPL;
3499 }
3500 
put_TheaterMode(VARIANT_BOOL bRegister)3501 HRESULT STDMETHODCALLTYPE CShellBrowser::put_TheaterMode(VARIANT_BOOL bRegister)
3502 {
3503     return E_NOTIMPL;
3504 }
3505 
get_AddressBar(VARIANT_BOOL * Value)3506 HRESULT STDMETHODCALLTYPE CShellBrowser::get_AddressBar(VARIANT_BOOL *Value)
3507 {
3508     return E_NOTIMPL;
3509 }
3510 
put_AddressBar(VARIANT_BOOL Value)3511 HRESULT STDMETHODCALLTYPE CShellBrowser::put_AddressBar(VARIANT_BOOL Value)
3512 {
3513     return E_NOTIMPL;
3514 }
3515 
get_Resizable(VARIANT_BOOL * Value)3516 HRESULT STDMETHODCALLTYPE CShellBrowser::get_Resizable(VARIANT_BOOL *Value)
3517 {
3518     return E_NOTIMPL;
3519 }
3520 
put_Resizable(VARIANT_BOOL Value)3521 HRESULT STDMETHODCALLTYPE CShellBrowser::put_Resizable(VARIANT_BOOL Value)
3522 {
3523     return E_NOTIMPL;
3524 }
3525 
FindWindowByIndex(DWORD dwID,IUnknown ** ppunk)3526 HRESULT STDMETHODCALLTYPE CShellBrowser::FindWindowByIndex(DWORD dwID, IUnknown **ppunk)
3527 {
3528     return E_NOTIMPL;
3529 }
3530 
GetWindowData(IStream * pStream,LPWINDOWDATA pWinData)3531 HRESULT STDMETHODCALLTYPE CShellBrowser::GetWindowData(IStream *pStream, LPWINDOWDATA pWinData)
3532 {
3533     if (pWinData == NULL)
3534         return E_POINTER;
3535 
3536     pWinData->dwWindowID = -1;
3537     pWinData->uiCP = 0;
3538     pWinData->pidl = ILClone(fCurrentDirectoryPIDL);
3539     pWinData->lpszUrl = NULL;
3540     pWinData->lpszUrlLocation = NULL;
3541     pWinData->lpszTitle = NULL;
3542     return S_OK;
3543 }
3544 
LoadHistoryPosition(LPWSTR pszUrlLocation,DWORD dwPosition)3545 HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistoryPosition(LPWSTR pszUrlLocation, DWORD dwPosition)
3546 {
3547     return E_NOTIMPL;
3548 }
3549 
GetClassID(CLSID * pClassID)3550 HRESULT STDMETHODCALLTYPE CShellBrowser::GetClassID(CLSID *pClassID)
3551 {
3552     return E_NOTIMPL;
3553 }
3554 
LoadHistory(IStream * pStream,IBindCtx * pbc)3555 HRESULT STDMETHODCALLTYPE CShellBrowser::LoadHistory(IStream *pStream, IBindCtx *pbc)
3556 {
3557     CComPtr<IPersistHistory>                viewPersistHistory;
3558     CComPtr<IOleObject>                     viewHistoryObject;
3559     persistState                            oldState;
3560     ULONG                                   numRead;
3561     LPITEMIDLIST                            pidl;
3562     HRESULT                                 hResult;
3563 
3564     hResult = pStream->Read(&oldState, sizeof(oldState), &numRead);
3565     if (FAILED_UNEXPECTEDLY(hResult))
3566         return hResult;
3567     if (numRead != sizeof(oldState) || oldState.dwSize != sizeof(oldState))
3568         return E_FAIL;
3569     if (oldState.browseType != 2)
3570         return E_FAIL;
3571     pidl = static_cast<LPITEMIDLIST>(CoTaskMemAlloc(oldState.pidlSize));
3572     if (pidl == NULL)
3573         return E_OUTOFMEMORY;
3574     hResult = pStream->Read(pidl, oldState.pidlSize, &numRead);
3575     if (FAILED_UNEXPECTEDLY(hResult))
3576     {
3577         ILFree(pidl);
3578         return hResult;
3579     }
3580     if (numRead != oldState.pidlSize)
3581     {
3582         ILFree(pidl);
3583         return E_FAIL;
3584     }
3585     hResult = CoCreateInstance(oldState.persistClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER,
3586         IID_PPV_ARG(IOleObject, &viewHistoryObject));
3587     fHistoryObject = viewHistoryObject;
3588     fHistoryStream = pStream;
3589     fHistoryBindContext = pbc;
3590     hResult = BrowseToPIDL(pidl, BTP_DONT_UPDATE_HISTORY);
3591     fHistoryObject = NULL;
3592     fHistoryStream = NULL;
3593     fHistoryBindContext = NULL;
3594     ILFree(pidl);
3595     if (FAILED_UNEXPECTEDLY(hResult))
3596         return hResult;
3597     return S_OK;
3598 }
3599 
SaveHistory(IStream * pStream)3600 HRESULT STDMETHODCALLTYPE CShellBrowser::SaveHistory(IStream *pStream)
3601 {
3602     CComPtr<IPersistHistory>                viewPersistHistory;
3603     persistState                            newState;
3604     HRESULT                                 hResult;
3605 
3606     hResult = fCurrentShellView->GetItemObject(
3607         SVGIO_BACKGROUND, IID_PPV_ARG(IPersistHistory, &viewPersistHistory));
3608     memset(&newState, 0, sizeof(newState));
3609     newState.dwSize = sizeof(newState);
3610     newState.browseType = 2;
3611     newState.browserIndex = GetBrowserIndex();
3612     if (viewPersistHistory.p != NULL)
3613     {
3614         hResult = viewPersistHistory->GetClassID(&newState.persistClass);
3615         if (FAILED_UNEXPECTEDLY(hResult))
3616             return hResult;
3617     }
3618     newState.pidlSize = ILGetSize(fCurrentDirectoryPIDL);
3619     hResult = pStream->Write(&newState, sizeof(newState), NULL);
3620     if (FAILED_UNEXPECTEDLY(hResult))
3621         return hResult;
3622     hResult = pStream->Write(fCurrentDirectoryPIDL, newState.pidlSize, NULL);
3623     if (FAILED_UNEXPECTEDLY(hResult))
3624         return hResult;
3625     if (viewPersistHistory.p != NULL)
3626     {
3627         hResult = viewPersistHistory->SaveHistory(pStream);
3628         if (FAILED_UNEXPECTEDLY(hResult))
3629             return hResult;
3630     }
3631     return S_OK;
3632 }
3633 
SetPositionCookie(DWORD dwPositioncookie)3634 HRESULT STDMETHODCALLTYPE CShellBrowser::SetPositionCookie(DWORD dwPositioncookie)
3635 {
3636     return E_NOTIMPL;
3637 }
3638 
GetPositionCookie(DWORD * pdwPositioncookie)3639 HRESULT STDMETHODCALLTYPE CShellBrowser::GetPositionCookie(DWORD *pdwPositioncookie)
3640 {
3641     return E_NOTIMPL;
3642 }
3643 
OnCreate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3644 LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3645 {
3646     OnCreate(reinterpret_cast<LPCREATESTRUCT> (lParam));
3647     return 0;
3648 }
3649 
OnDestroy(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3650 LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3651 {
3652     HRESULT hr;
3653     SaveViewState();
3654 
3655     /* The current thread is about to go down so render any IDataObject that may be left in the clipboard */
3656     OleFlushClipboard();
3657 
3658     // TODO: rip down everything
3659     {
3660         m_Destroyed = true; // Ignore browse requests from Explorer band TreeView during destruction
3661         fToolbarProxy.Destroy();
3662         fCurrentShellView->DestroyViewWindow();
3663         fCurrentShellView->UIActivate(SVUIA_DEACTIVATE);
3664 
3665         for (int i = 0; i < 3; i++)
3666         {
3667             CComPtr<IDockingWindow> pdw;
3668             CComPtr<IDeskBar> bar;
3669             CComPtr<IUnknown> pBarSite;
3670             CComPtr<IDeskBarClient> pClient;
3671 
3672             if (fClientBars[i].clientBar == NULL)
3673                 continue;
3674 
3675             hr = fClientBars[i].clientBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &pdw));
3676             if (FAILED_UNEXPECTEDLY(hr))
3677                 continue;
3678 
3679             /* We should destroy our basebarsite too */
3680             hr = pdw->QueryInterface(IID_PPV_ARG(IDeskBar, &bar));
3681             if (SUCCEEDED(hr))
3682             {
3683                 hr = bar->GetClient(&pBarSite);
3684                 if (SUCCEEDED(hr) && pBarSite)
3685                 {
3686                     hr = pBarSite->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pClient));
3687                     if (SUCCEEDED(hr))
3688                         pClient->SetDeskBarSite(NULL);
3689                 }
3690             }
3691             pdw->CloseDW(0);
3692 
3693             pClient = NULL;
3694             pBarSite = NULL;
3695             pdw = NULL;
3696             bar = NULL;
3697             ReleaseCComPtrExpectZero(fClientBars[i].clientBar);
3698         }
3699         ReleaseCComPtrExpectZero(fCurrentShellView);
3700         ReleaseCComPtrExpectZero(fTravelLog);
3701 
3702         fCurrentShellFolder.Release();
3703         ILFree(fCurrentDirectoryPIDL);
3704         ::DestroyWindow(fStatusBar);
3705         DestroyMenu(fCurrentMenuBar);
3706     }
3707     PostQuitMessage(0);
3708     return 0;
3709 }
3710 
OnSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3711 LRESULT CShellBrowser::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3712 {
3713     CComPtr<IDockingWindow>                 dockingWindow;
3714     RECT                                    availableBounds;
3715     static const INT                        excludeItems[] = {1, 1, 1, IDC_STATUSBAR, 0, 0};
3716     HRESULT                                 hResult;
3717 
3718     if (wParam != SIZE_MINIMIZED)
3719     {
3720         GetEffectiveClientRect(m_hWnd, &availableBounds, excludeItems);
3721         for (INT x = 0; x < 3; x++)
3722         {
3723             if (fClientBars[x].clientBar != NULL)
3724             {
3725                 hResult = fClientBars[x].clientBar->QueryInterface(
3726                     IID_PPV_ARG(IDockingWindow, &dockingWindow));
3727                 if (SUCCEEDED(hResult) && dockingWindow != NULL)
3728                 {
3729                     hResult = dockingWindow->ResizeBorderDW(
3730                         &availableBounds, static_cast<IDropTarget *>(this), TRUE);
3731                     break;
3732                 }
3733             }
3734         }
3735         RepositionBars();
3736     }
3737     return 1;
3738 }
3739 
OnInitMenuPopup(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3740 LRESULT CShellBrowser::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3741 {
3742     HMENU  theMenu;
3743     LPARAM menuIndex = lParam;
3744 
3745     theMenu = reinterpret_cast<HMENU>(wParam);
3746 
3747     if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_FILE))
3748     {
3749         menuIndex = 0;
3750     }
3751     else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_EDIT))
3752     {
3753         menuIndex = 1;
3754     }
3755     else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_VIEW))
3756     {
3757         UpdateViewMenu(theMenu);
3758         menuIndex = 2;
3759     }
3760     else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_FAVORITES))
3761     {
3762         menuIndex = 3;
3763     }
3764     else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_TOOLS))
3765     {
3766         // FIXME: Remove once implemented
3767         SHEnableMenuItem(theMenu, IDM_TOOLS_MAPNETWORKDRIVE, FALSE);
3768         SHEnableMenuItem(theMenu, IDM_TOOLS_SYNCHRONIZE, FALSE);
3769         menuIndex = 4;
3770     }
3771     else if (theMenu == SHGetMenuFromID(fCurrentMenuBar, FCIDM_MENU_HELP))
3772     {
3773         menuIndex = 5;
3774     }
3775 
3776     LRESULT ret = RelayMsgToShellView(uMsg, wParam, menuIndex, bHandled);
3777 
3778     return ret;
3779 }
3780 
OnSetFocus(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3781 LRESULT CShellBrowser::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3782 {
3783     ::SetFocus(fCurrentShellViewWindow);
3784     return 0;
3785 }
3786 
RelayMsgToShellView(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3787 LRESULT CShellBrowser::RelayMsgToShellView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3788 {
3789     if (fCurrentShellViewWindow != NULL)
3790         return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
3791     return 0;
3792 }
3793 
OnSettingChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3794 LRESULT CShellBrowser::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3795 {
3796     RefreshCabinetState();
3797     SHPropagateMessage(m_hWnd, uMsg, wParam, lParam, TRUE);
3798     return 0;
3799 }
3800 
OnSysColorChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)3801 LRESULT CShellBrowser::OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
3802 {
3803     SHPropagateMessage(m_hWnd, uMsg, wParam, lParam, TRUE);
3804     return 0;
3805 }
3806 
OnClose(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3807 LRESULT CShellBrowser::OnClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3808 {
3809     return SendMessage(WM_CLOSE);
3810 }
3811 
OnFolderOptions(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3812 LRESULT CShellBrowser::OnFolderOptions(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3813 {
3814     HRESULT hResult = DoFolderOptions();
3815     if (FAILED(hResult))
3816         TRACE("DoFolderOptions failed with hResult=%08lx\n", hResult);
3817     return 0;
3818 }
3819 
OnMapNetworkDrive(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3820 LRESULT CShellBrowser::OnMapNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3821 {
3822 #ifndef __REACTOS__
3823     WNetConnectionDialog(m_hWnd, RESOURCETYPE_DISK);
3824 #endif /* __REACTOS__ */
3825     return 0;
3826 }
3827 
OnDisconnectNetworkDrive(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3828 LRESULT CShellBrowser::OnDisconnectNetworkDrive(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3829 {
3830     WNetDisconnectDialog(m_hWnd, RESOURCETYPE_DISK);
3831     return 0;
3832 }
3833 
OnAboutReactOS(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3834 LRESULT CShellBrowser::OnAboutReactOS(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3835 {
3836     ShellAbout(m_hWnd, _T("ReactOS"), NULL, NULL);
3837     return 0;
3838 }
3839 
OnGoBack(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3840 LRESULT CShellBrowser::OnGoBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3841 {
3842     HRESULT hResult = GoBack();
3843     if (FAILED(hResult))
3844         TRACE("GoBack failed with hResult=%08lx\n", hResult);
3845     return 0;
3846 }
3847 
OnGoForward(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3848 LRESULT CShellBrowser::OnGoForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3849 {
3850     HRESULT hResult = GoForward();
3851     if (FAILED(hResult))
3852         TRACE("GoForward failed with hResult=%08lx\n", hResult);
3853     return 0;
3854 }
3855 
OnGoUpLevel(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3856 LRESULT CShellBrowser::OnGoUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3857 {
3858     HRESULT hResult = NavigateToParent();
3859     if (FAILED(hResult))
3860         TRACE("NavigateToParent failed with hResult=%08lx\n", hResult);
3861     return 0;
3862 }
3863 
OnGoHome(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3864 LRESULT CShellBrowser::OnGoHome(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3865 {
3866     HRESULT hResult = GoHome();
3867     if (FAILED(hResult))
3868         TRACE("GoHome failed with hResult=%08lx\n", hResult);
3869     return 0;
3870 }
3871 
OnBackspace(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3872 LRESULT CShellBrowser::OnBackspace(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3873 {
3874     // FIXME: This does not appear to be what windows does.
3875     HRESULT hResult = NavigateToParent();
3876     if (FAILED(hResult))
3877         TRACE("NavigateToParent failed with hResult=%08lx\n", hResult);
3878     return 0;
3879 }
3880 
3881 static BOOL
CreateShortcut(IN LPCWSTR pszLnkFileName,IN LPCITEMIDLIST pidl,IN LPCWSTR pszDescription OPTIONAL)3882 CreateShortcut(
3883     IN LPCWSTR pszLnkFileName,
3884     IN LPCITEMIDLIST pidl,
3885     IN LPCWSTR pszDescription OPTIONAL)
3886 {
3887     IPersistFile *pPF;
3888     IShellLinkW *pSL;
3889     HRESULT hr = CoInitialize(NULL);
3890     if (FAILED(hr))
3891         return hr;
3892 
3893     hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
3894                           IID_IShellLinkW, (LPVOID*)&pSL);
3895     if (SUCCEEDED(hr))
3896     {
3897         pSL->SetIDList(pidl);
3898 
3899         if (pszDescription)
3900             pSL->SetDescription(pszDescription);
3901 
3902         hr = pSL->QueryInterface(IID_IPersistFile, (LPVOID*)&pPF);
3903         if (SUCCEEDED(hr))
3904         {
3905             hr = pPF->Save(pszLnkFileName, TRUE);
3906             pPF->Release();
3907         }
3908         pSL->Release();
3909     }
3910 
3911     CoUninitialize();
3912 
3913     return SUCCEEDED(hr);
3914 }
3915 
GetFavsLocation(HWND hWnd,LPITEMIDLIST * pPidl)3916 HRESULT GetFavsLocation(HWND hWnd, LPITEMIDLIST *pPidl)
3917 {
3918     HRESULT hr = SHGetSpecialFolderLocation(hWnd, CSIDL_FAVORITES, pPidl);
3919     if (FAILED(hr))
3920         hr = SHGetSpecialFolderLocation(hWnd, CSIDL_COMMON_FAVORITES, pPidl);
3921 
3922     return hr;
3923 }
3924 
OnAddToFavorites(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3925 LRESULT CShellBrowser::OnAddToFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3926 {
3927     LPITEMIDLIST pidlFavs;
3928     HRESULT hr = GetFavsLocation(m_hWnd, &pidlFavs);
3929     if (FAILED_UNEXPECTEDLY(hr))
3930         return 0;
3931 
3932     SHFILEINFOW fileInfo = { NULL };
3933     if (!SHGetFileInfoW((LPCWSTR)fCurrentDirectoryPIDL, 0, &fileInfo, sizeof(fileInfo),
3934                         SHGFI_PIDL | SHGFI_DISPLAYNAME))
3935     {
3936         return 0;
3937     }
3938 
3939     WCHAR szPath[MAX_PATH];
3940     SHGetPathFromIDListW(pidlFavs, szPath);
3941     PathAppendW(szPath, fileInfo.szDisplayName);
3942     PathAddExtensionW(szPath, L".lnk");
3943 
3944     CreateShortcut(szPath, fCurrentDirectoryPIDL, NULL);
3945     return 0;
3946 }
3947 
OnOrganizeFavorites(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3948 LRESULT CShellBrowser::OnOrganizeFavorites(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3949 {
3950     CComPtr<IShellFolder> psfDesktop;
3951     LPITEMIDLIST pidlFavs;
3952     HRESULT hr = GetFavsLocation(m_hWnd, &pidlFavs);
3953     if (FAILED_UNEXPECTEDLY(hr))
3954         return 0;
3955 
3956     hr = SHGetDesktopFolder(&psfDesktop);
3957     if (FAILED_UNEXPECTEDLY(hr))
3958     {
3959         ILFree(pidlFavs);
3960         return 0;
3961     }
3962 
3963     hr = SHInvokeDefaultCommand(m_hWnd, psfDesktop, pidlFavs);
3964     ILFree(pidlFavs);
3965     if (FAILED_UNEXPECTEDLY(hr))
3966         return 0;
3967 
3968     return 0;
3969 }
3970 
OnToggleStatusBarVisible(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3971 LRESULT CShellBrowser::OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3972 {
3973     m_settings.fStatusBarVisible = !m_settings.fStatusBarVisible;
3974     m_settings.Save();
3975     SendMessageW(BWM_SETTINGCHANGE, 0, (LPARAM)&m_settings);
3976     return 0;
3977 }
3978 
OnToggleToolbarLock(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3979 LRESULT CShellBrowser::OnToggleToolbarLock(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3980 {
3981     HRESULT hResult;
3982     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
3983                             CGID_PrivCITCommands, ITID_TOOLBARLOCKED, 0, NULL, NULL);
3984     return 0;
3985 }
3986 
OnToggleToolbarBandVisible(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3987 LRESULT CShellBrowser::OnToggleToolbarBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3988 {
3989     HRESULT hResult;
3990     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
3991                             CGID_PrivCITCommands, ITID_TOOLBARBANDSHOWN, 0, NULL, NULL);
3992     return 0;
3993 }
3994 
OnToggleAddressBandVisible(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)3995 LRESULT CShellBrowser::OnToggleAddressBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
3996 {
3997     HRESULT hResult;
3998     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
3999                             CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
4000     return 0;
4001 }
4002 
OnToggleLinksBandVisible(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4003 LRESULT CShellBrowser::OnToggleLinksBandVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4004 {
4005     HRESULT hResult;
4006     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
4007                             CGID_PrivCITCommands, ITID_LINKSBANDSHOWN, 0, NULL, NULL);
4008     return 0;
4009 }
4010 
OnToggleTextLabels(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4011 LRESULT CShellBrowser::OnToggleTextLabels(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4012 {
4013     HRESULT hResult;
4014     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
4015                             CGID_PrivCITCommands, ITID_TEXTLABELS, 0, NULL, NULL);
4016     return 0;
4017 }
4018 
OnToolbarCustomize(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4019 LRESULT CShellBrowser::OnToolbarCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4020 {
4021     HRESULT hResult;
4022     hResult = IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
4023                             CGID_PrivCITCommands, ITID_CUSTOMIZEENABLED, 0, NULL, NULL);
4024     return 0;
4025 }
4026 
OnRefresh(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4027 LRESULT CShellBrowser::OnRefresh(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4028 {
4029     if (fCurrentShellView)
4030         fCurrentShellView->Refresh();
4031     return 0;
4032 }
4033 
OnGoTravel(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4034 LRESULT CShellBrowser::OnGoTravel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4035 {
4036     return 0;
4037 }
4038 
OnExplorerBar(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)4039 LRESULT CShellBrowser::OnExplorerBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
4040 {
4041     // TODO: HACK ! use the proper mechanism to show the band (i.e. pass the BSTR to basebar)
4042     if (wID >= IDM_EXPLORERBAND_BEGINCUSTOM && wID <= IDM_EXPLORERBAND_ENDCUSTOM)
4043     {
4044         MenuBandInfo *mbi;
4045         mbi = (MenuBandInfo*)DSA_GetItemPtr(menuDsa, (wID - IDM_EXPLORERBAND_BEGINCUSTOM));
4046         if (!mbi)
4047             return 0;
4048         ShowBand(mbi->barGuid, mbi->fVertical);
4049         bHandled = TRUE;
4050         return 1;
4051     }
4052     switch (wID)
4053     {
4054     case IDM_EXPLORERBAR_SEARCH:
4055         ShowBand(CLSID_FileSearchBand, true);
4056         break;
4057     case IDM_EXPLORERBAR_FOLDERS:
4058         ShowBand(CLSID_ExplorerBand, true);
4059         break;
4060     case IDM_EXPLORERBAR_HISTORY:
4061         ShowBand(CLSID_SH_HistBand, true);
4062         break;
4063     case IDM_EXPLORERBAR_FAVORITES:
4064         ShowBand(CLSID_SH_FavBand, true);
4065         break;
4066     default:
4067         WARN("Unknown id %x\n", wID);
4068     }
4069     bHandled = TRUE;
4070     return 1;
4071 }
4072 
RelayCommands(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4073 LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
4074 {
4075     if (HIWORD(wParam) == 0 && LOWORD(wParam) < FCIDM_SHVIEWLAST && fCurrentShellViewWindow != NULL)
4076         return SendMessage(fCurrentShellViewWindow, uMsg, wParam, lParam);
4077     return 0;
4078 }
4079 
OnCabinetStateChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4080 LRESULT CShellBrowser::OnCabinetStateChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
4081 {
4082     RefreshCabinetState();
4083     return 0;
4084 }
4085 
OnSettingsChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4086 LRESULT CShellBrowser::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
4087 {
4088     /* Refresh child windows */
4089     ::SendMessageW(fClientBars[BIInternetToolbar].hwnd, uMsg, wParam, lParam);
4090 
4091     /* Refresh status bar */
4092     if (fStatusBar)
4093     {
4094         ::ShowWindow(fStatusBar, m_settings.fStatusBarVisible ? SW_SHOW : SW_HIDE);
4095         RepositionBars();
4096     }
4097 
4098     return 0;
4099 }
4100 
OnGetSettingsPtr(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4101 LRESULT CShellBrowser::OnGetSettingsPtr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
4102 {
4103     if (!lParam)
4104         return ERROR_INVALID_PARAMETER;
4105 
4106     *(ShellSettings**)lParam = &m_settings;
4107     return NO_ERROR;
4108 }
4109 
4110 // WM_APPCOMMAND
OnAppCommand(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)4111 LRESULT CShellBrowser::OnAppCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
4112 {
4113     UINT uCmd = GET_APPCOMMAND_LPARAM(lParam);
4114     switch (uCmd)
4115     {
4116         case APPCOMMAND_BROWSER_BACKWARD:
4117             GoBack();
4118             break;
4119 
4120         case APPCOMMAND_BROWSER_FORWARD:
4121             GoForward();
4122             break;
4123 
4124         default:
4125             FIXME("uCmd: %u\n", uCmd);
4126             break;
4127     }
4128     return 0;
4129 }
4130 
CShellBrowser_CreateInstance(REFIID riid,void ** ppv)4131 HRESULT CShellBrowser_CreateInstance(REFIID riid, void **ppv)
4132 {
4133     return ShellObjectCreatorInit<CShellBrowser>(riid, ppv);
4134 }
4135 
RefreshCabinetState()4136 void CShellBrowser::RefreshCabinetState()
4137 {
4138     gCabinetState.Load();
4139     UpdateWindowTitle();
4140 }
4141 
UpdateWindowTitle()4142 void CShellBrowser::UpdateWindowTitle()
4143 {
4144     WCHAR title[MAX_PATH];
4145     SHGDNF flags = SHGDN_FORADDRESSBAR;
4146 
4147     if (gCabinetState.fFullPathTitle)
4148         flags |= SHGDN_FORPARSING;
4149 
4150     if (SUCCEEDED(IEGetNameAndFlags(fCurrentDirectoryPIDL, flags, title, _countof(title), NULL)))
4151         SetWindowText(title);
4152 }
4153 
SaveITBarLayout()4154 void CShellBrowser::SaveITBarLayout()
4155 {
4156     if (!gCabinetState.fSaveLocalView || (m_BrowserSvcFlags & (BSF_THEATERMODE | BSF_UISETBYAUTOMATION)))
4157         return;
4158 #if 0 // If CDesktopBrowser aggregates us, skip saving
4159     FOLDERSETTINGS fs;
4160     if (fCurrentShellView && SUCCEEDED(fCurrentShellView->GetCurrentInfo(&fs)) && (fs.fFlags & FWF_DESKTOP))
4161         return;
4162 #endif
4163 
4164     CComPtr<IPersistStreamInit> pPSI;
4165     CComPtr<IStream> pITBarStream;
4166     if (!fClientBars[BIInternetToolbar].clientBar.p)
4167         return;
4168     HRESULT hr = fClientBars[BIInternetToolbar].clientBar->QueryInterface(IID_PPV_ARG(IPersistStreamInit, &pPSI));
4169     if (FAILED(hr))
4170         return;
4171     if (FAILED(hr = CInternetToolbar::GetStream(ITBARSTREAM_EXPLORER, STGM_WRITE, &pITBarStream)))
4172         return;
4173     pPSI->Save(pITBarStream, TRUE);
4174 }
4175