4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
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.
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.
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
22 Implements a class that knows how to hold and manage the menu band, brand band,
23 toolbar, and address band for an explorer window
28 /* FIXME, I can't include windowsx because it conflicts with some #defines */
29 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
30 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
32 #define USE_CUSTOM_MENUBAND 1
34 // navigation controls and menubar just send a message to parent window
37 ****Implement BandProxy methods
38 ****Add QueryStatus handler for built-in bands
39 ****Enable/Disable up, search, and folders commands appropriately
40 **Why are explorer toolbar separators a nonstandard width?
41 **Remove "(Empty)" item from Favorites menu. Probably something missing in CMenuCallback::CallbackSM
42 **Chevron menu on menuband doesn't work
43 **Fix CInternetToolbar::QueryBand to be generic
45 ****Fix context menu to strip divider when menu shown for menu band
46 ****Fix context menu to have items checked appropriately
47 ****Implement -1 command id update
48 ****When bands are rearranged, resize the internet toolbar and fix height of brand band
49 ****Right clicking on the browse back and forward toolbar buttons displays the same as pulldown menus
50 Implement show/hide of bands
51 Why is the background color of my toolbars different from explorer?
52 Internet Toolbar command handler should get the target for the command and call Exec on the target.
53 For commands built in to the Internet Toolbar, its Exec handles the command
54 When window width is changed, brand band flashes badly
55 Add all bands with correct ids (system bands now add with correct ids)
57 Implement remaining IExplorerToolbar methods
58 Fix toolbar buttons to enable/disable correctly
59 After toolbar is customized, it may be necessary to patch the widths of separators
61 Check sizes and spacing of toolbars against Explorer
62 Implement resizing of the dock bar
63 Add missing icons for toolbar items
64 Draw History item in forward/back dropdown menus with icon
65 Fix toolbar customize dialog to not include separators as possible selections
66 Implement save/restore of toolbar state
67 Refactor drop down menu code to use a common function since code is so similar
70 extern HRESULT WINAPI
SHBindToFolder(LPCITEMIDLIST path
, IShellFolder
**newFolder
);
71 extern HRESULT
CreateToolsBar(REFIID riid
, void **ppv
);
72 extern HRESULT
CreateBrandBand(REFIID riid
, void **ppv
);
73 extern HRESULT
CreateBandProxy(REFIID riid
, void **ppv
);
74 extern HRESULT
CreateAddressBand(REFIID riid
, void **ppv
);
76 typedef HRESULT(WINAPI
* PMENUBAND_CONSTRUCTOR
)(REFIID riid
, void **ppv
);
77 typedef HRESULT(WINAPI
* PMERGEDFOLDER_CONSTRUCTOR
)(IShellFolder
* userLocal
, IShellFolder
* allUsers
, REFIID riid
, LPVOID
*ppv
);
79 HRESULT
IUnknown_HasFocusIO(IUnknown
* punk
)
81 CComPtr
<IInputObject
> pio
;
83 hr
= punk
->QueryInterface(IID_PPV_ARG(IInputObject
, &pio
));
84 if (FAILED_UNEXPECTEDLY(hr
))
86 return pio
->HasFocusIO();
89 HRESULT
IUnknown_TranslateAcceleratorIO(IUnknown
* punk
, MSG
* pmsg
)
91 CComPtr
<IInputObject
> pio
;
95 hr
= punk
->QueryInterface(IID_PPV_ARG(IInputObject
, &pio
));
96 if (FAILED_UNEXPECTEDLY(hr
))
98 return pio
->TranslateAcceleratorIO(pmsg
);
101 HRESULT
IUnknown_RelayWinEvent(IUnknown
* punk
, HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
103 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
104 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
105 if (FAILED_UNEXPECTEDLY(hResult
))
107 hResult
= menuWinEventHandler
->IsWindowOwner(hWnd
);
108 if (FAILED_UNEXPECTEDLY(hResult
))
111 return menuWinEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
115 HRESULT
IUnknown_ShowDW(IUnknown
* punk
, BOOL fShow
)
117 CComPtr
<IDockingWindow
> dockingWindow
;
118 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
119 if (FAILED_UNEXPECTEDLY(hResult
))
121 hResult
= dockingWindow
->ShowDW(fShow
);
122 if (FAILED_UNEXPECTEDLY(hResult
))
127 HRESULT
IUnknown_CloseDW(IUnknown
* punk
, DWORD dwReserved
)
129 CComPtr
<IDockingWindow
> dockingWindow
;
130 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
131 if (FAILED_UNEXPECTEDLY(hResult
))
133 hResult
= dockingWindow
->CloseDW(dwReserved
);
134 if (FAILED_UNEXPECTEDLY(hResult
))
139 class CInternetToolbar
;
142 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
143 public IDockingWindowSite
,
144 public IInputObjectSite
,
145 public IOleCommandTarget
,
146 public IServiceProvider
152 ITF_NEWBANDALWAYS
= 4,
153 ITF_GRIPPERALWAYS
= 8,
157 CComPtr
<IUnknown
> fContainedBand
; // the band inside us
158 CInternetToolbar
*fToolbar
; // our browser
166 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
167 DESKBANDINFO fDeskBandInfo
;
171 HRESULT
Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
);
172 HRESULT
GetRBBandInfo(REBARBANDINFOW
&bandInfo
);
175 // *** IOleWindow methods ***
176 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
177 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
179 // *** IDockingWindow methods ***
180 virtual HRESULT STDMETHODCALLTYPE
GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
);
181 virtual HRESULT STDMETHODCALLTYPE
RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
182 virtual HRESULT STDMETHODCALLTYPE
SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
184 // *** IInputObjectSite specific methods ***
185 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
187 // *** IOleCommandTarget specific methods ***
188 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
189 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
190 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
191 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
193 // *** IServiceProvider methods ***
194 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
196 BEGIN_COM_MAP(CDockSite
)
197 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
198 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite
, IDockingWindowSite
)
199 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
200 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
201 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
205 CDockSite::CDockSite()
212 fInitialized
= false;
213 memset(&fDeskBandInfo
, 0, sizeof(fDeskBandInfo
));
216 CDockSite::~CDockSite()
220 HRESULT
CDockSite::Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
)
222 TCHAR textBuffer
[40];
223 REBARBANDINFOW bandInfo
;
226 fContainedBand
= containedBand
;
231 hResult
= IUnknown_SetSite(containedBand
, static_cast<IOleWindow
*>(this));
232 if (FAILED_UNEXPECTEDLY(hResult
))
234 hResult
= IUnknown_GetWindow(containedBand
, &fChildWindow
);
235 if (FAILED_UNEXPECTEDLY(hResult
))
238 memset(&bandInfo
, 0, sizeof(bandInfo
));
239 bandInfo
.cbSize
= sizeof(bandInfo
);
240 bandInfo
.lpText
= textBuffer
;
241 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
242 hResult
= GetRBBandInfo(bandInfo
);
244 SendMessage(fRebarWindow
, RB_GETBANDCOUNT
, 0, 0);
245 SendMessage(fRebarWindow
, RB_INSERTBANDW
, -1, (LPARAM
)&bandInfo
);
250 HRESULT
CDockSite::GetRBBandInfo(REBARBANDINFOW
&bandInfo
)
252 CComPtr
<IDeskBand
> deskBand
;
255 hResult
= fContainedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
256 if (FAILED_UNEXPECTEDLY(hResult
))
259 fDeskBandInfo
.dwMask
= DBIM_BKCOLOR
| DBIM_MODEFLAGS
| DBIM_TITLE
| DBIM_ACTUAL
|
260 DBIM_INTEGRAL
| DBIM_MAXSIZE
| DBIM_MINSIZE
;
261 hResult
= deskBand
->GetBandInfo(fBandID
, 0, &fDeskBandInfo
);
262 // result of call is ignored
264 bandInfo
.fMask
= RBBIM_LPARAM
| RBBIM_IDEALSIZE
| RBBIM_ID
| RBBIM_CHILDSIZE
| RBBIM_CHILD
|
265 RBBIM_TEXT
| RBBIM_STYLE
;
267 bandInfo
.fStyle
= RBBS_FIXEDBMP
;
268 if (fDeskBandInfo
.dwModeFlags
& DBIMF_VARIABLEHEIGHT
)
269 bandInfo
.fStyle
|= RBBS_VARIABLEHEIGHT
;
270 if (fDeskBandInfo
.dwModeFlags
& DBIMF_USECHEVRON
)
271 bandInfo
.fStyle
|= RBBS_USECHEVRON
;
272 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BREAK
)
273 bandInfo
.fStyle
|= RBBS_BREAK
;
274 if (fDeskBandInfo
.dwModeFlags
& DBIMF_TOPALIGN
)
275 bandInfo
.fStyle
|= RBBS_TOPALIGN
;
276 if (fFlags
& ITF_NOGRIPPER
|| fToolbar
->fLocked
)
277 bandInfo
.fStyle
|= RBBS_NOGRIPPER
;
278 if (fFlags
& ITF_NOTITLE
)
279 bandInfo
.fStyle
|= RBBS_HIDETITLE
;
280 if (fFlags
& ITF_GRIPPERALWAYS
&& !fToolbar
->fLocked
)
281 bandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
282 if (fFlags
& ITF_FIXEDSIZE
)
283 bandInfo
.fStyle
|= RBBS_FIXEDSIZE
;
285 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BKCOLOR
)
287 bandInfo
.fMask
|= RBBIM_COLORS
;
288 bandInfo
.clrFore
= CLR_DEFAULT
;
289 bandInfo
.clrBack
= fDeskBandInfo
.crBkgnd
;
291 wcsncpy(bandInfo
.lpText
, fDeskBandInfo
.wszTitle
, bandInfo
.cch
);
292 bandInfo
.hwndChild
= fChildWindow
;
293 bandInfo
.cxMinChild
= fDeskBandInfo
.ptMinSize
.x
;
294 bandInfo
.cyMinChild
= fDeskBandInfo
.ptMinSize
.y
;
295 bandInfo
.wID
= fBandID
;
296 bandInfo
.cyChild
= fDeskBandInfo
.ptActual
.y
;
297 bandInfo
.cyMaxChild
= fDeskBandInfo
.ptMaxSize
.y
;
298 bandInfo
.cyIntegral
= fDeskBandInfo
.ptIntegral
.y
;
299 bandInfo
.cxIdeal
= fDeskBandInfo
.ptActual
.x
;
300 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(this);
304 HRESULT STDMETHODCALLTYPE
CDockSite::GetWindow(HWND
*lphwnd
)
308 *lphwnd
= fRebarWindow
;
312 HRESULT STDMETHODCALLTYPE
CDockSite::ContextSensitiveHelp(BOOL fEnterMode
)
317 HRESULT STDMETHODCALLTYPE
CDockSite::GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
)
322 HRESULT STDMETHODCALLTYPE
CDockSite::RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
327 HRESULT STDMETHODCALLTYPE
CDockSite::SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
332 HRESULT STDMETHODCALLTYPE
CDockSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
337 HRESULT STDMETHODCALLTYPE
CDockSite::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
338 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
343 HRESULT STDMETHODCALLTYPE
CDockSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
,
344 VARIANT
*pvaIn
, VARIANT
*pvaOut
)
346 TCHAR textBuffer
[40];
347 REBARBANDINFOW bandInfo
;
351 if (IsEqualIID(*pguidCmdGroup
, CGID_DeskBand
))
355 case DBID_BANDINFOCHANGED
:
356 if (fInitialized
== false)
358 if (V_VT(pvaIn
) != VT_I4
)
360 if (V_I4(pvaIn
) != fBandID
)
362 // deskband information changed
363 // call GetBandInfo and refresh information in rebar
364 memset(&bandInfo
, 0, sizeof(bandInfo
));
365 bandInfo
.cbSize
= sizeof(bandInfo
);
366 bandInfo
.lpText
= textBuffer
;
367 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
368 hResult
= GetRBBandInfo(bandInfo
);
369 if (FAILED_UNEXPECTEDLY(hResult
))
371 index
= (int)SendMessage(fRebarWindow
, RB_IDTOINDEX
, fBandID
, 0);
372 SendMessage(fRebarWindow
, RB_SETBANDINFOW
, index
, (LPARAM
)&bandInfo
);
379 HRESULT STDMETHODCALLTYPE
CDockSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
381 if (IsEqualIID(guidService
, SID_SMenuBandParent
))
382 return this->QueryInterface(riid
, ppvObject
);
384 return fToolbar
->QueryService(guidService
, riid
, ppvObject
);
387 CMenuCallback::CMenuCallback()
391 CMenuCallback::~CMenuCallback()
395 HRESULT STDMETHODCALLTYPE
CMenuCallback::GetObject(LPSMDATA psmd
, REFIID riid
, void **ppvObject
)
397 CComPtr
<IShellMenu
> parentMenu
;
398 CComPtr
<IShellMenu
> newMenu
;
399 CComPtr
<IShellFolder
> favoritesFolder
;
400 LPITEMIDLIST favoritesPIDL
;
401 CComPtr
<IShellFolder
> commonFavsFolder
;
402 LPITEMIDLIST commonFavsPIDL
;
403 CComPtr
<IShellFolder
> mergedFolder
;
406 HMENU favoritesHMenu
;
410 static const TCHAR szFavoritesKey
[] =
411 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
413 if (!IsEqualIID(riid
, IID_IShellMenu
))
415 if (psmd
->uId
!= FCIDM_MENU_FAVORITES
)
418 if (fFavoritesMenu
.p
== NULL
)
420 // create favorites menu
421 hResult
= psmd
->punk
->QueryInterface(IID_PPV_ARG(IShellMenu
, &parentMenu
));
422 if (FAILED_UNEXPECTEDLY(hResult
))
424 hResult
= parentMenu
->GetMenu(&parentHMenu
, &ownerWindow
, NULL
);
425 if (FAILED_UNEXPECTEDLY(hResult
))
427 favoritesHMenu
= GetSubMenu(parentHMenu
, 3);
428 if (favoritesHMenu
== NULL
)
430 #if USE_CUSTOM_MENUBAND
431 HMODULE hrs
= LoadLibrary(L
"rshell.dll");
433 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
436 hResult
= func(IID_PPV_ARG(IShellMenu
, &newMenu
));
440 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
441 IID_PPV_ARG(IShellMenu
, &newMenu
));
444 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
445 IID_PPV_ARG(IShellMenu
, &newMenu
));
447 if (FAILED_UNEXPECTEDLY(hResult
))
449 hResult
= newMenu
->Initialize(this, FCIDM_MENU_FAVORITES
, -1, SMINIT_VERTICAL
| SMINIT_CACHED
);
450 if (FAILED_UNEXPECTEDLY(hResult
))
452 hResult
= newMenu
->SetMenu(favoritesHMenu
, ownerWindow
, SMSET_TOP
| SMSET_DONTOWN
);
453 if (FAILED_UNEXPECTEDLY(hResult
))
455 hResult
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &favoritesPIDL
);
456 if (FAILED_UNEXPECTEDLY(hResult
))
458 hResult
= SHBindToFolder(favoritesPIDL
, &favoritesFolder
);
459 if (FAILED_UNEXPECTEDLY(hResult
))
461 RegCreateKeyEx(HKEY_CURRENT_USER
, szFavoritesKey
,
462 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &orderRegKey
, &disposition
);
463 #if 1 /*USE_MERGED_FAVORITES*/
464 hResult
= SHGetSpecialFolderLocation(NULL
, CSIDL_COMMON_FAVORITES
, &commonFavsPIDL
);
465 if (FAILED_UNEXPECTEDLY(hResult
))
467 hResult
= SHBindToFolder(commonFavsPIDL
, &commonFavsFolder
);
468 if (FAILED_UNEXPECTEDLY(hResult
))
470 ILFree(commonFavsPIDL
);
472 PMERGEDFOLDER_CONSTRUCTOR mfconstruct
= (PMERGEDFOLDER_CONSTRUCTOR
) GetProcAddress(hrs
, "CMergedFolder_Constructor");
475 hResult
= mfconstruct(favoritesFolder
, commonFavsFolder
, IID_PPV_ARG(IShellFolder
, &mergedFolder
));
479 mergedFolder
= favoritesFolder
;
482 mergedFolder
= favoritesFolder
;
484 hResult
= newMenu
->SetShellFolder(mergedFolder
, favoritesPIDL
, orderRegKey
, SMSET_BOTTOM
| SMINIT_CACHED
| SMINV_ID
);
485 ILFree(favoritesPIDL
);
486 if (SUCCEEDED(hResult
))
487 fFavoritesMenu
.Attach(newMenu
.Detach());
489 if (fFavoritesMenu
.p
== NULL
)
491 return fFavoritesMenu
->QueryInterface(riid
, ppvObject
);
494 HRESULT STDMETHODCALLTYPE
CMenuCallback::CallbackSM(LPSMDATA psmd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
506 SMINFO
*infoPtr
= reinterpret_cast<SMINFO
*>(lParam
);
507 if ((infoPtr
->dwMask
& SMIM_FLAGS
) != 0)
509 if (psmd
->uId
== FCIDM_MENU_FAVORITES
)
511 infoPtr
->dwFlags
|= SMIF_DROPCASCADE
;
515 infoPtr
->dwFlags
|= SMIF_TRACKPOPUP
;
518 if ((infoPtr
->dwMask
& SMIM_ICON
) != 0)
525 return GetObject(psmd
, *reinterpret_cast<IID
*>(wParam
), reinterpret_cast<void **>(lParam
));
526 case SMC_GETSFOBJECT
:
530 case SMC_SFSELECTITEM
:
543 case SMC_DEFAULTICON
:
547 case SMC_CHEVRONEXPAND
:
549 case SMC_DISPLAYCHEVRONTIP
:
551 case SMC_SETSFOBJECT
:
553 case SMC_SHCHANGENOTIFY
:
555 case SMC_CHEVRONGETTIP
:
557 case SMC_SFDDRESTRICTED
:
569 CInternetToolbar::CInternetToolbar()
573 fMenuBandWindow
= NULL
;
574 fNavigationWindow
= NULL
;
575 fMenuCallback
= new CComObject
<CMenuCallback
>();
576 fToolbarWindow
= NULL
;
579 fMenuCallback
->AddRef();
582 CInternetToolbar::~CInternetToolbar()
584 fMenuCallback
.Release();
587 void CInternetToolbar::AddDockItem(IUnknown
*newItem
, int bandID
, int flags
)
589 CComPtr
<CDockSite
> newSite
;
591 newSite
= new CComObject
<CDockSite
>;
592 newSite
->Initialize(newItem
, this, fMainReBar
, bandID
, flags
);
595 HRESULT
CInternetToolbar::ReserveBorderSpace(LONG maxHeight
)
597 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
598 RECT availableBorderSpace
;
600 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
601 if (FAILED_UNEXPECTEDLY(hResult
))
603 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDockingWindow
*>(this), &availableBorderSpace
);
604 if (FAILED_UNEXPECTEDLY(hResult
))
607 if (availableBorderSpace
.top
> maxHeight
)
609 availableBorderSpace
.top
= maxHeight
;
612 return ResizeBorderDW(&availableBorderSpace
, fSite
, FALSE
);
615 HRESULT
CInternetToolbar::CreateMenuBar(IShellMenu
**pMenuBar
)
617 CComPtr
<IShellMenu
> menubar
;
618 CComPtr
<IShellMenuCallback
> callback
;
629 #if USE_CUSTOM_MENUBAND
630 HMODULE hrs
= GetModuleHandleW(L
"rshell.dll");
632 if (!hrs
) hrs
= LoadLibraryW(L
"rshell.dll");
636 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
639 hResult
= func(IID_PPV_ARG(IShellMenu
, &menubar
));
646 if (FAILED_UNEXPECTEDLY(hResult
))
648 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
649 IID_PPV_ARG(IShellMenu
, &menubar
));
650 if (FAILED_UNEXPECTEDLY(hResult
))
654 hResult
= fMenuCallback
->QueryInterface(IID_PPV_ARG(IShellMenuCallback
, &callback
));
655 if (FAILED_UNEXPECTEDLY(hResult
))
658 hResult
= menubar
->Initialize(callback
, -1, ANCESTORDEFAULT
, SMINIT_HORIZONTAL
| SMINIT_TOPLEVEL
);
659 if (FAILED_UNEXPECTEDLY(hResult
))
664 hResult
= IUnknown_Exec(fSite
, CGID_Explorer
, 0x35, 0, NULL
, &menuOut
);
665 if (FAILED_UNEXPECTEDLY(hResult
))
668 if (V_VT(&menuOut
) != VT_INT_PTR
|| V_INTREF(&menuOut
) == NULL
)
671 hResult
= IUnknown_GetWindow(fSite
, &ownerWindow
);
672 if (FAILED_UNEXPECTEDLY(hResult
))
675 hResult
= menubar
->SetMenu((HMENU
) V_INTREF(&menuOut
), ownerWindow
, SMSET_DONTOWN
);
676 if (FAILED_UNEXPECTEDLY(hResult
))
680 hResult
= IUnknown_Exec(menubar
, CGID_MenuBand
, 3, 1, NULL
, NULL
);
681 if (FAILED_UNEXPECTEDLY(hResult
))
684 *pMenuBar
= menubar
.Detach();
689 HRESULT
CInternetToolbar::CreateBrandBand(IUnknown
**logoBar
)
692 return ::CreateBrandBand(IID_PPV_ARG(IUnknown
, logoBar
));
694 return CoCreateInstance(CLSID_BrandBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, logoBar
));
698 HRESULT
CInternetToolbar::CreateToolsBar(IUnknown
**toolsBar
)
700 return ::CreateToolsBar(IID_PPV_ARG(IUnknown
, toolsBar
));
703 HRESULT
CInternetToolbar::CreateAddressBand(IUnknown
**toolsBar
)
706 return ::CreateAddressBand(IID_PPV_ARG(IUnknown
, toolsBar
));
708 return CoCreateInstance(CLSID_SH_AddressBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, toolsBar
));
712 HRESULT
CInternetToolbar::LockUnlockToolbars(bool locked
)
714 REBARBANDINFOW rebarBandInfo
;
719 if (locked
!= fLocked
)
722 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
723 rebarBandInfo
.fMask
= RBBIM_STYLE
| RBBIM_LPARAM
;
724 bandCount
= (int)SendMessage(fMainReBar
, RB_GETBANDCOUNT
, 0, 0);
725 for (INT x
= 0; x
< bandCount
; x
++)
727 SendMessage(fMainReBar
, RB_GETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
728 dockSite
= reinterpret_cast<CDockSite
*>(rebarBandInfo
.lParam
);
729 if (dockSite
!= NULL
)
731 rebarBandInfo
.fStyle
&= ~(RBBS_NOGRIPPER
| RBBS_GRIPPERALWAYS
);
732 if (dockSite
->fFlags
& CDockSite::ITF_NOGRIPPER
|| fLocked
)
733 rebarBandInfo
.fStyle
|= RBBS_NOGRIPPER
;
734 if (dockSite
->fFlags
& CDockSite::ITF_GRIPPERALWAYS
&& !fLocked
)
735 rebarBandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
736 SendMessage(fMainReBar
, RB_SETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
739 hResult
= ReserveBorderSpace();
741 // TODO: refresh view menu?
746 HRESULT
CInternetToolbar::CommandStateChanged(bool newValue
, int commandID
)
754 // loop through buttons
755 //for buttons in CLSID_CommonButtons
756 // if up, QueryStatus for up state and update it
758 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
762 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_FORWARD
, newValue
? TBSTATE_ENABLED
: 0);
766 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_BACK
, newValue
? TBSTATE_ENABLED
: 0);
772 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
774 CComPtr
<IServiceProvider
> serviceProvider
;
777 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
778 if (FAILED_UNEXPECTEDLY(hResult
))
780 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
781 if (FAILED_UNEXPECTEDLY(hResult
))
783 hResult
= CreateBandProxy(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
784 if (FAILED_UNEXPECTEDLY(hResult
))
786 hResult
= fBandProxy
->SetSite(fSite
);
787 if (FAILED_UNEXPECTEDLY(hResult
))
793 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
798 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
800 HRESULT hr
= S_FALSE
;
803 hr
= IUnknown_HasFocusIO(fMenuBar
);
808 hr
= IUnknown_HasFocusIO(fControlsBar
);
813 hr
= IUnknown_HasFocusIO(fNavigationBar
);
820 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
822 HRESULT hr
= S_FALSE
;
825 hr
= IUnknown_TranslateAcceleratorIO(fMenuBar
, lpMsg
);
830 hr
= IUnknown_TranslateAcceleratorIO(fControlsBar
, lpMsg
);
835 hr
= IUnknown_TranslateAcceleratorIO(fNavigationBar
, lpMsg
);
842 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
850 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
855 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
862 hResult
= ReserveBorderSpace();
863 if (FAILED_UNEXPECTEDLY(hResult
))
869 hResult
= IUnknown_ShowDW(fMenuBar
, fShow
);
870 if (FAILED_UNEXPECTEDLY(hResult
))
876 hResult
= IUnknown_ShowDW(fControlsBar
, fShow
);
877 if (FAILED_UNEXPECTEDLY(hResult
))
882 hResult
= IUnknown_ShowDW(fNavigationBar
, fShow
);
883 if (FAILED_UNEXPECTEDLY(hResult
))
888 hResult
= IUnknown_ShowDW(fLogoBar
, fShow
);
889 if (FAILED_UNEXPECTEDLY(hResult
))
896 void ReleaseCComPtrExpectZero(CComPtr
<T
>& cptr
, BOOL forceRelease
= FALSE
)
900 int nrc
= cptr
->Release();
903 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc
);
908 nrc
= cptr
->Release();
916 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
922 hResult
= IUnknown_CloseDW(fMenuBar
, dwReserved
);
923 if (FAILED_UNEXPECTEDLY(hResult
))
925 ReleaseCComPtrExpectZero(fMenuBar
);
929 hResult
= IUnknown_CloseDW(fControlsBar
, dwReserved
);
930 if (FAILED_UNEXPECTEDLY(hResult
))
932 ReleaseCComPtrExpectZero(fControlsBar
);
936 hResult
= IUnknown_CloseDW(fNavigationBar
, dwReserved
);
937 if (FAILED_UNEXPECTEDLY(hResult
))
939 ReleaseCComPtrExpectZero(fNavigationBar
);
943 hResult
= IUnknown_CloseDW(fLogoBar
, dwReserved
);
944 if (FAILED_UNEXPECTEDLY(hResult
))
946 ReleaseCComPtrExpectZero(fLogoBar
);
951 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
952 IUnknown
*punkToolbarSite
, BOOL fReserved
)
954 RECT neededBorderSpace
;
955 RECT availableBorderSpace
= *prcBorder
;
957 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
959 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
960 // Let's make sure we fetch the actual size properly.
961 GetWindowRect(fMainReBar
, &availableBorderSpace
);
962 neededBorderSpace
.left
= 0;
963 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
965 neededBorderSpace
.top
+= 3;
966 neededBorderSpace
.right
= 0;
967 neededBorderSpace
.bottom
= 0;
969 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
971 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
972 if (FAILED_UNEXPECTEDLY(hResult
))
975 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
976 if (FAILED_UNEXPECTEDLY(hResult
))
979 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
980 if (FAILED_UNEXPECTEDLY(hResult
))
986 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
988 if (pClassID
== NULL
)
990 *pClassID
= CLSID_InternetToolbar
;
994 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
999 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
1004 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
1009 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1014 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
1016 CComPtr
<IShellMenu
> menuBar
;
1017 CComPtr
<IUnknown
> logoBar
;
1018 CComPtr
<IUnknown
> toolsBar
;
1019 CComPtr
<IUnknown
> navigationBar
;
1022 /* Create and attach the menubar to the rebar */
1023 hResult
= CreateMenuBar(&menuBar
);
1024 if (FAILED_UNEXPECTEDLY(hResult
))
1026 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1028 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
1029 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1031 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1032 // and it will put them in their own row, sized to take up the whole row.
1034 /* Create and attach the brand/logo to the rebar */
1035 hResult
= CreateBrandBand(&logoBar
);
1036 if (FAILED_UNEXPECTEDLY(hResult
))
1038 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1039 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1042 /* Create and attach the standard toolbar to the rebar */
1043 hResult
= CreateToolsBar(&toolsBar
);
1044 if (FAILED_UNEXPECTEDLY(hResult
))
1046 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1047 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1048 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1049 if (FAILED_UNEXPECTEDLY(hResult
))
1052 /* Create and attach the address/navigation toolbar to the rebar */
1053 hResult
= CreateAddressBand(&navigationBar
);
1054 if (FAILED_UNEXPECTEDLY(hResult
))
1056 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1057 fNavigationBar
.Attach(navigationBar
.Detach());
1058 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1063 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1064 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1066 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1070 switch (prgCmds
->cmdID
)
1072 case ITID_TEXTLABELS
: // Text Labels state
1073 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1075 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1076 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1078 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1079 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1081 case ITID_LINKSBANDSHOWN
: // links bar visibility
1084 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1087 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1090 case ITID_CUSTOMIZEENABLED
: // customize enabled
1091 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1093 case ITID_TOOLBARLOCKED
: // lock toolbars
1094 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1096 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1110 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1111 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1113 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1118 // what do I do here?
1120 case ITID_TEXTLABELS
:
1121 // toggle text labels
1123 case ITID_TOOLBARBANDSHOWN
:
1124 // toggle toolbar band visibility
1126 case ITID_ADDRESSBANDSHOWN
:
1127 // toggle address band visibility
1129 case ITID_LINKSBANDSHOWN
:
1130 // toggle links band visibility
1132 case ITID_CUSTOMIZEENABLED
:
1135 case ITID_TOOLBARLOCKED
:
1136 return LockUnlockToolbars(!fLocked
);
1142 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1147 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1152 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1153 LCID lcid
, DISPID
*rgDispId
)
1158 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1159 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1163 switch(dispIdMember
)
1165 case DISPID_BEFORENAVIGATE
:
1168 case DISPID_DOWNLOADCOMPLETE
:
1171 case DISPID_COMMANDSTATECHANGE
:
1172 if (pDispParams
->cArgs
!= 2)
1173 return E_INVALIDARG
;
1174 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1175 return E_INVALIDARG
;
1176 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1177 V_I4(&pDispParams
->rgvarg
[1]));
1178 case DISPID_DOWNLOADBEGIN
:
1181 case DISPID_NAVIGATECOMPLETE2
:
1184 case DISPID_DOCUMENTCOMPLETE
:
1191 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1195 fCommandTarget
.Release();
1196 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1197 if (FAILED_UNEXPECTEDLY(hResult
))
1199 fCommandCategory
= *category
;
1203 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1208 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1213 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1214 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1218 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1219 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1226 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1231 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1233 if (theState
== NULL
)
1235 // map the command id
1236 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1240 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1242 // map the command id
1243 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1247 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1248 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1253 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1257 *paramC
= MAKELONG(24, 24);
1261 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1262 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1267 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1268 HIMAGELIST param14
, HIMAGELIST param18
)
1273 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1278 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1283 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1285 CComPtr
<IBrowserService
> browserService
;
1286 CComPtr
<IServiceProvider
> serviceProvider
;
1287 CComPtr
<IOleWindow
> oleWindow
;
1292 if (pUnkSite
== NULL
)
1294 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1295 ::DestroyWindow(fMainReBar
);
1301 // get window handle of owner
1302 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
1303 if (FAILED_UNEXPECTEDLY(hResult
))
1305 hResult
= oleWindow
->GetWindow(&ownerWindow
);
1306 if (FAILED_UNEXPECTEDLY(hResult
))
1308 if (ownerWindow
== NULL
)
1311 // create dock container
1313 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1314 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1315 if (dockContainer
== NULL
)
1317 SubclassWindow(dockContainer
);
1319 // create rebar in dock container
1320 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1321 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1322 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1323 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1324 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1325 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1326 if (fMainReBar
== NULL
)
1329 // take advice to watch events
1330 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1331 hResult
= serviceProvider
->QueryService(
1332 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1333 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1338 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1340 if (ppvSite
== NULL
)
1342 if (fSite
.p
!= NULL
)
1343 return fSite
->QueryInterface(riid
, ppvSite
);
1348 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1350 CComPtr
<IServiceProvider
> serviceProvider
;
1353 if (IsEqualIID(guidService
, IID_IBandSite
))
1354 return this->QueryInterface(riid
, ppvObject
);
1355 if (IsEqualIID(guidService
, SID_IBandProxy
))
1357 if (fBandProxy
.p
== NULL
)
1359 hResult
= CreateAndInitBandProxy();
1360 if (FAILED_UNEXPECTEDLY(hResult
))
1363 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1365 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1368 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1369 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1375 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1376 if (hResult
!= S_FALSE
)
1382 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1383 if (hResult
!= S_FALSE
)
1389 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1390 if (hResult
!= S_FALSE
)
1397 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1403 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1409 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1415 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1416 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1420 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1421 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1422 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1423 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1428 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1434 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1440 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1446 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1452 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1458 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1460 CComPtr
<IServiceProvider
> serviceProvider
;
1461 CComPtr
<IWebBrowser
> webBrowser
;
1464 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1465 if (FAILED_UNEXPECTEDLY(hResult
))
1467 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
,
1468 IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1469 if (FAILED_UNEXPECTEDLY(hResult
))
1471 hResult
= webBrowser
->GoBack();
1475 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1477 CComPtr
<IServiceProvider
> serviceProvider
;
1478 CComPtr
<IWebBrowser
> webBrowser
;
1481 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1482 if (FAILED_UNEXPECTEDLY(hResult
))
1484 hResult
= serviceProvider
->QueryService(
1485 SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1486 if (FAILED_UNEXPECTEDLY(hResult
))
1488 hResult
= webBrowser
->GoForward();
1492 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1494 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1497 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1498 if (FAILED_UNEXPECTEDLY(hResult
))
1500 hResult
= oleCommandTarget
->Exec(&CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1504 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1506 CComPtr
<IObjectWithSite
> objectWithSite
;
1507 CComPtr
<IContextMenu
> contextMenu
;
1508 CMINVOKECOMMANDINFO commandInfo
;
1509 const char *searchGUID
= "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1512 // TODO: Query shell if this command is enabled first
1514 memset(&commandInfo
, 0, sizeof(commandInfo
));
1515 commandInfo
.cbSize
= sizeof(commandInfo
);
1516 commandInfo
.hwnd
= m_hWnd
;
1517 commandInfo
.lpParameters
= searchGUID
;
1518 commandInfo
.nShow
= SW_SHOWNORMAL
;
1520 hResult
= CoCreateInstance(CLSID_ShellSearchExt
, NULL
, CLSCTX_INPROC_SERVER
,
1521 IID_PPV_ARG(IContextMenu
, &contextMenu
));
1522 if (FAILED_UNEXPECTEDLY(hResult
))
1524 hResult
= contextMenu
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &objectWithSite
));
1525 if (FAILED_UNEXPECTEDLY(hResult
))
1527 hResult
= objectWithSite
->SetSite(fSite
);
1528 if (FAILED_UNEXPECTEDLY(hResult
))
1530 hResult
= contextMenu
->InvokeCommand(&commandInfo
);
1531 hResult
= objectWithSite
->SetSite(NULL
);
1535 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1537 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1540 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1541 if (FAILED_UNEXPECTEDLY(hResult
))
1543 hResult
= oleCommandTarget
->Exec(&CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1547 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1551 if (fCommandTarget
.p
!= NULL
)
1553 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1558 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1560 CComPtr
<IServiceProvider
> serviceProvider
;
1561 CComPtr
<IBrowserService
> browserService
;
1562 CComPtr
<IOleCommandTarget
> commandTarget
;
1563 CComPtr
<ITravelLog
> travelLog
;
1564 NMTOOLBARW
*notifyInfo
;
1573 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1574 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1576 // not from the toolbar, keep looking for a message handler
1580 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1581 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1582 switch (notifyInfo
->iItem
)
1585 newMenu
= CreatePopupMenu();
1586 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1587 hResult
= serviceProvider
->QueryService(
1588 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1589 hResult
= browserService
->GetTravelLog(&travelLog
);
1590 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1591 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1592 commandInfo
.cmdID
= 0x1d;
1593 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1594 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1595 travelLog
->CountEntries(browserService
) > 1)
1597 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1598 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1600 params
.cbSize
= sizeof (params
);
1601 params
.rcExclude
= bounds
;
1602 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1603 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1604 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1606 V_VT(&parmIn
) = VT_I4
;
1608 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1610 else if (selectedItem
!= 0)
1611 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1612 DestroyMenu(newMenu
);
1614 case IDM_GOTO_FORWARD
:
1615 newMenu
= CreatePopupMenu();
1616 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1617 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1618 hResult
= browserService
->GetTravelLog(&travelLog
);
1619 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1620 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1621 commandInfo
.cmdID
= 0x1d;
1622 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1623 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1624 travelLog
->CountEntries(browserService
) > 1)
1626 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1627 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1629 params
.cbSize
= sizeof (params
);
1630 params
.rcExclude
= bounds
;
1631 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1632 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1633 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1635 V_VT(&parmIn
) = VT_I4
;
1637 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1639 else if (selectedItem
!= 0)
1640 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1641 DestroyMenu(newMenu
);
1643 case gViewsCommandID
:
1645 CComVariant outValue
;
1648 V_VT(&inValue
) = VT_INT_PTR
;
1649 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1651 if (fCommandTarget
.p
!= NULL
)
1652 hResult
= fCommandTarget
->Exec(&fCommandCategory
, FCIDM_SHVIEW_AUTOARRANGE
, 1, &inValue
, &outValue
);
1653 // pvaOut is VT_I4 with value 0x403
1656 return TBDDRET_DEFAULT
;
1659 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1664 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1669 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1671 HMENU contextMenuBar
;
1673 POINT clickLocation
;
1675 RBHITTESTINFO hitTestInfo
;
1676 REBARBANDINFOW rebarBandInfo
;
1679 clickLocation
.x
= LOWORD(lParam
);
1680 clickLocation
.y
= HIWORD(lParam
);
1681 hitTestInfo
.pt
= clickLocation
;
1682 ScreenToClient(&hitTestInfo
.pt
);
1683 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1684 if (hitTestInfo
.iBand
== -1)
1686 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1687 rebarBandInfo
.fMask
= RBBIM_ID
;
1688 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1689 bandID
= rebarBandInfo
.wID
;
1690 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1691 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1694 case ITBBID_MENUBAND
: // menu band
1695 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1696 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1697 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1699 case ITBBID_BRANDBAND
: // brand band
1700 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1701 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1702 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1704 case ITBBID_TOOLSBAND
: // tools band
1705 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1706 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1708 case ITBBID_ADDRESSBAND
: // navigation band
1709 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1710 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1717 mii
.cbSize
= sizeof(mii
);
1718 mii
.fMask
= MIIM_STATE
;
1719 mii
.fState
= fLocked
? MFS_CHECKED
: MFS_UNCHECKED
;
1720 SetMenuItemInfo(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, FALSE
, &mii
);
1722 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1723 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1724 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1727 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1729 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1731 case IDM_TOOLBARS_LINKSBAR
: // links
1733 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1734 LockUnlockToolbars(!fLocked
);
1736 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1737 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1741 DestroyMenu(contextMenuBar
);
1745 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1747 if (wParam
!= SIZE_MINIMIZED
)
1749 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1750 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1755 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1757 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1762 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1766 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1768 CComPtr
<IBrowserService
> browserService
;
1769 CComPtr
<ITravelLog
> travelLog
;
1770 TOOLTIPTEXTW
*pTTTW
;
1772 wchar_t tempString
[300];
1775 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1776 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1777 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1779 nID
= (UINT
)pNMHDR
->idFrom
;
1783 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1785 // TODO: Should this call QueryService?
1786 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1787 hResult
= browserService
->GetTravelLog(&travelLog
);
1788 hResult
= travelLog
->GetToolTipText(browserService
,
1789 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1790 0, tempString
, 299);
1791 if (FAILED_UNEXPECTEDLY(hResult
))
1799 wcsncpy (pTTTW
->szText
, tempString
, sizeof (pTTTW
->szText
) / sizeof (wchar_t));
1800 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1801 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1807 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1812 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1814 bHandled
= hResult
== S_OK
;
1816 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1818 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1820 NMHDR
*notifyHeader
;
1824 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1826 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1828 bHandled
= hResult
== S_OK
;
1830 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1833 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1839 if (wParam
& MK_CONTROL
)
1844 DWORD msgp
= GetMessagePos();
1846 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1847 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1850 GetWindowRect(m_hWnd
, &rc
);
1852 fStartHeight
= rc
.bottom
- rc
.top
;
1860 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1866 DWORD msgp
= GetMessagePos();
1869 pt
.x
= GET_X_LPARAM(msgp
);
1870 pt
.y
= GET_Y_LPARAM(msgp
);
1872 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1878 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1884 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);
1893 HRESULT
CreateInternetToolbar(REFIID riid
, void **ppv
)
1895 CInternetToolbar
*theToolbar
;
1901 ATLTRY (theToolbar
= new CComObject
<CInternetToolbar
>);
1902 if (theToolbar
== NULL
)
1903 return E_OUTOFMEMORY
;
1904 hResult
= theToolbar
->QueryInterface (riid
, reinterpret_cast<void **>(ppv
));
1905 if (FAILED_UNEXPECTEDLY(hResult
))