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