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