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(*PMENUBAND_CONSTRUCTOR
)(REFIID riid
, void **ppv
);
78 class CInternetToolbar
;
81 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
82 public IDockingWindowSite
,
83 public IInputObjectSite
,
84 public IOleCommandTarget
,
85 public IServiceProvider
91 ITF_NEWBANDALWAYS
= 4,
92 ITF_GRIPPERALWAYS
= 8,
96 CComPtr
<IUnknown
> fContainedBand
; // the band inside us
97 CInternetToolbar
*fToolbar
; // our browser
105 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
106 DESKBANDINFO fDeskBandInfo
;
110 HRESULT
Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
);
111 HRESULT
GetRBBandInfo(REBARBANDINFOW
&bandInfo
);
114 // *** IOleWindow methods ***
115 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
116 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
118 // *** IDockingWindow methods ***
119 virtual HRESULT STDMETHODCALLTYPE
GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
);
120 virtual HRESULT STDMETHODCALLTYPE
RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
121 virtual HRESULT STDMETHODCALLTYPE
SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
123 // *** IInputObjectSite specific methods ***
124 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
126 // *** IOleCommandTarget specific methods ***
127 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
128 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
129 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
130 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
132 // *** IServiceProvider methods ***
133 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
135 BEGIN_COM_MAP(CDockSite
)
136 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
137 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite
, IDockingWindowSite
)
138 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
139 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
140 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
144 CDockSite::CDockSite()
151 fInitialized
= false;
152 memset(&fDeskBandInfo
, 0, sizeof(fDeskBandInfo
));
155 CDockSite::~CDockSite()
159 HRESULT
CDockSite::Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
)
161 CComPtr
<IObjectWithSite
> site
;
162 CComPtr
<IOleWindow
> oleWindow
;
163 CComPtr
<IDeskBand
> deskBand
;
164 TCHAR textBuffer
[40];
165 REBARBANDINFOW bandInfo
;
168 hResult
= containedBand
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &site
));
171 hResult
= containedBand
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
174 hResult
= containedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
177 fContainedBand
= containedBand
;
182 hResult
= site
->SetSite(static_cast<IOleWindow
*>(this));
185 hResult
= oleWindow
->GetWindow(&fChildWindow
);
189 memset(&bandInfo
, 0, sizeof(bandInfo
));
190 bandInfo
.cbSize
= sizeof(bandInfo
);
191 bandInfo
.lpText
= textBuffer
;
192 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
193 hResult
= GetRBBandInfo(bandInfo
);
195 SendMessage(fRebarWindow
, RB_GETBANDCOUNT
, 0, 0);
196 SendMessage(fRebarWindow
, RB_INSERTBANDW
, -1, (LPARAM
)&bandInfo
);
201 HRESULT
CDockSite::GetRBBandInfo(REBARBANDINFOW
&bandInfo
)
203 CComPtr
<IDeskBand
> deskBand
;
206 hResult
= fContainedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
210 fDeskBandInfo
.dwMask
= DBIM_BKCOLOR
| DBIM_MODEFLAGS
| DBIM_TITLE
| DBIM_ACTUAL
|
211 DBIM_INTEGRAL
| DBIM_MAXSIZE
| DBIM_MINSIZE
;
212 hResult
= deskBand
->GetBandInfo(fBandID
, 0, &fDeskBandInfo
);
213 // result of call is ignored
215 bandInfo
.fMask
= RBBIM_LPARAM
| RBBIM_IDEALSIZE
| RBBIM_ID
| RBBIM_CHILDSIZE
| RBBIM_CHILD
|
216 RBBIM_TEXT
| RBBIM_STYLE
;
218 bandInfo
.fStyle
= RBBS_FIXEDBMP
;
219 if (fDeskBandInfo
.dwModeFlags
& DBIMF_VARIABLEHEIGHT
)
220 bandInfo
.fStyle
|= RBBS_VARIABLEHEIGHT
;
221 if (fDeskBandInfo
.dwModeFlags
& DBIMF_USECHEVRON
)
222 bandInfo
.fStyle
|= RBBS_USECHEVRON
;
223 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BREAK
)
224 bandInfo
.fStyle
|= RBBS_BREAK
;
225 if (fDeskBandInfo
.dwModeFlags
& DBIMF_TOPALIGN
)
226 bandInfo
.fStyle
|= RBBS_TOPALIGN
;
227 if (fFlags
& ITF_NOGRIPPER
|| fToolbar
->fLocked
)
228 bandInfo
.fStyle
|= RBBS_NOGRIPPER
;
229 if (fFlags
& ITF_NOTITLE
)
230 bandInfo
.fStyle
|= RBBS_HIDETITLE
;
231 if (fFlags
& ITF_GRIPPERALWAYS
&& !fToolbar
->fLocked
)
232 bandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
233 if (fFlags
& ITF_FIXEDSIZE
)
234 bandInfo
.fStyle
|= RBBS_FIXEDSIZE
;
236 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BKCOLOR
)
238 bandInfo
.fMask
|= RBBIM_COLORS
;
239 bandInfo
.clrFore
= CLR_DEFAULT
;
240 bandInfo
.clrBack
= fDeskBandInfo
.crBkgnd
;
242 wcsncpy(bandInfo
.lpText
, fDeskBandInfo
.wszTitle
, bandInfo
.cch
);
243 bandInfo
.hwndChild
= fChildWindow
;
244 bandInfo
.cxMinChild
= fDeskBandInfo
.ptMinSize
.x
;
245 bandInfo
.cyMinChild
= fDeskBandInfo
.ptMinSize
.y
;
246 bandInfo
.wID
= fBandID
;
247 bandInfo
.cyChild
= fDeskBandInfo
.ptActual
.y
;
248 bandInfo
.cyMaxChild
= fDeskBandInfo
.ptMaxSize
.y
;
249 bandInfo
.cyIntegral
= fDeskBandInfo
.ptIntegral
.y
;
250 bandInfo
.cxIdeal
= fDeskBandInfo
.ptActual
.x
;
251 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(this);
255 HRESULT STDMETHODCALLTYPE
CDockSite::GetWindow(HWND
*lphwnd
)
259 *lphwnd
= fRebarWindow
;
263 HRESULT STDMETHODCALLTYPE
CDockSite::ContextSensitiveHelp(BOOL fEnterMode
)
268 HRESULT STDMETHODCALLTYPE
CDockSite::GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
)
273 HRESULT STDMETHODCALLTYPE
CDockSite::RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
278 HRESULT STDMETHODCALLTYPE
CDockSite::SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
283 HRESULT STDMETHODCALLTYPE
CDockSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
288 HRESULT STDMETHODCALLTYPE
CDockSite::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
289 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
294 HRESULT STDMETHODCALLTYPE
CDockSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
,
295 VARIANT
*pvaIn
, VARIANT
*pvaOut
)
297 TCHAR textBuffer
[40];
298 REBARBANDINFOW bandInfo
;
302 if (IsEqualIID(*pguidCmdGroup
, CGID_DeskBand
))
306 case DBID_BANDINFOCHANGED
:
307 if (fInitialized
== false)
309 if (V_VT(pvaIn
) != VT_I4
)
311 if (V_I4(pvaIn
) != fBandID
)
313 // deskband information changed
314 // call GetBandInfo and refresh information in rebar
315 memset(&bandInfo
, 0, sizeof(bandInfo
));
316 bandInfo
.cbSize
= sizeof(bandInfo
);
317 bandInfo
.lpText
= textBuffer
;
318 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
319 hResult
= GetRBBandInfo(bandInfo
);
322 index
= (int)SendMessage(fRebarWindow
, RB_IDTOINDEX
, fBandID
, 0);
323 SendMessage(fRebarWindow
, RB_SETBANDINFOW
, index
, (LPARAM
)&bandInfo
);
330 HRESULT STDMETHODCALLTYPE
CDockSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
332 if (IsEqualIID(guidService
, SID_SMenuBandParent
))
333 return this->QueryInterface(riid
, ppvObject
);
335 return fToolbar
->QueryService(guidService
, riid
, ppvObject
);
338 CMenuCallback::CMenuCallback()
342 CMenuCallback::~CMenuCallback()
346 HRESULT STDMETHODCALLTYPE
CMenuCallback::GetObject(LPSMDATA psmd
, REFIID riid
, void **ppvObject
)
348 CComPtr
<IShellMenu
> parentMenu
;
349 CComPtr
<IShellMenu
> newMenu
;
350 CComPtr
<IShellFolder
> favoritesFolder
;
351 LPITEMIDLIST favoritesPIDL
;
354 HMENU favoritesHMenu
;
358 static const TCHAR szFavoritesKey
[] =
359 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
361 if (!IsEqualIID(riid
, IID_IShellMenu
))
363 if (psmd
->uId
!= FCIDM_MENU_FAVORITES
)
366 if (fFavoritesMenu
.p
== NULL
)
368 // create favorites menu
369 hResult
= psmd
->punk
->QueryInterface(IID_PPV_ARG(IShellMenu
, &parentMenu
));
372 hResult
= parentMenu
->GetMenu(&parentHMenu
, &ownerWindow
, NULL
);
375 favoritesHMenu
= GetSubMenu(parentHMenu
, 3);
376 if (favoritesHMenu
== NULL
)
378 #if USE_CUSTOM_MENUBAND
379 HMODULE hrs
= LoadLibrary(L
"rshell.dll");
381 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
384 hResult
= func(IID_PPV_ARG(IShellMenu
, &newMenu
));
388 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
389 IID_PPV_ARG(IShellMenu
, &newMenu
));
392 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
393 IID_PPV_ARG(IShellMenu
, &newMenu
));
397 hResult
= newMenu
->Initialize(this, FCIDM_MENU_FAVORITES
, -1, SMINIT_VERTICAL
| SMINIT_CACHED
);
400 hResult
= newMenu
->SetMenu(favoritesHMenu
, ownerWindow
, SMSET_TOP
| SMSET_DONTOWN
);
403 hResult
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &favoritesPIDL
);
406 hResult
= SHBindToFolder(favoritesPIDL
, &favoritesFolder
);
409 RegCreateKeyEx(HKEY_CURRENT_USER
, szFavoritesKey
,
410 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &orderRegKey
, &disposition
);
411 hResult
= newMenu
->SetShellFolder(favoritesFolder
, favoritesPIDL
, orderRegKey
, SMSET_BOTTOM
| 0x18);
412 ILFree(favoritesPIDL
);
413 if (SUCCEEDED(hResult
))
414 fFavoritesMenu
.Attach(newMenu
.Detach());
416 if (fFavoritesMenu
.p
== NULL
)
418 return fFavoritesMenu
->QueryInterface(riid
, ppvObject
);
421 HRESULT STDMETHODCALLTYPE
CMenuCallback::CallbackSM(LPSMDATA psmd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
433 SMINFO
*infoPtr
= reinterpret_cast<SMINFO
*>(lParam
);
434 if ((infoPtr
->dwMask
& SMIM_FLAGS
) != 0)
436 if (psmd
->uId
== FCIDM_MENU_FAVORITES
)
438 infoPtr
->dwFlags
|= SMIF_DROPCASCADE
;
442 infoPtr
->dwFlags
|= SMIF_TRACKPOPUP
;
445 if ((infoPtr
->dwMask
& SMIM_ICON
) != 0)
452 return GetObject(psmd
, *reinterpret_cast<IID
*>(wParam
), reinterpret_cast<void **>(lParam
));
453 case SMC_GETSFOBJECT
:
457 case SMC_SFSELECTITEM
:
470 case SMC_DEFAULTICON
:
474 case SMC_CHEVRONEXPAND
:
476 case SMC_DISPLAYCHEVRONTIP
:
478 case SMC_SETSFOBJECT
:
480 case SMC_SHCHANGENOTIFY
:
482 case SMC_CHEVRONGETTIP
:
484 case SMC_SFDDRESTRICTED
:
496 CInternetToolbar::CInternetToolbar()
500 fMenuBandWindow
= NULL
;
501 fNavigationWindow
= NULL
;
502 fMenuCallback
.AddRef();
503 fToolbarWindow
= NULL
;
507 CInternetToolbar::~CInternetToolbar()
509 fMenuCallback
.Release();
512 void CInternetToolbar::AddDockItem(IUnknown
*newItem
, int bandID
, int flags
)
516 newSite
= new CComObject
<CDockSite
>;
518 newSite
->Initialize(newItem
, this, fMainReBar
, bandID
, flags
);
521 HRESULT
CInternetToolbar::ReserveBorderSpace(LONG maxHeight
)
523 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
524 RECT availableBorderSpace
;
526 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
529 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDockingWindow
*>(this), &availableBorderSpace
);
533 if (availableBorderSpace
.top
> maxHeight
)
535 availableBorderSpace
.top
= maxHeight
;
538 return ResizeBorderDW(&availableBorderSpace
, fSite
, FALSE
);
541 HRESULT
CInternetToolbar::CreateMenuBar(IShellMenu
**menuBar
)
543 CComPtr
<IOleCommandTarget
> siteCommandTarget
;
544 CComPtr
<IOleWindow
> oleWindow
;
545 CComPtr
<IOleCommandTarget
> commandTarget
;
546 CComPtr
<IShellMenuCallback
> callback
;
551 #if USE_CUSTOM_MENUBAND
552 HMODULE hrs
= LoadLibraryW(L
"rshell.dll");
556 DbgPrint("Failed: %d\n", GetLastError());
560 PMENUBAND_CONSTRUCTOR func
= (PMENUBAND_CONSTRUCTOR
) GetProcAddress(hrs
, "CMenuBand_Constructor");
563 hResult
= func(IID_PPV_ARG(IShellMenu
, menuBar
));
567 DbgPrint("Failed: %d\n", GetLastError());
573 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
574 IID_PPV_ARG(IShellMenu
, menuBar
));
577 hResult
= CoCreateInstance(CLSID_MenuBand
, NULL
, CLSCTX_INPROC_SERVER
,
578 IID_PPV_ARG(IShellMenu
, menuBar
));
582 hResult
= fMenuCallback
.QueryInterface(IID_PPV_ARG(IShellMenuCallback
, &callback
));
585 hResult
= (*menuBar
)->Initialize(callback
, -1, ANCESTORDEFAULT
, SMINIT_HORIZONTAL
| SMINIT_TOPLEVEL
);
588 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
591 hResult
= oleWindow
->GetWindow(&ownerWindow
);
594 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &siteCommandTarget
));
597 hResult
= siteCommandTarget
->Exec(&CGID_Explorer
, 0x35, 0, NULL
, &menuOut
);
600 if (V_VT(&menuOut
) != VT_INT_PTR
|| V_INTREF(&menuOut
) == NULL
)
602 hResult
= (*menuBar
)->SetMenu((HMENU
)V_INTREF(&menuOut
), ownerWindow
, SMSET_DONTOWN
);
605 hResult
= (*menuBar
)->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
608 hResult
= commandTarget
->Exec(&CGID_MenuBand
, 3, 1, NULL
, NULL
);
614 HRESULT
CInternetToolbar::CreateBrandBand(IUnknown
**logoBar
)
616 CComPtr
<IUnknown
> tempBand
;
620 hResult
= ::CreateBrandBand(IID_PPV_ARG(IUnknown
, logoBar
));
622 hResult
= CoCreateInstance(CLSID_BrandBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, logoBar
));
629 HRESULT
CInternetToolbar::CreateToolsBar(IUnknown
**toolsBar
)
633 hResult
= ::CreateToolsBar(IID_PPV_ARG(IUnknown
, toolsBar
));
639 HRESULT
CInternetToolbar::CreateAddressBand(IUnknown
**toolsBar
)
641 CComPtr
<IAddressBand
> addressBand
;
645 hResult
= ::CreateAddressBand(IID_PPV_ARG(IUnknown
, toolsBar
));
647 hResult
= CoCreateInstance(CLSID_SH_AddressBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, toolsBar
));
651 hResult
= (*toolsBar
)->QueryInterface(IID_PPV_ARG(IAddressBand
, &addressBand
));
655 HRESULT
CInternetToolbar::LockUnlockToolbars(bool locked
)
657 REBARBANDINFOW rebarBandInfo
;
662 if (locked
!= fLocked
)
665 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
666 rebarBandInfo
.fMask
= RBBIM_STYLE
| RBBIM_LPARAM
;
667 bandCount
= (int)SendMessage(fMainReBar
, RB_GETBANDCOUNT
, 0, 0);
668 for (INT x
= 0; x
< bandCount
; x
++)
670 SendMessage(fMainReBar
, RB_GETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
671 dockSite
= reinterpret_cast<CDockSite
*>(rebarBandInfo
.lParam
);
672 if (dockSite
!= NULL
)
674 rebarBandInfo
.fStyle
&= ~(RBBS_NOGRIPPER
| RBBS_GRIPPERALWAYS
);
675 if (dockSite
->fFlags
& CDockSite::ITF_NOGRIPPER
|| fLocked
)
676 rebarBandInfo
.fStyle
|= RBBS_NOGRIPPER
;
677 if (dockSite
->fFlags
& CDockSite::ITF_GRIPPERALWAYS
&& !fLocked
)
678 rebarBandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
679 SendMessage(fMainReBar
, RB_SETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
682 hResult
= ReserveBorderSpace();
687 HRESULT
CInternetToolbar::CommandStateChanged(bool newValue
, int commandID
)
695 // loop through buttons
696 //for buttons in CLSID_CommonButtons
697 // if up, QueryStatus for up state and update it
699 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
703 hResult
= SetState(&CLSID_CommonButtons
, gForwardCommandID
, newValue
? TBSTATE_ENABLED
: 0);
707 hResult
= SetState(&CLSID_CommonButtons
, gBackCommandID
, newValue
? TBSTATE_ENABLED
: 0);
713 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
715 CComPtr
<IServiceProvider
> serviceProvider
;
718 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
721 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
724 hResult
= CreateBandProxy(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
727 hResult
= fBandProxy
->SetSite(fSite
);
734 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
739 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
744 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
749 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
757 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
762 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
764 CComPtr
<IDockingWindow
> dockingWindow
;
768 hResult
= ReserveBorderSpace();
769 hResult
= fMenuBar
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
770 hResult
= dockingWindow
->ShowDW(fShow
);
774 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
779 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
780 IUnknown
*punkToolbarSite
, BOOL fReserved
)
782 RECT neededBorderSpace
;
783 RECT availableBorderSpace
= *prcBorder
;
785 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
787 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
788 // Let's make sure we fetch the actual size properly.
789 GetWindowRect(fMainReBar
, &availableBorderSpace
);
790 neededBorderSpace
.left
= 0;
791 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
793 neededBorderSpace
.top
+= 3;
794 neededBorderSpace
.right
= 0;
795 neededBorderSpace
.bottom
= 0;
797 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
799 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
803 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
807 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
814 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
816 if (pClassID
== NULL
)
818 *pClassID
= CLSID_InternetToolbar
;
822 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
827 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
832 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
837 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
842 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
844 CComPtr
<IShellMenu
> menuBar
;
845 CComPtr
<IUnknown
> logoBar
;
846 CComPtr
<IUnknown
> toolsBar
;
847 CComPtr
<IUnknown
> navigationBar
;
848 CComPtr
<IOleWindow
> menuOleWindow
;
849 CComPtr
<IOleWindow
> toolbarOleWindow
;
850 CComPtr
<IOleWindow
> navigationOleWindow
;
853 /* Create and attach the menubar to the rebar */
854 hResult
= CreateMenuBar(&menuBar
);
857 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
859 hResult
= menuBar
->QueryInterface(IID_PPV_ARG(IOleWindow
, &menuOleWindow
));
860 hResult
= menuOleWindow
->GetWindow(&fMenuBandWindow
);
861 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
863 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
864 // and it will put them in their own row, sized to take up the whole row.
866 /* Create and attach the brand/logo to the rebar */
867 hResult
= CreateBrandBand(&logoBar
);
870 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
871 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
874 /* Create and attach the standard toolbar to the rebar */
875 hResult
= CreateToolsBar(&toolsBar
);
878 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
879 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
880 hResult
= fControlsBar
->QueryInterface(IID_PPV_ARG(IOleWindow
, &toolbarOleWindow
));
883 hResult
= toolbarOleWindow
->GetWindow(&fToolbarWindow
);
887 /* Create and attach the address/navigation toolbar to the rebar */
888 hResult
= CreateAddressBand(&navigationBar
);
891 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
892 hResult
= navigationBar
->QueryInterface(IID_PPV_ARG(IOleWindow
, &navigationOleWindow
));
893 hResult
= navigationOleWindow
->GetWindow(&fNavigationWindow
);
894 fNavigationBar
.Attach(navigationBar
.Detach());
899 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
900 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
902 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
906 switch (prgCmds
->cmdID
)
908 case ITID_TEXTLABELS
: // Text Labels state
909 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
911 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
912 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
914 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
915 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
917 case ITID_LINKSBANDSHOWN
: // links bar visibility
920 case ITID_MENUBANDSHOWN
: // Menubar band visibility
923 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
926 case ITID_CUSTOMIZEENABLED
: // customize enabled
927 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
929 case ITID_TOOLBARLOCKED
: // lock toolbars
930 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
932 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
946 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
947 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
949 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
954 // what do I do here?
956 case ITID_TEXTLABELS
:
957 // toggle text labels
959 case ITID_TOOLBARBANDSHOWN
:
960 // toggle toolbar band visibility
962 case ITID_ADDRESSBANDSHOWN
:
963 // toggle address band visibility
965 case ITID_LINKSBANDSHOWN
:
966 // toggle links band visibility
968 case ITID_CUSTOMIZEENABLED
:
971 case ITID_TOOLBARLOCKED
:
972 return LockUnlockToolbars(!fLocked
);
978 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
983 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
988 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
989 LCID lcid
, DISPID
*rgDispId
)
994 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
995 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1001 case DISPID_BEFORENAVIGATE
:
1004 case DISPID_DOWNLOADCOMPLETE
:
1007 case DISPID_COMMANDSTATECHANGE
:
1008 if (pDispParams
->cArgs
!= 2)
1009 return E_INVALIDARG
;
1010 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1011 return E_INVALIDARG
;
1012 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1013 V_I4(&pDispParams
->rgvarg
[1]));
1014 case DISPID_DOWNLOADBEGIN
:
1017 case DISPID_NAVIGATECOMPLETE2
:
1020 case DISPID_DOCUMENTCOMPLETE
:
1027 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1031 fCommandTarget
.Release();
1032 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1033 if (FAILED(hResult
))
1035 fCommandCategory
= *category
;
1039 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1044 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1049 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1050 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1054 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1055 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1062 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1067 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1069 if (theState
== NULL
)
1071 // map the command id
1072 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1076 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1078 // map the command id
1079 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1083 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1084 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1089 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1093 *paramC
= MAKELONG(24, 24);
1097 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1098 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1103 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1104 HIMAGELIST param14
, HIMAGELIST param18
)
1109 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1114 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1119 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1121 CComPtr
<IBrowserService
> browserService
;
1122 CComPtr
<IServiceProvider
> serviceProvider
;
1123 CComPtr
<IOleWindow
> oleWindow
;
1128 if (pUnkSite
== NULL
)
1130 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1131 ::DestroyWindow(fMainReBar
);
1137 // get window handle of owner
1138 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &oleWindow
));
1139 if (FAILED(hResult
))
1141 hResult
= oleWindow
->GetWindow(&ownerWindow
);
1142 if (FAILED(hResult
))
1144 if (ownerWindow
== NULL
)
1147 // create dock container
1149 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1150 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1151 if (dockContainer
== NULL
)
1153 SubclassWindow(dockContainer
);
1155 // create rebar in dock container
1156 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1157 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1158 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1159 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1160 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1161 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1162 if (fMainReBar
== NULL
)
1165 // take advice to watch events
1166 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1167 hResult
= serviceProvider
->QueryService(
1168 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1169 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1174 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1176 if (ppvSite
== NULL
)
1178 if (fSite
.p
!= NULL
)
1179 return fSite
->QueryInterface(riid
, ppvSite
);
1184 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1186 CComPtr
<IServiceProvider
> serviceProvider
;
1189 if (IsEqualIID(guidService
, IID_IBandSite
))
1190 return this->QueryInterface(riid
, ppvObject
);
1191 if (IsEqualIID(guidService
, SID_IBandProxy
))
1193 if (fBandProxy
.p
== NULL
)
1195 hResult
= CreateAndInitBandProxy();
1196 if (FAILED(hResult
))
1199 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1201 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1204 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1205 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1207 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
1212 hResult
= fMenuBar
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
1213 if (menuWinEventHandler
->IsWindowOwner(hWnd
) == S_OK
)
1215 return menuWinEventHandler
->OnWinEvent(fMenuBandWindow
, uMsg
, wParam
, lParam
, theResult
);
1222 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1227 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1232 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1237 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1238 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1242 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1243 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1244 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1245 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1250 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1255 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1260 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1265 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1270 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1275 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1277 CComPtr
<IServiceProvider
> serviceProvider
;
1278 CComPtr
<IWebBrowser
> webBrowser
;
1281 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1282 if (FAILED(hResult
))
1284 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
,
1285 IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1286 if (FAILED(hResult
))
1288 hResult
= webBrowser
->GoBack();
1292 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1294 CComPtr
<IServiceProvider
> serviceProvider
;
1295 CComPtr
<IWebBrowser
> webBrowser
;
1298 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1299 if (FAILED(hResult
))
1301 hResult
= serviceProvider
->QueryService(
1302 SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1303 if (FAILED(hResult
))
1305 hResult
= webBrowser
->GoForward();
1309 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1311 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1314 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1315 if (FAILED(hResult
))
1317 hResult
= oleCommandTarget
->Exec(&CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1321 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1323 CComPtr
<IObjectWithSite
> objectWithSite
;
1324 CComPtr
<IContextMenu
> contextMenu
;
1325 CMINVOKECOMMANDINFO commandInfo
;
1326 const char *searchGUID
= "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1329 // TODO: Query shell if this command is enabled first
1331 memset(&commandInfo
, 0, sizeof(commandInfo
));
1332 commandInfo
.cbSize
= sizeof(commandInfo
);
1333 commandInfo
.hwnd
= m_hWnd
;
1334 commandInfo
.lpParameters
= searchGUID
;
1335 commandInfo
.nShow
= SW_SHOWNORMAL
;
1337 hResult
= CoCreateInstance(CLSID_ShellSearchExt
, NULL
, CLSCTX_INPROC_SERVER
,
1338 IID_PPV_ARG(IContextMenu
, &contextMenu
));
1339 if (FAILED(hResult
))
1341 hResult
= contextMenu
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &objectWithSite
));
1342 if (FAILED(hResult
))
1344 hResult
= objectWithSite
->SetSite(fSite
);
1345 if (FAILED(hResult
))
1347 hResult
= contextMenu
->InvokeCommand(&commandInfo
);
1348 hResult
= objectWithSite
->SetSite(NULL
);
1352 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1354 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
1357 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &oleCommandTarget
));
1358 if (FAILED(hResult
))
1360 hResult
= oleCommandTarget
->Exec(&CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1364 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1368 if (fCommandTarget
.p
!= NULL
)
1370 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1375 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1377 CComPtr
<IServiceProvider
> serviceProvider
;
1378 CComPtr
<IBrowserService
> browserService
;
1379 CComPtr
<IOleCommandTarget
> commandTarget
;
1380 CComPtr
<ITravelLog
> travelLog
;
1381 NMTOOLBARW
*notifyInfo
;
1390 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1391 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1393 // not from the toolbar, keep looking for a message handler
1397 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1398 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1399 switch (notifyInfo
->iItem
)
1401 case gBackCommandID
:
1402 newMenu
= CreatePopupMenu();
1403 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1404 hResult
= serviceProvider
->QueryService(
1405 SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1406 hResult
= browserService
->GetTravelLog(&travelLog
);
1407 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1408 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1409 commandInfo
.cmdID
= 0x1d;
1410 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1411 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1412 travelLog
->CountEntries(browserService
) > 1)
1414 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1415 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1417 params
.cbSize
= sizeof (params
);
1418 params
.rcExclude
= bounds
;
1419 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1420 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1421 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1423 V_VT(&parmIn
) = VT_I4
;
1425 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1427 else if (selectedItem
!= 0)
1428 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1429 DestroyMenu(newMenu
);
1431 case gForwardCommandID
:
1432 newMenu
= CreatePopupMenu();
1433 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
1434 hResult
= serviceProvider
->QueryService(SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1435 hResult
= browserService
->GetTravelLog(&travelLog
);
1436 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1437 hResult
= browserService
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &commandTarget
));
1438 commandInfo
.cmdID
= 0x1d;
1439 hResult
= commandTarget
->QueryStatus(&CGID_Explorer
, 1, &commandInfo
, NULL
);
1440 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1441 travelLog
->CountEntries(browserService
) > 1)
1443 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1444 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1446 params
.cbSize
= sizeof (params
);
1447 params
.rcExclude
= bounds
;
1448 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1449 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1450 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1452 V_VT(&parmIn
) = VT_I4
;
1454 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1456 else if (selectedItem
!= 0)
1457 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1458 DestroyMenu(newMenu
);
1460 case gViewsCommandID
:
1462 CComVariant outValue
;
1465 V_VT(&inValue
) = VT_INT_PTR
;
1466 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1468 if (fCommandTarget
.p
!= NULL
)
1469 hResult
= fCommandTarget
->Exec(&fCommandCategory
, 0x7031, 1, &inValue
, &outValue
);
1470 // pvaOut is VT_I4 with value 0x403
1473 return TBDDRET_DEFAULT
;
1476 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1481 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1486 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1488 HMENU contextMenuBar
;
1490 POINT clickLocation
;
1492 RBHITTESTINFO hitTestInfo
;
1493 REBARBANDINFOW rebarBandInfo
;
1496 clickLocation
.x
= LOWORD(lParam
);
1497 clickLocation
.y
= HIWORD(lParam
);
1498 hitTestInfo
.pt
= clickLocation
;
1499 ScreenToClient(&hitTestInfo
.pt
);
1500 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1501 if (hitTestInfo
.iBand
== -1)
1503 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1504 rebarBandInfo
.fMask
= RBBIM_ID
;
1505 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1506 bandID
= rebarBandInfo
.wID
;
1507 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1508 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1511 case ITBBID_MENUBAND
: // menu band
1512 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1513 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1514 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1516 case ITBBID_BRANDBAND
: // brand band
1517 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1518 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1519 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1521 case ITBBID_TOOLSBAND
: // tools band
1522 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1523 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1525 case ITBBID_ADDRESSBAND
: // navigation band
1526 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1527 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1532 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1533 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1534 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1537 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1539 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1541 case IDM_TOOLBARS_LINKSBAR
: // links
1543 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1544 LockUnlockToolbars(!fLocked
);
1546 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1547 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1553 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1555 if (wParam
!= SIZE_MINIMIZED
)
1557 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1558 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1563 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1565 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1570 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1574 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1576 CComPtr
<IBrowserService
> browserService
;
1577 CComPtr
<ITravelLog
> travelLog
;
1578 TOOLTIPTEXTW
*pTTTW
;
1580 wchar_t tempString
[300];
1583 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1584 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1585 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1587 nID
= (UINT
)pNMHDR
->idFrom
;
1591 if (nID
== (UINT
)gBackCommandID
|| nID
== (UINT
)gForwardCommandID
)
1593 // TODO: Should this call QueryService?
1594 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1595 hResult
= browserService
->GetTravelLog(&travelLog
);
1596 hResult
= travelLog
->GetToolTipText(browserService
,
1597 (nID
== (UINT
)gBackCommandID
) ? TLOG_BACK
: TLOG_FORE
,
1598 0, tempString
, 299);
1599 if (FAILED(hResult
))
1607 wcsncpy (pTTTW
->szText
, tempString
, sizeof (pTTTW
->szText
) / sizeof (wchar_t));
1608 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1609 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1615 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1619 HWND target
= (HWND
) lParam
;
1623 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
1624 hResult
= fMenuBar
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
1625 if (SUCCEEDED(hResult
))
1627 if (menuWinEventHandler
->IsWindowOwner(target
) == S_OK
)
1629 hResult
= menuWinEventHandler
->OnWinEvent(target
, uMsg
, wParam
, lParam
, &theResult
);
1630 return FAILED(hResult
) ? 0 : theResult
;
1637 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
1638 hResult
= fNavigationBar
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
1639 if (SUCCEEDED(hResult
))
1641 if (menuWinEventHandler
->IsWindowOwner(target
) == S_OK
)
1643 hResult
= menuWinEventHandler
->OnWinEvent(target
, uMsg
, wParam
, lParam
, &theResult
);
1644 return FAILED(hResult
) ? 0 : theResult
;
1651 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1653 NMHDR
*notifyHeader
;
1657 notifyHeader
= (NMHDR
*) lParam
;
1661 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
1662 hResult
= fMenuBar
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
1663 if (SUCCEEDED(hResult
))
1665 if (menuWinEventHandler
->IsWindowOwner(notifyHeader
->hwndFrom
) == S_OK
)
1667 hResult
= menuWinEventHandler
->OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1668 return FAILED(hResult
) ? 0 : theResult
;
1675 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
1676 hResult
= fNavigationBar
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
1677 if (SUCCEEDED(hResult
))
1679 if (menuWinEventHandler
->IsWindowOwner(notifyHeader
->hwndFrom
) == S_OK
)
1681 hResult
= menuWinEventHandler
->OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1682 return FAILED(hResult
) ? 0 : theResult
;
1690 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1696 if (wParam
& MK_CONTROL
)
1701 DWORD msgp
= GetMessagePos();
1703 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1704 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1707 GetWindowRect(m_hWnd
, &rc
);
1709 fStartHeight
= rc
.bottom
- rc
.top
;
1717 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1723 DWORD msgp
= GetMessagePos();
1726 pt
.x
= GET_X_LPARAM(msgp
);
1727 pt
.y
= GET_Y_LPARAM(msgp
);
1729 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1735 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1741 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);
1750 HRESULT
CreateInternetToolbar(REFIID riid
, void **ppv
)
1752 CComObject
<CInternetToolbar
> *theToolbar
;
1758 ATLTRY (theToolbar
= new CComObject
<CInternetToolbar
>);
1759 if (theToolbar
== NULL
)
1760 return E_OUTOFMEMORY
;
1761 hResult
= theToolbar
->QueryInterface (riid
, reinterpret_cast<void **>(ppv
));
1762 if (FAILED(hResult
))