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