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 HRESULT
IUnknown_HasFocusIO(IUnknown
* punk
)
78 CComPtr
<IInputObject
> pio
;
80 hr
= punk
->QueryInterface(IID_PPV_ARG(IInputObject
, &pio
));
81 if (FAILED_UNEXPECTEDLY(hr
))
83 return pio
->HasFocusIO();
86 HRESULT
IUnknown_TranslateAcceleratorIO(IUnknown
* punk
, MSG
* pmsg
)
88 CComPtr
<IInputObject
> pio
;
92 hr
= punk
->QueryInterface(IID_PPV_ARG(IInputObject
, &pio
));
93 if (FAILED_UNEXPECTEDLY(hr
))
95 return pio
->TranslateAcceleratorIO(pmsg
);
98 HRESULT
IUnknown_RelayWinEvent(IUnknown
* punk
, HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
100 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
101 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
102 if (FAILED_UNEXPECTEDLY(hResult
))
104 hResult
= menuWinEventHandler
->IsWindowOwner(hWnd
);
105 if (FAILED_UNEXPECTEDLY(hResult
))
108 return menuWinEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
112 HRESULT
IUnknown_ShowDW(IUnknown
* punk
, BOOL fShow
)
114 CComPtr
<IDockingWindow
> dockingWindow
;
115 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
116 if (FAILED_UNEXPECTEDLY(hResult
))
118 hResult
= dockingWindow
->ShowDW(fShow
);
119 if (FAILED_UNEXPECTEDLY(hResult
))
124 HRESULT
IUnknown_CloseDW(IUnknown
* punk
, DWORD dwReserved
)
126 CComPtr
<IDockingWindow
> dockingWindow
;
127 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
128 if (FAILED_UNEXPECTEDLY(hResult
))
130 hResult
= dockingWindow
->CloseDW(dwReserved
);
131 if (FAILED_UNEXPECTEDLY(hResult
))
136 typedef HRESULT(*PMENUBAND_CONSTRUCTOR
)(REFIID riid
, void **ppv
);
138 class CInternetToolbar
;
141 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
142 public IDockingWindowSite
,
143 public IInputObjectSite
,
144 public IOleCommandTarget
,
145 public IServiceProvider
151 ITF_NEWBANDALWAYS
= 4,
152 ITF_GRIPPERALWAYS
= 8,
156 CComPtr
<IUnknown
> fContainedBand
; // the band inside us
157 CInternetToolbar
*fToolbar
; // our browser
165 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
166 DESKBANDINFO fDeskBandInfo
;
170 HRESULT
Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
);
171 HRESULT
GetRBBandInfo(REBARBANDINFOW
&bandInfo
);
174 // *** IOleWindow methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
176 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
178 // *** IDockingWindow methods ***
179 virtual HRESULT STDMETHODCALLTYPE
GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
);
180 virtual HRESULT STDMETHODCALLTYPE
RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
181 virtual HRESULT STDMETHODCALLTYPE
SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
183 // *** IInputObjectSite specific methods ***
184 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
186 // *** IOleCommandTarget specific methods ***
187 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
188 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
189 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
190 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
192 // *** IServiceProvider methods ***
193 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
195 BEGIN_COM_MAP(CDockSite
)
196 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
197 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite
, IDockingWindowSite
)
198 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
199 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
200 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
204 CDockSite::CDockSite()
211 fInitialized
= false;
212 memset(&fDeskBandInfo
, 0, sizeof(fDeskBandInfo
));
215 CDockSite::~CDockSite()
219 HRESULT
CDockSite::Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
)
221 TCHAR textBuffer
[40];
222 REBARBANDINFOW bandInfo
;
225 fContainedBand
= containedBand
;
230 hResult
= IUnknown_SetSite(containedBand
, static_cast<IOleWindow
*>(this));
231 if (FAILED_UNEXPECTEDLY(hResult
))
233 hResult
= IUnknown_GetWindow(containedBand
, &fChildWindow
);
234 if (FAILED_UNEXPECTEDLY(hResult
))
237 memset(&bandInfo
, 0, sizeof(bandInfo
));
238 bandInfo
.cbSize
= sizeof(bandInfo
);
239 bandInfo
.lpText
= textBuffer
;
240 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
241 hResult
= GetRBBandInfo(bandInfo
);
243 SendMessage(fRebarWindow
, RB_GETBANDCOUNT
, 0, 0);
244 SendMessage(fRebarWindow
, RB_INSERTBANDW
, -1, (LPARAM
)&bandInfo
);
249 HRESULT
CDockSite::GetRBBandInfo(REBARBANDINFOW
&bandInfo
)
251 CComPtr
<IDeskBand
> deskBand
;
254 hResult
= fContainedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
255 if (FAILED_UNEXPECTEDLY(hResult
))
258 fDeskBandInfo
.dwMask
= DBIM_BKCOLOR
| DBIM_MODEFLAGS
| DBIM_TITLE
| DBIM_ACTUAL
|
259 DBIM_INTEGRAL
| DBIM_MAXSIZE
| DBIM_MINSIZE
;
260 hResult
= deskBand
->GetBandInfo(fBandID
, 0, &fDeskBandInfo
);
261 // result of call is ignored
263 bandInfo
.fMask
= RBBIM_LPARAM
| RBBIM_IDEALSIZE
| RBBIM_ID
| RBBIM_CHILDSIZE
| RBBIM_CHILD
|
264 RBBIM_TEXT
| RBBIM_STYLE
;
266 bandInfo
.fStyle
= RBBS_FIXEDBMP
;
267 if (fDeskBandInfo
.dwModeFlags
& DBIMF_VARIABLEHEIGHT
)
268 bandInfo
.fStyle
|= RBBS_VARIABLEHEIGHT
;
269 if (fDeskBandInfo
.dwModeFlags
& DBIMF_USECHEVRON
)
270 bandInfo
.fStyle
|= RBBS_USECHEVRON
;
271 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BREAK
)
272 bandInfo
.fStyle
|= RBBS_BREAK
;
273 if (fDeskBandInfo
.dwModeFlags
& DBIMF_TOPALIGN
)
274 bandInfo
.fStyle
|= RBBS_TOPALIGN
;
275 if (fFlags
& ITF_NOGRIPPER
|| fToolbar
->fLocked
)
276 bandInfo
.fStyle
|= RBBS_NOGRIPPER
;
277 if (fFlags
& ITF_NOTITLE
)
278 bandInfo
.fStyle
|= RBBS_HIDETITLE
;
279 if (fFlags
& ITF_GRIPPERALWAYS
&& !fToolbar
->fLocked
)
280 bandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
281 if (fFlags
& ITF_FIXEDSIZE
)
282 bandInfo
.fStyle
|= RBBS_FIXEDSIZE
;
284 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BKCOLOR
)
286 bandInfo
.fMask
|= RBBIM_COLORS
;
287 bandInfo
.clrFore
= CLR_DEFAULT
;
288 bandInfo
.clrBack
= fDeskBandInfo
.crBkgnd
;
290 wcsncpy(bandInfo
.lpText
, fDeskBandInfo
.wszTitle
, bandInfo
.cch
);
291 bandInfo
.hwndChild
= fChildWindow
;
292 bandInfo
.cxMinChild
= fDeskBandInfo
.ptMinSize
.x
;
293 bandInfo
.cyMinChild
= fDeskBandInfo
.ptMinSize
.y
;
294 bandInfo
.wID
= fBandID
;
295 bandInfo
.cyChild
= fDeskBandInfo
.ptActual
.y
;
296 bandInfo
.cyMaxChild
= fDeskBandInfo
.ptMaxSize
.y
;
297 bandInfo
.cyIntegral
= fDeskBandInfo
.ptIntegral
.y
;
298 bandInfo
.cxIdeal
= fDeskBandInfo
.ptActual
.x
;
299 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(this);
303 HRESULT STDMETHODCALLTYPE
CDockSite::GetWindow(HWND
*lphwnd
)
307 *lphwnd
= fRebarWindow
;
311 HRESULT STDMETHODCALLTYPE
CDockSite::ContextSensitiveHelp(BOOL fEnterMode
)
316 HRESULT STDMETHODCALLTYPE
CDockSite::GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
)
321 HRESULT STDMETHODCALLTYPE
CDockSite::RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
326 HRESULT STDMETHODCALLTYPE
CDockSite::SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
331 HRESULT STDMETHODCALLTYPE
CDockSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
336 HRESULT STDMETHODCALLTYPE
CDockSite::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
337 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
342 HRESULT STDMETHODCALLTYPE
CDockSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
,
343 VARIANT
*pvaIn
, VARIANT
*pvaOut
)
345 TCHAR textBuffer
[40];
346 REBARBANDINFOW bandInfo
;
350 if (IsEqualIID(*pguidCmdGroup
, CGID_DeskBand
))
354 case DBID_BANDINFOCHANGED
:
355 if (fInitialized
== false)
357 if (V_VT(pvaIn
) != VT_I4
)
359 if (V_I4(pvaIn
) != fBandID
)
361 // deskband information changed
362 // call GetBandInfo and refresh information in rebar
363 memset(&bandInfo
, 0, sizeof(bandInfo
));
364 bandInfo
.cbSize
= sizeof(bandInfo
);
365 bandInfo
.lpText
= textBuffer
;
366 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
367 hResult
= GetRBBandInfo(bandInfo
);
368 if (FAILED_UNEXPECTEDLY(hResult
))
370 index
= (int)SendMessage(fRebarWindow
, RB_IDTOINDEX
, fBandID
, 0);
371 SendMessage(fRebarWindow
, RB_SETBANDINFOW
, index
, (LPARAM
)&bandInfo
);
378 HRESULT STDMETHODCALLTYPE
CDockSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
380 if (IsEqualIID(guidService
, SID_SMenuBandParent
))
381 return this->QueryInterface(riid
, ppvObject
);
383 return fToolbar
->QueryService(guidService
, riid
, ppvObject
);
386 CMenuCallback::CMenuCallback()
390 CMenuCallback::~CMenuCallback()
394 HRESULT STDMETHODCALLTYPE
CMenuCallback::GetObject(LPSMDATA psmd
, REFIID riid
, void **ppvObject
)
396 CComPtr
<IShellMenu
> parentMenu
;
397 CComPtr
<IShellMenu
> newMenu
;
398 CComPtr
<IShellFolder
> favoritesFolder
;
399 LPITEMIDLIST favoritesPIDL
;
402 HMENU favoritesHMenu
;
406 static const TCHAR szFavoritesKey
[] =
407 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
409 if (!IsEqualIID(riid
, IID_IShellMenu
))
411 if (psmd
->uId
!= FCIDM_MENU_FAVORITES
)
414 if (fFavoritesMenu
.p
== NULL
)
416 // create favorites menu
417 hResult
= psmd
->punk
->QueryInterface(IID_PPV_ARG(IShellMenu
, &parentMenu
));
418 if (FAILED_UNEXPECTEDLY(hResult
))
420 hResult
= parentMenu
->GetMenu(&parentHMenu
, &ownerWindow
, NULL
);
421 if (FAILED_UNEXPECTEDLY(hResult
))
423 favoritesHMenu
= GetSubMenu(parentHMenu
, 3);
424 if (favoritesHMenu
== NULL
)
426 #if USE_CUSTOM_MENUBAND
427 HMODULE hrs
= LoadLibrary(L
"rshell.dll");
429 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
432 hResult
= func(IID_PPV_ARG(IShellMenu
, &newMenu
));
436 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
437 IID_PPV_ARG(IShellMenu
, &newMenu
));
440 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
441 IID_PPV_ARG(IShellMenu
, &newMenu
));
443 if (FAILED_UNEXPECTEDLY(hResult
))
445 hResult
= newMenu
->Initialize(this, FCIDM_MENU_FAVORITES
, -1, SMINIT_VERTICAL
| SMINIT_CACHED
);
446 if (FAILED_UNEXPECTEDLY(hResult
))
448 hResult
= newMenu
->SetMenu(favoritesHMenu
, ownerWindow
, SMSET_TOP
| SMSET_DONTOWN
);
449 if (FAILED_UNEXPECTEDLY(hResult
))
451 hResult
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &favoritesPIDL
);
452 if (FAILED_UNEXPECTEDLY(hResult
))
454 hResult
= SHBindToFolder(favoritesPIDL
, &favoritesFolder
);
455 if (FAILED_UNEXPECTEDLY(hResult
))
457 RegCreateKeyEx(HKEY_CURRENT_USER
, szFavoritesKey
,
458 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &orderRegKey
, &disposition
);
459 hResult
= newMenu
->SetShellFolder(favoritesFolder
, favoritesPIDL
, orderRegKey
, SMSET_BOTTOM
| 0x18);
460 ILFree(favoritesPIDL
);
461 if (SUCCEEDED(hResult
))
462 fFavoritesMenu
.Attach(newMenu
.Detach());
464 if (fFavoritesMenu
.p
== NULL
)
466 return fFavoritesMenu
->QueryInterface(riid
, ppvObject
);
469 HRESULT STDMETHODCALLTYPE
CMenuCallback::CallbackSM(LPSMDATA psmd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
481 SMINFO
*infoPtr
= reinterpret_cast<SMINFO
*>(lParam
);
482 if ((infoPtr
->dwMask
& SMIM_FLAGS
) != 0)
484 if (psmd
->uId
== FCIDM_MENU_FAVORITES
)
486 infoPtr
->dwFlags
|= SMIF_DROPCASCADE
;
490 infoPtr
->dwFlags
|= SMIF_TRACKPOPUP
;
493 if ((infoPtr
->dwMask
& SMIM_ICON
) != 0)
500 return GetObject(psmd
, *reinterpret_cast<IID
*>(wParam
), reinterpret_cast<void **>(lParam
));
501 case SMC_GETSFOBJECT
:
505 case SMC_SFSELECTITEM
:
518 case SMC_DEFAULTICON
:
522 case SMC_CHEVRONEXPAND
:
524 case SMC_DISPLAYCHEVRONTIP
:
526 case SMC_SETSFOBJECT
:
528 case SMC_SHCHANGENOTIFY
:
530 case SMC_CHEVRONGETTIP
:
532 case SMC_SFDDRESTRICTED
:
544 CInternetToolbar::CInternetToolbar()
548 fMenuBandWindow
= NULL
;
549 fNavigationWindow
= NULL
;
550 fMenuCallback
.AddRef();
551 fToolbarWindow
= NULL
;
555 CInternetToolbar::~CInternetToolbar()
557 fMenuCallback
.Release();
560 void CInternetToolbar::AddDockItem(IUnknown
*newItem
, int bandID
, int flags
)
562 CComPtr
<CDockSite
> newSite
;
564 newSite
= new CComObject
<CDockSite
>;
565 newSite
->Initialize(newItem
, this, fMainReBar
, bandID
, flags
);
568 HRESULT
CInternetToolbar::ReserveBorderSpace(LONG maxHeight
)
570 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
571 RECT availableBorderSpace
;
573 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
574 if (FAILED_UNEXPECTEDLY(hResult
))
576 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDockingWindow
*>(this), &availableBorderSpace
);
577 if (FAILED_UNEXPECTEDLY(hResult
))
580 if (availableBorderSpace
.top
> maxHeight
)
582 availableBorderSpace
.top
= maxHeight
;
585 return ResizeBorderDW(&availableBorderSpace
, fSite
, FALSE
);
588 HRESULT
CInternetToolbar::CreateMenuBar(IShellMenu
**menuBar
)
590 CComPtr
<IOleCommandTarget
> siteCommandTarget
;
591 CComPtr
<IOleWindow
> oleWindow
;
592 CComPtr
<IOleCommandTarget
> commandTarget
;
593 CComPtr
<IShellMenuCallback
> callback
;
598 #if USE_CUSTOM_MENUBAND
599 HMODULE hrs
= LoadLibraryW(L
"rshell.dll");
603 DbgPrint("Failed: %d\n", GetLastError());
607 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
610 hResult
= func(IID_PPV_ARG(IShellMenu
, menuBar
));
614 DbgPrint("Failed: %d\n", GetLastError());
618 if (FAILED_UNEXPECTEDLY(hResult
))
620 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
621 IID_PPV_ARG(IShellMenu
, menuBar
));
624 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
625 IID_PPV_ARG(IShellMenu
, menuBar
));
627 if (FAILED_UNEXPECTEDLY(hResult
))
629 hResult
= fMenuCallback
.QueryInterface(IID_PPV_ARG(IShellMenuCallback
, &callback
));
630 if (FAILED_UNEXPECTEDLY(hResult
))
632 hResult
= (*menuBar
)->Initialize(callback
, -1, ANCESTORDEFAULT
, SMINIT_HORIZONTAL
| SMINIT_TOPLEVEL
);
633 if (FAILED_UNEXPECTEDLY(hResult
))
635 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
636 if (FAILED_UNEXPECTEDLY(hResult
))
638 hResult
= oleWindow
->GetWindow(&ownerWindow
);
639 if (FAILED_UNEXPECTEDLY(hResult
))
641 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &siteCommandTarget
));
642 if (FAILED_UNEXPECTEDLY(hResult
))
644 hResult
= siteCommandTarget
->Exec(&CGID_Explorer
, 0x35, 0, NULL
, &menuOut
);
645 if (FAILED_UNEXPECTEDLY(hResult
))
647 if (V_VT(&menuOut
) != VT_INT_PTR
|| V_INTREF(&menuOut
) == NULL
)
649 hResult
= (*menuBar
)->SetMenu((HMENU
)V_INTREF(&menuOut
), ownerWindow
, SMSET_DONTOWN
);
650 if (FAILED_UNEXPECTEDLY(hResult
))
652 hResult
= IUnknown_Exec(*menuBar
, CGID_MenuBand
, 3, 1, NULL
, NULL
);
653 if (FAILED_UNEXPECTEDLY(hResult
))
658 HRESULT
CInternetToolbar::CreateBrandBand(IUnknown
**logoBar
)
661 return ::CreateBrandBand(IID_PPV_ARG(IUnknown
, logoBar
));
663 return CoCreateInstance(CLSID_BrandBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, logoBar
));
667 HRESULT
CInternetToolbar::CreateToolsBar(IUnknown
**toolsBar
)
669 return ::CreateToolsBar(IID_PPV_ARG(IUnknown
, toolsBar
));
672 HRESULT
CInternetToolbar::CreateAddressBand(IUnknown
**toolsBar
)
675 return ::CreateAddressBand(IID_PPV_ARG(IUnknown
, toolsBar
));
677 return CoCreateInstance(CLSID_SH_AddressBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, toolsBar
));
681 HRESULT
CInternetToolbar::LockUnlockToolbars(bool locked
)
683 REBARBANDINFOW rebarBandInfo
;
688 if (locked
!= fLocked
)
691 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
692 rebarBandInfo
.fMask
= RBBIM_STYLE
| RBBIM_LPARAM
;
693 bandCount
= (int)SendMessage(fMainReBar
, RB_GETBANDCOUNT
, 0, 0);
694 for (INT x
= 0; x
< bandCount
; x
++)
696 SendMessage(fMainReBar
, RB_GETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
697 dockSite
= reinterpret_cast<CDockSite
*>(rebarBandInfo
.lParam
);
698 if (dockSite
!= NULL
)
700 rebarBandInfo
.fStyle
&= ~(RBBS_NOGRIPPER
| RBBS_GRIPPERALWAYS
);
701 if (dockSite
->fFlags
& CDockSite::ITF_NOGRIPPER
|| fLocked
)
702 rebarBandInfo
.fStyle
|= RBBS_NOGRIPPER
;
703 if (dockSite
->fFlags
& CDockSite::ITF_GRIPPERALWAYS
&& !fLocked
)
704 rebarBandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
705 SendMessage(fMainReBar
, RB_SETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
708 hResult
= ReserveBorderSpace();
710 // TODO: refresh view menu?
715 HRESULT
CInternetToolbar::CommandStateChanged(bool newValue
, int commandID
)
723 // loop through buttons
724 //for buttons in CLSID_CommonButtons
725 // if up, QueryStatus for up state and update it
727 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
731 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_FORWARD
, newValue
? TBSTATE_ENABLED
: 0);
735 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_BACK
, newValue
? TBSTATE_ENABLED
: 0);
741 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
743 CComPtr
<IServiceProvider
> serviceProvider
;
746 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
747 if (FAILED_UNEXPECTEDLY(hResult
))
749 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
750 if (FAILED_UNEXPECTEDLY(hResult
))
752 hResult
= CreateBandProxy(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
753 if (FAILED_UNEXPECTEDLY(hResult
))
755 hResult
= fBandProxy
->SetSite(fSite
);
756 if (FAILED_UNEXPECTEDLY(hResult
))
762 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
767 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
769 HRESULT hr
= S_FALSE
;
772 hr
= IUnknown_HasFocusIO(fMenuBar
);
777 hr
= IUnknown_HasFocusIO(fControlsBar
);
782 hr
= IUnknown_HasFocusIO(fNavigationBar
);
789 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
791 HRESULT hr
= S_FALSE
;
794 hr
= IUnknown_TranslateAcceleratorIO(fMenuBar
, lpMsg
);
799 hr
= IUnknown_TranslateAcceleratorIO(fControlsBar
, lpMsg
);
804 hr
= IUnknown_TranslateAcceleratorIO(fNavigationBar
, lpMsg
);
811 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
819 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
824 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
831 hResult
= ReserveBorderSpace();
832 if (FAILED_UNEXPECTEDLY(hResult
))
838 hResult
= IUnknown_ShowDW(fMenuBar
, fShow
);
839 if (FAILED_UNEXPECTEDLY(hResult
))
845 hResult
= IUnknown_ShowDW(fControlsBar
, fShow
);
846 if (FAILED_UNEXPECTEDLY(hResult
))
851 hResult
= IUnknown_ShowDW(fNavigationBar
, fShow
);
852 if (FAILED_UNEXPECTEDLY(hResult
))
857 hResult
= IUnknown_ShowDW(fLogoBar
, fShow
);
858 if (FAILED_UNEXPECTEDLY(hResult
))
865 void ReleaseCComPtrExpectZero(CComPtr
<T
>& cptr
, BOOL forceRelease
= FALSE
)
869 int nrc
= cptr
->Release();
872 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc
);
877 nrc
= cptr
->Release();
885 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
891 hResult
= IUnknown_CloseDW(fMenuBar
, dwReserved
);
892 if (FAILED_UNEXPECTEDLY(hResult
))
894 ReleaseCComPtrExpectZero(fMenuBar
);
898 hResult
= IUnknown_CloseDW(fControlsBar
, dwReserved
);
899 if (FAILED_UNEXPECTEDLY(hResult
))
901 ReleaseCComPtrExpectZero(fControlsBar
);
905 hResult
= IUnknown_CloseDW(fNavigationBar
, dwReserved
);
906 if (FAILED_UNEXPECTEDLY(hResult
))
908 ReleaseCComPtrExpectZero(fNavigationBar
);
912 hResult
= IUnknown_CloseDW(fLogoBar
, dwReserved
);
913 if (FAILED_UNEXPECTEDLY(hResult
))
915 ReleaseCComPtrExpectZero(fLogoBar
);
920 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
921 IUnknown
*punkToolbarSite
, BOOL fReserved
)
923 RECT neededBorderSpace
;
924 RECT availableBorderSpace
= *prcBorder
;
926 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
928 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
929 // Let's make sure we fetch the actual size properly.
930 GetWindowRect(fMainReBar
, &availableBorderSpace
);
931 neededBorderSpace
.left
= 0;
932 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
934 neededBorderSpace
.top
+= 3;
935 neededBorderSpace
.right
= 0;
936 neededBorderSpace
.bottom
= 0;
938 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
940 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
941 if (FAILED_UNEXPECTEDLY(hResult
))
944 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
945 if (FAILED_UNEXPECTEDLY(hResult
))
948 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
949 if (FAILED_UNEXPECTEDLY(hResult
))
955 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
957 if (pClassID
== NULL
)
959 *pClassID
= CLSID_InternetToolbar
;
963 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
968 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
973 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
978 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
983 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
985 CComPtr
<IShellMenu
> menuBar
;
986 CComPtr
<IUnknown
> logoBar
;
987 CComPtr
<IUnknown
> toolsBar
;
988 CComPtr
<IUnknown
> navigationBar
;
991 /* Create and attach the menubar to the rebar */
992 hResult
= CreateMenuBar(&menuBar
);
993 if (FAILED_UNEXPECTEDLY(hResult
))
995 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
997 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
998 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1000 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1001 // and it will put them in their own row, sized to take up the whole row.
1003 /* Create and attach the brand/logo to the rebar */
1004 hResult
= CreateBrandBand(&logoBar
);
1005 if (FAILED_UNEXPECTEDLY(hResult
))
1007 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1008 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1011 /* Create and attach the standard toolbar to the rebar */
1012 hResult
= CreateToolsBar(&toolsBar
);
1013 if (FAILED_UNEXPECTEDLY(hResult
))
1015 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1016 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1017 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1018 if (FAILED_UNEXPECTEDLY(hResult
))
1021 /* Create and attach the address/navigation toolbar to the rebar */
1022 hResult
= CreateAddressBand(&navigationBar
);
1023 if (FAILED_UNEXPECTEDLY(hResult
))
1025 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1026 fNavigationBar
.Attach(navigationBar
.Detach());
1027 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1032 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1033 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1035 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1039 switch (prgCmds
->cmdID
)
1041 case ITID_TEXTLABELS
: // Text Labels state
1042 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1044 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1045 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1047 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1048 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1050 case ITID_LINKSBANDSHOWN
: // links bar visibility
1053 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1056 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1059 case ITID_CUSTOMIZEENABLED
: // customize enabled
1060 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1062 case ITID_TOOLBARLOCKED
: // lock toolbars
1063 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1065 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1079 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1080 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1082 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1087 // what do I do here?
1089 case ITID_TEXTLABELS
:
1090 // toggle text labels
1092 case ITID_TOOLBARBANDSHOWN
:
1093 // toggle toolbar band visibility
1095 case ITID_ADDRESSBANDSHOWN
:
1096 // toggle address band visibility
1098 case ITID_LINKSBANDSHOWN
:
1099 // toggle links band visibility
1101 case ITID_CUSTOMIZEENABLED
:
1104 case ITID_TOOLBARLOCKED
:
1105 return LockUnlockToolbars(!fLocked
);
1111 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1116 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1121 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1122 LCID lcid
, DISPID
*rgDispId
)
1127 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1128 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1132 switch(dispIdMember
)
1134 case DISPID_BEFORENAVIGATE
:
1137 case DISPID_DOWNLOADCOMPLETE
:
1140 case DISPID_COMMANDSTATECHANGE
:
1141 if (pDispParams
->cArgs
!= 2)
1142 return E_INVALIDARG
;
1143 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1144 return E_INVALIDARG
;
1145 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1146 V_I4(&pDispParams
->rgvarg
[1]));
1147 case DISPID_DOWNLOADBEGIN
:
1150 case DISPID_NAVIGATECOMPLETE2
:
1153 case DISPID_DOCUMENTCOMPLETE
:
1160 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1164 fCommandTarget
.Release();
1165 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1166 if (FAILED_UNEXPECTEDLY(hResult
))
1168 fCommandCategory
= *category
;
1172 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1177 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1182 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1183 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1187 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1188 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1195 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1200 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1202 if (theState
== NULL
)
1204 // map the command id
1205 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1209 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1211 // map the command id
1212 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1216 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1217 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1222 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1226 *paramC
= MAKELONG(24, 24);
1230 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1231 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1236 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1237 HIMAGELIST param14
, HIMAGELIST param18
)
1242 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1247 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1252 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1254 CComPtr
<IBrowserService
> browserService
;
1255 CComPtr
<IServiceProvider
> serviceProvider
;
1256 CComPtr
<IOleWindow
> oleWindow
;
1261 if (pUnkSite
== NULL
)
1263 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1264 ::DestroyWindow(fMainReBar
);
1270 // get window handle of owner
1271 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
1272 if (FAILED_UNEXPECTEDLY(hResult
))
1274 hResult
= oleWindow
->GetWindow(&ownerWindow
);
1275 if (FAILED_UNEXPECTEDLY(hResult
))
1277 if (ownerWindow
== NULL
)
1280 // create dock container
1282 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1283 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1284 if (dockContainer
== NULL
)
1286 SubclassWindow(dockContainer
);
1288 // create rebar in dock container
1289 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1290 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1291 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1292 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1293 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1294 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1295 if (fMainReBar
== NULL
)
1298 // take advice to watch events
1299 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1300 hResult
= serviceProvider
->QueryService(
1301 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1302 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1307 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1309 if (ppvSite
== NULL
)
1311 if (fSite
.p
!= NULL
)
1312 return fSite
->QueryInterface(riid
, ppvSite
);
1317 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1319 CComPtr
<IServiceProvider
> serviceProvider
;
1322 if (IsEqualIID(guidService
, IID_IBandSite
))
1323 return this->QueryInterface(riid
, ppvObject
);
1324 if (IsEqualIID(guidService
, SID_IBandProxy
))
1326 if (fBandProxy
.p
== NULL
)
1328 hResult
= CreateAndInitBandProxy();
1329 if (FAILED_UNEXPECTEDLY(hResult
))
1332 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1334 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1337 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1338 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1344 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1345 if (hResult
!= S_FALSE
)
1351 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1352 if (hResult
!= S_FALSE
)
1358 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1359 if (hResult
!= S_FALSE
)
1366 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1372 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1378 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1384 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1385 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1389 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1390 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1391 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1392 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1397 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1403 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1409 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1415 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1421 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1427 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1429 CComPtr
<IServiceProvider
> serviceProvider
;
1430 CComPtr
<IWebBrowser
> webBrowser
;
1433 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1434 if (FAILED_UNEXPECTEDLY(hResult
))
1436 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
,
1437 IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1438 if (FAILED_UNEXPECTEDLY(hResult
))
1440 hResult
= webBrowser
->GoBack();
1444 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1446 CComPtr
<IServiceProvider
> serviceProvider
;
1447 CComPtr
<IWebBrowser
> webBrowser
;
1450 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1451 if (FAILED_UNEXPECTEDLY(hResult
))
1453 hResult
= serviceProvider
->QueryService(
1454 SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1455 if (FAILED_UNEXPECTEDLY(hResult
))
1457 hResult
= webBrowser
->GoForward();
1461 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1463 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1466 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1467 if (FAILED_UNEXPECTEDLY(hResult
))
1469 hResult
= oleCommandTarget
->Exec(&CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1473 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1475 CComPtr
<IObjectWithSite
> objectWithSite
;
1476 CComPtr
<IContextMenu
> contextMenu
;
1477 CMINVOKECOMMANDINFO commandInfo
;
1478 const char *searchGUID
= "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1481 // TODO: Query shell if this command is enabled first
1483 memset(&commandInfo
, 0, sizeof(commandInfo
));
1484 commandInfo
.cbSize
= sizeof(commandInfo
);
1485 commandInfo
.hwnd
= m_hWnd
;
1486 commandInfo
.lpParameters
= searchGUID
;
1487 commandInfo
.nShow
= SW_SHOWNORMAL
;
1489 hResult
= CoCreateInstance(CLSID_ShellSearchExt
, NULL
, CLSCTX_INPROC_SERVER
,
1490 IID_PPV_ARG(IContextMenu
, &contextMenu
));
1491 if (FAILED_UNEXPECTEDLY(hResult
))
1493 hResult
= contextMenu
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &objectWithSite
));
1494 if (FAILED_UNEXPECTEDLY(hResult
))
1496 hResult
= objectWithSite
->SetSite(fSite
);
1497 if (FAILED_UNEXPECTEDLY(hResult
))
1499 hResult
= contextMenu
->InvokeCommand(&commandInfo
);
1500 hResult
= objectWithSite
->SetSite(NULL
);
1504 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1506 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1509 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1510 if (FAILED_UNEXPECTEDLY(hResult
))
1512 hResult
= oleCommandTarget
->Exec(&CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1516 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1520 if (fCommandTarget
.p
!= NULL
)
1522 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1527 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1529 CComPtr
<IServiceProvider
> serviceProvider
;
1530 CComPtr
<IBrowserService
> browserService
;
1531 CComPtr
<IOleCommandTarget
> commandTarget
;
1532 CComPtr
<ITravelLog
> travelLog
;
1533 NMTOOLBARW
*notifyInfo
;
1542 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1543 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1545 // not from the toolbar, keep looking for a message handler
1549 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1550 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1551 switch (notifyInfo
->iItem
)
1554 newMenu
= CreatePopupMenu();
1555 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1556 hResult
= serviceProvider
->QueryService(
1557 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1558 hResult
= browserService
->GetTravelLog(&travelLog
);
1559 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1560 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1561 commandInfo
.cmdID
= 0x1d;
1562 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1563 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1564 travelLog
->CountEntries(browserService
) > 1)
1566 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1567 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1569 params
.cbSize
= sizeof (params
);
1570 params
.rcExclude
= bounds
;
1571 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1572 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1573 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1575 V_VT(&parmIn
) = VT_I4
;
1577 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1579 else if (selectedItem
!= 0)
1580 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1581 DestroyMenu(newMenu
);
1583 case IDM_GOTO_FORWARD
:
1584 newMenu
= CreatePopupMenu();
1585 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1586 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1587 hResult
= browserService
->GetTravelLog(&travelLog
);
1588 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1589 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1590 commandInfo
.cmdID
= 0x1d;
1591 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1592 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1593 travelLog
->CountEntries(browserService
) > 1)
1595 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1596 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1598 params
.cbSize
= sizeof (params
);
1599 params
.rcExclude
= bounds
;
1600 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1601 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1602 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1604 V_VT(&parmIn
) = VT_I4
;
1606 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1608 else if (selectedItem
!= 0)
1609 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1610 DestroyMenu(newMenu
);
1612 case gViewsCommandID
:
1614 CComVariant outValue
;
1617 V_VT(&inValue
) = VT_INT_PTR
;
1618 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1620 if (fCommandTarget
.p
!= NULL
)
1621 hResult
= fCommandTarget
->Exec(&fCommandCategory
, 0x7031, 1, &inValue
, &outValue
);
1622 // pvaOut is VT_I4 with value 0x403
1625 return TBDDRET_DEFAULT
;
1628 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1633 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1638 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1640 HMENU contextMenuBar
;
1642 POINT clickLocation
;
1644 RBHITTESTINFO hitTestInfo
;
1645 REBARBANDINFOW rebarBandInfo
;
1648 clickLocation
.x
= LOWORD(lParam
);
1649 clickLocation
.y
= HIWORD(lParam
);
1650 hitTestInfo
.pt
= clickLocation
;
1651 ScreenToClient(&hitTestInfo
.pt
);
1652 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1653 if (hitTestInfo
.iBand
== -1)
1655 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1656 rebarBandInfo
.fMask
= RBBIM_ID
;
1657 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1658 bandID
= rebarBandInfo
.wID
;
1659 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1660 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1663 case ITBBID_MENUBAND
: // menu band
1664 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1665 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1666 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1668 case ITBBID_BRANDBAND
: // brand band
1669 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1670 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1671 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1673 case ITBBID_TOOLSBAND
: // tools band
1674 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1675 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1677 case ITBBID_ADDRESSBAND
: // navigation band
1678 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1679 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1686 mii
.cbSize
= sizeof(mii
);
1687 mii
.fMask
= MIIM_STATE
;
1688 mii
.fState
= fLocked
? MFS_CHECKED
: MFS_UNCHECKED
;
1689 command
= SetMenuItemInfo(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, FALSE
, &mii
);
1691 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1692 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1693 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1696 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1698 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1700 case IDM_TOOLBARS_LINKSBAR
: // links
1702 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1703 LockUnlockToolbars(!fLocked
);
1705 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1706 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1710 DestroyMenu(contextMenuBar
);
1714 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1716 if (wParam
!= SIZE_MINIMIZED
)
1718 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1719 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1724 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1726 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1731 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1735 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1737 CComPtr
<IBrowserService
> browserService
;
1738 CComPtr
<ITravelLog
> travelLog
;
1739 TOOLTIPTEXTW
*pTTTW
;
1741 wchar_t tempString
[300];
1744 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1745 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1746 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1748 nID
= (UINT
)pNMHDR
->idFrom
;
1752 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1754 // TODO: Should this call QueryService?
1755 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1756 hResult
= browserService
->GetTravelLog(&travelLog
);
1757 hResult
= travelLog
->GetToolTipText(browserService
,
1758 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1759 0, tempString
, 299);
1760 if (FAILED_UNEXPECTEDLY(hResult
))
1768 wcsncpy (pTTTW
->szText
, tempString
, sizeof (pTTTW
->szText
) / sizeof (wchar_t));
1769 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1770 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1776 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1781 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1783 bHandled
= hResult
== S_OK
;
1785 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1787 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1789 NMHDR
*notifyHeader
;
1793 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1795 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1797 bHandled
= hResult
== S_OK
;
1799 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1802 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1808 if (wParam
& MK_CONTROL
)
1813 DWORD msgp
= GetMessagePos();
1815 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1816 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1819 GetWindowRect(m_hWnd
, &rc
);
1821 fStartHeight
= rc
.bottom
- rc
.top
;
1829 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1835 DWORD msgp
= GetMessagePos();
1838 pt
.x
= GET_X_LPARAM(msgp
);
1839 pt
.y
= GET_Y_LPARAM(msgp
);
1841 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1847 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1853 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);
1862 HRESULT
CreateInternetToolbar(REFIID riid
, void **ppv
)
1864 CInternetToolbar
*theToolbar
;
1870 ATLTRY (theToolbar
= new CComObject
<CInternetToolbar
>);
1871 if (theToolbar
== NULL
)
1872 return E_OUTOFMEMORY
;
1873 hResult
= theToolbar
->QueryInterface (riid
, reinterpret_cast<void **>(ppv
));
1874 if (FAILED_UNEXPECTEDLY(hResult
))