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