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))
34 interface IAugmentedShellFolder
: public IShellFolder
36 virtual HRESULT STDMETHODCALLTYPE
AddNameSpace(LPGUID
, IShellFolder
*, LPCITEMIDLIST
, ULONG
) = 0;
37 virtual HRESULT STDMETHODCALLTYPE
GetNameSpaceID(LPCITEMIDLIST
, LPGUID
) = 0;
38 virtual HRESULT STDMETHODCALLTYPE
QueryNameSpace(ULONG
, LPGUID
, IShellFolder
**) = 0;
39 virtual HRESULT STDMETHODCALLTYPE
EnumNameSpace(ULONG
, PULONG
) = 0;
44 // navigation controls and menubar just send a message to parent window
47 ****Implement BandProxy methods
48 ****Add QueryStatus handler for built-in bands
49 ****Enable/Disable up, search, and folders commands appropriately
50 **Why are explorer toolbar separators a nonstandard width?
51 **Remove "(Empty)" item from Favorites menu. Probably something missing in CMenuCallback::CallbackSM
52 **Chevron menu on menuband doesn't work
53 **Fix CInternetToolbar::QueryBand to be generic
55 ****Fix context menu to strip divider when menu shown for menu band
56 ****Fix context menu to have items checked appropriately
57 ****Implement -1 command id update
58 ****When bands are rearranged, resize the internet toolbar and fix height of brand band
59 ****Right clicking on the browse back and forward toolbar buttons displays the same as pulldown menus
60 Implement show/hide of bands
61 Why is the background color of my toolbars different from explorer?
62 Internet Toolbar command handler should get the target for the command and call Exec on the target.
63 For commands built in to the Internet Toolbar, its Exec handles the command
64 When window width is changed, brand band flashes badly
65 Add all bands with correct ids (system bands now add with correct ids)
67 Implement remaining IExplorerToolbar methods
68 Fix toolbar buttons to enable/disable correctly
69 After toolbar is customized, it may be necessary to patch the widths of separators
71 Check sizes and spacing of toolbars against Explorer
72 Implement resizing of the dock bar
73 Add missing icons for toolbar items
74 Draw History item in forward/back dropdown menus with icon
75 Fix toolbar customize dialog to not include separators as possible selections
76 Implement save/restore of toolbar state
77 Refactor drop down menu code to use a common function since code is so similar
80 extern HRESULT WINAPI
SHBindToFolder(LPCITEMIDLIST path
, IShellFolder
**newFolder
);
82 HRESULT
IUnknown_RelayWinEvent(IUnknown
* punk
, HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
84 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
85 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
86 if (FAILED_UNEXPECTEDLY(hResult
))
88 hResult
= menuWinEventHandler
->IsWindowOwner(hWnd
);
89 if (FAILED_UNEXPECTEDLY(hResult
))
92 return menuWinEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
96 HRESULT
IUnknown_ShowDW(IUnknown
* punk
, BOOL fShow
)
98 CComPtr
<IDockingWindow
> dockingWindow
;
99 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
100 if (FAILED_UNEXPECTEDLY(hResult
))
102 hResult
= dockingWindow
->ShowDW(fShow
);
103 if (FAILED_UNEXPECTEDLY(hResult
))
108 HRESULT
IUnknown_CloseDW(IUnknown
* punk
, DWORD dwReserved
)
110 CComPtr
<IDockingWindow
> dockingWindow
;
111 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
112 if (FAILED_UNEXPECTEDLY(hResult
))
114 hResult
= dockingWindow
->CloseDW(dwReserved
);
115 if (FAILED_UNEXPECTEDLY(hResult
))
120 class CInternetToolbar
;
123 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
124 public IDockingWindowSite
,
125 public IInputObjectSite
,
126 public IOleCommandTarget
,
127 public IServiceProvider
133 ITF_NEWBANDALWAYS
= 4,
134 ITF_GRIPPERALWAYS
= 8,
138 CComPtr
<IUnknown
> fContainedBand
; // the band inside us
139 CInternetToolbar
*fToolbar
; // our browser
147 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
148 DESKBANDINFO fDeskBandInfo
;
152 HRESULT
Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
);
153 HRESULT
GetRBBandInfo(REBARBANDINFOW
&bandInfo
);
156 // *** IOleWindow methods ***
157 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
158 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
160 // *** IDockingWindow methods ***
161 virtual HRESULT STDMETHODCALLTYPE
GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
);
162 virtual HRESULT STDMETHODCALLTYPE
RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
163 virtual HRESULT STDMETHODCALLTYPE
SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
165 // *** IInputObjectSite specific methods ***
166 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
168 // *** IOleCommandTarget specific methods ***
169 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
170 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
171 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
172 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
174 // *** IServiceProvider methods ***
175 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
177 BEGIN_COM_MAP(CDockSite
)
178 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
179 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite
, IDockingWindowSite
)
180 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
181 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
182 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
186 CDockSite::CDockSite()
193 fInitialized
= false;
194 memset(&fDeskBandInfo
, 0, sizeof(fDeskBandInfo
));
197 CDockSite::~CDockSite()
201 HRESULT
CDockSite::Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
)
203 TCHAR textBuffer
[40];
204 REBARBANDINFOW bandInfo
;
207 fContainedBand
= containedBand
;
212 hResult
= IUnknown_SetSite(containedBand
, static_cast<IOleWindow
*>(this));
213 if (FAILED_UNEXPECTEDLY(hResult
))
215 hResult
= IUnknown_GetWindow(containedBand
, &fChildWindow
);
216 if (FAILED_UNEXPECTEDLY(hResult
))
219 memset(&bandInfo
, 0, sizeof(bandInfo
));
220 bandInfo
.cbSize
= sizeof(bandInfo
);
221 bandInfo
.lpText
= textBuffer
;
222 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
223 hResult
= GetRBBandInfo(bandInfo
);
225 SendMessage(fRebarWindow
, RB_GETBANDCOUNT
, 0, 0);
226 SendMessage(fRebarWindow
, RB_INSERTBANDW
, -1, (LPARAM
)&bandInfo
);
231 HRESULT
CDockSite::GetRBBandInfo(REBARBANDINFOW
&bandInfo
)
233 CComPtr
<IDeskBand
> deskBand
;
236 hResult
= fContainedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
237 if (FAILED_UNEXPECTEDLY(hResult
))
240 fDeskBandInfo
.dwMask
= DBIM_BKCOLOR
| DBIM_MODEFLAGS
| DBIM_TITLE
| DBIM_ACTUAL
|
241 DBIM_INTEGRAL
| DBIM_MAXSIZE
| DBIM_MINSIZE
;
242 hResult
= deskBand
->GetBandInfo(fBandID
, 0, &fDeskBandInfo
);
243 // result of call is ignored
245 bandInfo
.fMask
= RBBIM_LPARAM
| RBBIM_IDEALSIZE
| RBBIM_ID
| RBBIM_CHILDSIZE
| RBBIM_CHILD
|
246 RBBIM_TEXT
| RBBIM_STYLE
;
248 bandInfo
.fStyle
= RBBS_FIXEDBMP
;
249 if (fDeskBandInfo
.dwModeFlags
& DBIMF_VARIABLEHEIGHT
)
250 bandInfo
.fStyle
|= RBBS_VARIABLEHEIGHT
;
251 if (fDeskBandInfo
.dwModeFlags
& DBIMF_USECHEVRON
)
252 bandInfo
.fStyle
|= RBBS_USECHEVRON
;
253 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BREAK
)
254 bandInfo
.fStyle
|= RBBS_BREAK
;
255 if (fDeskBandInfo
.dwModeFlags
& DBIMF_TOPALIGN
)
256 bandInfo
.fStyle
|= RBBS_TOPALIGN
;
257 if (fFlags
& ITF_NOGRIPPER
|| fToolbar
->fLocked
)
258 bandInfo
.fStyle
|= RBBS_NOGRIPPER
;
259 if (fFlags
& ITF_NOTITLE
)
260 bandInfo
.fStyle
|= RBBS_HIDETITLE
;
261 if (fFlags
& ITF_GRIPPERALWAYS
&& !fToolbar
->fLocked
)
262 bandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
263 if (fFlags
& ITF_FIXEDSIZE
)
264 bandInfo
.fStyle
|= RBBS_FIXEDSIZE
;
266 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BKCOLOR
)
268 bandInfo
.fMask
|= RBBIM_COLORS
;
269 bandInfo
.clrFore
= CLR_DEFAULT
;
270 bandInfo
.clrBack
= fDeskBandInfo
.crBkgnd
;
272 wcsncpy(bandInfo
.lpText
, fDeskBandInfo
.wszTitle
, bandInfo
.cch
);
273 bandInfo
.hwndChild
= fChildWindow
;
274 bandInfo
.cxMinChild
= fDeskBandInfo
.ptMinSize
.x
;
275 bandInfo
.cyMinChild
= fDeskBandInfo
.ptMinSize
.y
;
276 bandInfo
.wID
= fBandID
;
277 bandInfo
.cyChild
= fDeskBandInfo
.ptActual
.y
;
278 bandInfo
.cyMaxChild
= fDeskBandInfo
.ptMaxSize
.y
;
279 bandInfo
.cyIntegral
= fDeskBandInfo
.ptIntegral
.y
;
280 bandInfo
.cxIdeal
= fDeskBandInfo
.ptActual
.x
;
281 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(this);
285 HRESULT STDMETHODCALLTYPE
CDockSite::GetWindow(HWND
*lphwnd
)
289 *lphwnd
= fRebarWindow
;
293 HRESULT STDMETHODCALLTYPE
CDockSite::ContextSensitiveHelp(BOOL fEnterMode
)
298 HRESULT STDMETHODCALLTYPE
CDockSite::GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
)
303 HRESULT STDMETHODCALLTYPE
CDockSite::RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
308 HRESULT STDMETHODCALLTYPE
CDockSite::SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
313 HRESULT STDMETHODCALLTYPE
CDockSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
318 HRESULT STDMETHODCALLTYPE
CDockSite::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
319 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
324 HRESULT STDMETHODCALLTYPE
CDockSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
,
325 VARIANT
*pvaIn
, VARIANT
*pvaOut
)
327 TCHAR textBuffer
[40];
328 REBARBANDINFOW bandInfo
;
332 if (IsEqualIID(*pguidCmdGroup
, CGID_DeskBand
))
336 case DBID_BANDINFOCHANGED
:
337 if (fInitialized
== false)
339 if (V_VT(pvaIn
) != VT_I4
)
341 if (V_I4(pvaIn
) != fBandID
)
343 // deskband information changed
344 // call GetBandInfo and refresh information in rebar
345 memset(&bandInfo
, 0, sizeof(bandInfo
));
346 bandInfo
.cbSize
= sizeof(bandInfo
);
347 bandInfo
.lpText
= textBuffer
;
348 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
349 hResult
= GetRBBandInfo(bandInfo
);
350 if (FAILED_UNEXPECTEDLY(hResult
))
352 index
= (int)SendMessage(fRebarWindow
, RB_IDTOINDEX
, fBandID
, 0);
353 SendMessage(fRebarWindow
, RB_SETBANDINFOW
, index
, (LPARAM
)&bandInfo
);
360 HRESULT STDMETHODCALLTYPE
CDockSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
362 if (IsEqualIID(guidService
, SID_SMenuBandParent
))
363 return this->QueryInterface(riid
, ppvObject
);
365 return fToolbar
->QueryService(guidService
, riid
, ppvObject
);
368 CMenuCallback::CMenuCallback()
372 CMenuCallback::~CMenuCallback()
376 static HRESULT
BindToDesktop(LPCITEMIDLIST pidl
, IShellFolder
** ppsfResult
)
379 CComPtr
<IShellFolder
> psfDesktop
;
383 hr
= SHGetDesktopFolder(&psfDesktop
);
387 hr
= psfDesktop
->BindToObject(pidl
, NULL
, IID_PPV_ARG(IShellFolder
, ppsfResult
));
392 static HRESULT
GetFavoritesFolder(IShellFolder
** ppsfFavorites
, LPITEMIDLIST
* ppidl
)
395 LPITEMIDLIST pidlUserFavorites
;
396 LPITEMIDLIST pidlCommonFavorites
;
397 CComPtr
<IShellFolder
> psfUserFavorites
;
398 CComPtr
<IShellFolder
> psfCommonFavorites
;
399 CComPtr
<IAugmentedShellFolder
> pasf
;
402 *ppsfFavorites
= NULL
;
407 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &pidlUserFavorites
);
410 WARN("Failed to get the USER favorites folder. Trying to run with just the COMMON one.\n");
412 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_COMMON_FAVORITES
, &pidlCommonFavorites
);
413 if (FAILED_UNEXPECTEDLY(hr
))
416 TRACE("COMMON favorites obtained.\n");
417 *ppidl
= pidlCommonFavorites
;
418 hr
= BindToDesktop(pidlCommonFavorites
, ppsfFavorites
);
422 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_COMMON_FAVORITES
, &pidlCommonFavorites
);
423 if (FAILED_UNEXPECTEDLY(hr
))
425 WARN("Failed to get the COMMON favorites folder. Will use only the USER contents.\n");
426 *ppidl
= pidlCommonFavorites
;
427 hr
= BindToDesktop(pidlUserFavorites
, ppsfFavorites
);
431 TRACE("Both COMMON and USER favorites folders obtained, merging them...\n");
433 hr
= BindToDesktop(pidlUserFavorites
, &psfUserFavorites
);
434 if (FAILED_UNEXPECTEDLY(hr
))
437 hr
= BindToDesktop(pidlCommonFavorites
, &psfCommonFavorites
);
438 if (FAILED_UNEXPECTEDLY(hr
))
441 hr
= CMergedFolder_CreateInstance(IID_PPV_ARG(IAugmentedShellFolder
, &pasf
));
442 if (FAILED_UNEXPECTEDLY(hr
))
444 *ppsfFavorites
= psfUserFavorites
.Detach();
445 *ppidl
= pidlUserFavorites
;
446 ILFree(pidlCommonFavorites
);
450 hr
= pasf
->AddNameSpace(NULL
, psfUserFavorites
, pidlUserFavorites
, 0xFF00);
451 if (FAILED_UNEXPECTEDLY(hr
))
454 hr
= pasf
->AddNameSpace(NULL
, psfCommonFavorites
, pidlCommonFavorites
, 0);
455 if (FAILED_UNEXPECTEDLY(hr
))
458 hr
= pasf
->QueryInterface(IID_PPV_ARG(IShellFolder
, ppsfFavorites
));
461 // TODO: obtain the folder's PIDL
463 ILFree(pidlCommonFavorites
);
464 ILFree(pidlUserFavorites
);
469 HRESULT STDMETHODCALLTYPE
CMenuCallback::GetObject(LPSMDATA psmd
, REFIID riid
, void **ppvObject
)
471 CComPtr
<IShellMenu
> parentMenu
;
472 CComPtr
<IShellMenu
> newMenu
;
473 CComPtr
<IShellFolder
> favoritesFolder
;
474 LPITEMIDLIST favoritesPIDL
;
477 HMENU favoritesHMenu
;
481 static const TCHAR szFavoritesKey
[] =
482 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
484 if (!IsEqualIID(riid
, IID_IShellMenu
))
486 if (psmd
->uId
!= FCIDM_MENU_FAVORITES
)
489 // create favorites menu
490 hResult
= psmd
->punk
->QueryInterface(IID_PPV_ARG(IShellMenu
, &parentMenu
));
491 if (FAILED_UNEXPECTEDLY(hResult
))
493 hResult
= parentMenu
->GetMenu(&parentHMenu
, &ownerWindow
, NULL
);
494 if (FAILED_UNEXPECTEDLY(hResult
))
496 favoritesHMenu
= GetSubMenu(parentHMenu
, 3);
497 if (favoritesHMenu
== NULL
)
500 if (fFavoritesMenu
.p
== NULL
)
502 hResult
= CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu
, &newMenu
));
503 if (FAILED_UNEXPECTEDLY(hResult
))
505 hResult
= newMenu
->Initialize(this, FCIDM_MENU_FAVORITES
, -1, SMINIT_VERTICAL
| SMINIT_CACHED
);
506 if (FAILED_UNEXPECTEDLY(hResult
))
509 RegCreateKeyEx(HKEY_CURRENT_USER
, szFavoritesKey
,
510 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &orderRegKey
, &disposition
);
512 hResult
= GetFavoritesFolder(&favoritesFolder
, &favoritesPIDL
);
513 if (FAILED_UNEXPECTEDLY(hResult
))
516 hResult
= newMenu
->SetShellFolder(favoritesFolder
, favoritesPIDL
, orderRegKey
, SMSET_BOTTOM
| SMINIT_CACHED
| SMINV_ID
);
518 ILFree(favoritesPIDL
);
523 fFavoritesMenu
= newMenu
;
526 hResult
= fFavoritesMenu
->SetMenu(favoritesHMenu
, ownerWindow
, SMSET_TOP
| SMSET_DONTOWN
);
527 if (FAILED_UNEXPECTEDLY(hResult
))
530 return fFavoritesMenu
->QueryInterface(riid
, ppvObject
);
533 HRESULT STDMETHODCALLTYPE
CMenuCallback::CallbackSM(LPSMDATA psmd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
545 SMINFO
*infoPtr
= reinterpret_cast<SMINFO
*>(lParam
);
546 if ((infoPtr
->dwMask
& SMIM_FLAGS
) != 0)
548 if (psmd
->uId
== FCIDM_MENU_FAVORITES
)
550 infoPtr
->dwFlags
|= SMIF_DROPCASCADE
;
554 infoPtr
->dwFlags
|= SMIF_TRACKPOPUP
;
557 if ((infoPtr
->dwMask
& SMIM_ICON
) != 0)
564 return GetObject(psmd
, *reinterpret_cast<IID
*>(wParam
), reinterpret_cast<void **>(lParam
));
565 case SMC_GETSFOBJECT
:
568 PostMessageW(psmd
->hwnd
, WM_COMMAND
, psmd
->uId
, 0);
571 SHInvokeDefaultCommand(psmd
->hwnd
, psmd
->psf
, psmd
->pidlItem
);
573 case SMC_SFSELECTITEM
:
586 case SMC_DEFAULTICON
:
590 case SMC_CHEVRONEXPAND
:
592 case SMC_DISPLAYCHEVRONTIP
:
594 case SMC_SETSFOBJECT
:
596 case SMC_SHCHANGENOTIFY
:
598 case SMC_CHEVRONGETTIP
:
600 case SMC_SFDDRESTRICTED
:
612 CInternetToolbar::CInternetToolbar()
616 fMenuBandWindow
= NULL
;
617 fNavigationWindow
= NULL
;
618 fMenuCallback
= new CComObject
<CMenuCallback
>();
619 fToolbarWindow
= NULL
;
622 fMenuCallback
->AddRef();
625 CInternetToolbar::~CInternetToolbar()
629 void CInternetToolbar::AddDockItem(IUnknown
*newItem
, int bandID
, int flags
)
631 CComPtr
<CDockSite
> newSite
;
633 newSite
= new CComObject
<CDockSite
>;
634 newSite
->Initialize(newItem
, this, fMainReBar
, bandID
, flags
);
637 HRESULT
CInternetToolbar::ReserveBorderSpace(LONG maxHeight
)
639 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
640 RECT availableBorderSpace
;
642 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
643 if (FAILED_UNEXPECTEDLY(hResult
))
645 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDockingWindow
*>(this), &availableBorderSpace
);
646 if (FAILED_UNEXPECTEDLY(hResult
))
649 if (maxHeight
&& availableBorderSpace
.bottom
- availableBorderSpace
.top
> maxHeight
)
651 availableBorderSpace
.bottom
= availableBorderSpace
.top
+ maxHeight
;
654 return ResizeBorderDW(&availableBorderSpace
, fSite
, FALSE
);
657 HRESULT
CInternetToolbar::CreateMenuBar(IShellMenu
**pMenuBar
)
659 CComPtr
<IShellMenu
> menubar
;
660 CComPtr
<IShellMenuCallback
> callback
;
670 hResult
= CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu
, &menubar
));
671 if (FAILED_UNEXPECTEDLY(hResult
))
674 hResult
= fMenuCallback
->QueryInterface(IID_PPV_ARG(IShellMenuCallback
, &callback
));
675 if (FAILED_UNEXPECTEDLY(hResult
))
678 hResult
= menubar
->Initialize(callback
, -1, ANCESTORDEFAULT
, SMINIT_HORIZONTAL
| SMINIT_TOPLEVEL
);
679 if (FAILED_UNEXPECTEDLY(hResult
))
684 hResult
= IUnknown_Exec(fSite
, CGID_Explorer
, 0x35, 0, NULL
, &menuOut
);
685 if (FAILED_UNEXPECTEDLY(hResult
))
688 if (V_VT(&menuOut
) != VT_INT_PTR
|| V_INTREF(&menuOut
) == NULL
)
691 hResult
= IUnknown_GetWindow(fSite
, &ownerWindow
);
692 if (FAILED_UNEXPECTEDLY(hResult
))
695 HMENU hMenuBar
= (HMENU
) V_INTREF(&menuOut
);
697 // FIXME: Figure out the proper way to do this.
698 HMENU hMenuFavs
= GetSubMenu(hMenuBar
, 3);
701 DeleteMenu(hMenuFavs
, IDM_FAVORITES_EMPTY
, MF_BYCOMMAND
);
704 hResult
= menubar
->SetMenu(hMenuBar
, ownerWindow
, SMSET_DONTOWN
);
705 if (FAILED_UNEXPECTEDLY(hResult
))
709 hResult
= IUnknown_Exec(menubar
, CGID_MenuBand
, 3, 1, NULL
, NULL
);
710 if (FAILED_UNEXPECTEDLY(hResult
))
713 *pMenuBar
= menubar
.Detach();
718 HRESULT
CInternetToolbar::LockUnlockToolbars(bool locked
)
720 REBARBANDINFOW rebarBandInfo
;
725 if (locked
!= fLocked
)
728 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
729 rebarBandInfo
.fMask
= RBBIM_STYLE
| RBBIM_LPARAM
;
730 bandCount
= (int)SendMessage(fMainReBar
, RB_GETBANDCOUNT
, 0, 0);
731 for (INT x
= 0; x
< bandCount
; x
++)
733 SendMessage(fMainReBar
, RB_GETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
734 dockSite
= reinterpret_cast<CDockSite
*>(rebarBandInfo
.lParam
);
735 if (dockSite
!= NULL
)
737 rebarBandInfo
.fStyle
&= ~(RBBS_NOGRIPPER
| RBBS_GRIPPERALWAYS
);
738 if (dockSite
->fFlags
& CDockSite::ITF_NOGRIPPER
|| fLocked
)
739 rebarBandInfo
.fStyle
|= RBBS_NOGRIPPER
;
740 if (dockSite
->fFlags
& CDockSite::ITF_GRIPPERALWAYS
&& !fLocked
)
741 rebarBandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
742 SendMessage(fMainReBar
, RB_SETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
745 hResult
= ReserveBorderSpace(0);
747 // TODO: refresh view menu?
752 HRESULT
CInternetToolbar::CommandStateChanged(bool newValue
, int commandID
)
760 // loop through buttons
761 //for buttons in CLSID_CommonButtons
762 // if up, QueryStatus for up state and update it
764 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
768 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_FORWARD
, newValue
? TBSTATE_ENABLED
: 0);
772 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_BACK
, newValue
? TBSTATE_ENABLED
: 0);
776 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_UPONELEVEL
, newValue
? TBSTATE_ENABLED
: 0);
782 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
784 CComPtr
<IServiceProvider
> serviceProvider
;
787 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
788 if (FAILED_UNEXPECTEDLY(hResult
))
790 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
791 if (FAILED_UNEXPECTEDLY(hResult
))
793 hResult
= CBandProxy_CreateInstance(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
794 if (FAILED_UNEXPECTEDLY(hResult
))
796 hResult
= fBandProxy
->SetSite(fSite
);
797 if (FAILED_UNEXPECTEDLY(hResult
))
803 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
808 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
810 HRESULT hr
= S_FALSE
;
813 hr
= IUnknown_HasFocusIO(fMenuBar
);
818 hr
= IUnknown_HasFocusIO(fControlsBar
);
823 hr
= IUnknown_HasFocusIO(fNavigationBar
);
830 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
832 HRESULT hr
= S_FALSE
;
835 hr
= IUnknown_TranslateAcceleratorIO(fMenuBar
, lpMsg
);
840 hr
= IUnknown_TranslateAcceleratorIO(fControlsBar
, lpMsg
);
845 hr
= IUnknown_TranslateAcceleratorIO(fNavigationBar
, lpMsg
);
852 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
860 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
865 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
872 hResult
= ReserveBorderSpace();
873 if (FAILED_UNEXPECTEDLY(hResult
))
879 hResult
= IUnknown_ShowDW(fMenuBar
, fShow
);
880 if (FAILED_UNEXPECTEDLY(hResult
))
886 hResult
= IUnknown_ShowDW(fControlsBar
, fShow
);
887 if (FAILED_UNEXPECTEDLY(hResult
))
892 hResult
= IUnknown_ShowDW(fNavigationBar
, fShow
);
893 if (FAILED_UNEXPECTEDLY(hResult
))
898 hResult
= IUnknown_ShowDW(fLogoBar
, fShow
);
899 if (FAILED_UNEXPECTEDLY(hResult
))
905 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
911 hResult
= IUnknown_CloseDW(fMenuBar
, dwReserved
);
912 if (FAILED_UNEXPECTEDLY(hResult
))
914 ReleaseCComPtrExpectZero(fMenuBar
);
918 hResult
= IUnknown_CloseDW(fControlsBar
, dwReserved
);
919 if (FAILED_UNEXPECTEDLY(hResult
))
921 ReleaseCComPtrExpectZero(fControlsBar
);
925 hResult
= IUnknown_CloseDW(fNavigationBar
, dwReserved
);
926 if (FAILED_UNEXPECTEDLY(hResult
))
928 ReleaseCComPtrExpectZero(fNavigationBar
);
932 hResult
= IUnknown_CloseDW(fLogoBar
, dwReserved
);
933 if (FAILED_UNEXPECTEDLY(hResult
))
935 ReleaseCComPtrExpectZero(fLogoBar
);
942 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
943 IUnknown
*punkToolbarSite
, BOOL fReserved
)
945 RECT neededBorderSpace
;
946 RECT availableBorderSpace
= *prcBorder
;
948 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
950 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
951 // Let's make sure we fetch the actual size properly.
952 ::GetWindowRect(fMainReBar
, &availableBorderSpace
);
953 neededBorderSpace
.left
= 0;
954 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
956 neededBorderSpace
.top
+= 3;
957 neededBorderSpace
.right
= 0;
958 neededBorderSpace
.bottom
= 0;
960 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
962 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
963 if (FAILED_UNEXPECTEDLY(hResult
))
966 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
967 if (FAILED_UNEXPECTEDLY(hResult
))
970 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
971 if (FAILED_UNEXPECTEDLY(hResult
))
977 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
979 if (pClassID
== NULL
)
981 *pClassID
= CLSID_InternetToolbar
;
985 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
990 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
995 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
1000 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1005 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
1007 CComPtr
<IShellMenu
> menuBar
;
1008 CComPtr
<IUnknown
> logoBar
;
1009 CComPtr
<IUnknown
> toolsBar
;
1010 CComPtr
<IUnknown
> navigationBar
;
1013 /* Create and attach the menubar to the rebar */
1014 hResult
= CreateMenuBar(&menuBar
);
1015 if (FAILED_UNEXPECTEDLY(hResult
))
1017 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1019 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
1020 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1022 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1023 // and it will put them in their own row, sized to take up the whole row.
1025 /* Create and attach the brand/logo to the rebar */
1026 hResult
= CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown
, &logoBar
));
1027 if (FAILED_UNEXPECTEDLY(hResult
))
1029 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1030 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1033 /* Create and attach the standard toolbar to the rebar */
1034 hResult
= CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown
, &toolsBar
));
1035 if (FAILED_UNEXPECTEDLY(hResult
))
1037 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1038 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1039 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1040 if (FAILED_UNEXPECTEDLY(hResult
))
1043 /* Create and attach the address/navigation toolbar to the rebar */
1044 hResult
= CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown
, &navigationBar
));
1045 if (FAILED_UNEXPECTEDLY(hResult
))
1047 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1048 fNavigationBar
.Attach(navigationBar
.Detach());
1049 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1054 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1055 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1057 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1061 switch (prgCmds
->cmdID
)
1063 case ITID_TEXTLABELS
: // Text Labels state
1064 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1066 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1067 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1069 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1071 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1072 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1074 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1076 case ITID_LINKSBANDSHOWN
: // links bar visibility
1079 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1080 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1082 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1084 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1087 case ITID_CUSTOMIZEENABLED
: // customize enabled
1088 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1090 case ITID_TOOLBARLOCKED
: // lock toolbars
1091 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1093 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1107 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1108 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1110 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1115 // what do I do here?
1117 case ITID_TEXTLABELS
:
1118 // toggle text labels
1120 case ITID_TOOLBARBANDSHOWN
:
1121 // toggle toolbar band visibility
1123 case ITID_ADDRESSBANDSHOWN
:
1124 // toggle address band visibility
1126 case ITID_LINKSBANDSHOWN
:
1127 // toggle links band visibility
1129 case ITID_CUSTOMIZEENABLED
:
1132 case ITID_TOOLBARLOCKED
:
1133 return LockUnlockToolbars(!fLocked
);
1139 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1144 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1149 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1150 LCID lcid
, DISPID
*rgDispId
)
1155 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1156 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1160 switch(dispIdMember
)
1162 case DISPID_BEFORENAVIGATE
:
1165 case DISPID_DOWNLOADCOMPLETE
:
1168 case DISPID_COMMANDSTATECHANGE
:
1169 if (pDispParams
->cArgs
!= 2)
1170 return E_INVALIDARG
;
1171 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1172 return E_INVALIDARG
;
1173 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1174 V_I4(&pDispParams
->rgvarg
[1]));
1175 case DISPID_DOWNLOADBEGIN
:
1178 case DISPID_NAVIGATECOMPLETE2
:
1181 case DISPID_DOCUMENTCOMPLETE
:
1188 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1192 TRACE("SetCommandTarget %p category %s param %d\n", theTarget
, wine_dbgstr_guid(category
), param14
);
1194 fCommandTarget
.Release();
1195 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1196 if (FAILED_UNEXPECTEDLY(hResult
))
1198 fCommandCategory
= *category
;
1202 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1207 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1212 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1213 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1217 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1218 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1225 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1230 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1232 if (theState
== NULL
)
1234 // map the command id
1235 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1239 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1241 // map the command id
1242 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1246 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1247 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1252 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1256 *paramC
= MAKELONG(24, 24);
1260 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1261 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1266 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1267 HIMAGELIST param14
, HIMAGELIST param18
)
1272 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1277 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1282 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1284 CComPtr
<IBrowserService
> browserService
;
1289 if (pUnkSite
== NULL
)
1291 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1292 ::DestroyWindow(fMainReBar
);
1298 // get window handle of owner
1299 hResult
= IUnknown_GetWindow(pUnkSite
, &ownerWindow
);
1300 if (FAILED_UNEXPECTEDLY(hResult
))
1302 if (ownerWindow
== NULL
)
1305 // create dock container
1307 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1308 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1309 if (dockContainer
== NULL
)
1311 SubclassWindow(dockContainer
);
1313 // create rebar in dock container
1314 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1315 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1316 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1317 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1318 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1319 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1320 if (fMainReBar
== NULL
)
1323 // take advice to watch events
1324 hResult
= IUnknown_QueryService(pUnkSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1325 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1330 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1332 if (ppvSite
== NULL
)
1334 if (fSite
.p
!= NULL
)
1335 return fSite
->QueryInterface(riid
, ppvSite
);
1340 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1344 if (IsEqualIID(guidService
, IID_IBandSite
))
1345 return this->QueryInterface(riid
, ppvObject
);
1346 if (IsEqualIID(guidService
, SID_IBandProxy
))
1348 if (fBandProxy
.p
== NULL
)
1350 hResult
= CreateAndInitBandProxy();
1351 if (FAILED_UNEXPECTEDLY(hResult
))
1354 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1356 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1359 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1360 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1366 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1367 if (hResult
!= S_FALSE
)
1373 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1374 if (hResult
!= S_FALSE
)
1380 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1381 if (hResult
!= S_FALSE
)
1388 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1394 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1400 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1406 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1407 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1411 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1412 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1413 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1414 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1419 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1425 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1431 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1437 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1443 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1449 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1451 CComPtr
<IWebBrowser
> webBrowser
;
1454 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1455 if (FAILED_UNEXPECTEDLY(hResult
))
1457 hResult
= webBrowser
->GoBack();
1461 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1463 CComPtr
<IWebBrowser
> webBrowser
;
1466 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1467 if (FAILED_UNEXPECTEDLY(hResult
))
1469 hResult
= webBrowser
->GoForward();
1473 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1475 IUnknown_Exec(fSite
, CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1479 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1481 return IUnknown_Exec(fSite
, CLSID_CommonButtons
, 0x123, 1, NULL
, NULL
);
1484 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1486 IUnknown_Exec(fSite
, CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1490 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1494 if (fCommandTarget
.p
!= NULL
)
1496 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1501 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1503 CComPtr
<IBrowserService
> browserService
;
1504 CComPtr
<IOleCommandTarget
> commandTarget
;
1505 CComPtr
<ITravelLog
> travelLog
;
1506 NMTOOLBARW
*notifyInfo
;
1514 wchar_t templateString
[200];
1516 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1517 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1519 // not from the toolbar, keep looking for a message handler
1523 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1524 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1525 switch (notifyInfo
->iItem
)
1528 newMenu
= CreatePopupMenu();
1529 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1530 hResult
= browserService
->GetTravelLog(&travelLog
);
1531 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1532 commandInfo
.cmdID
= 0x1d;
1533 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1534 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1535 travelLog
->CountEntries(browserService
) > 1)
1537 AppendMenuW(newMenu
, MF_SEPARATOR
, -1, L
"");
1539 if (LoadStringW(_AtlBaseModule
.GetResourceInstance(),
1540 IDS_HISTORYTEXT
, templateString
, sizeof(templateString
) / sizeof(wchar_t)) == 0)
1541 StringCbCopyW(templateString
, sizeof(templateString
), L
"&History\tCtrl+H");
1543 AppendMenuW(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, templateString
);
1545 params
.cbSize
= sizeof(params
);
1546 params
.rcExclude
= bounds
;
1547 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1548 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1549 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1551 V_VT(&parmIn
) = VT_I4
;
1553 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1555 else if (selectedItem
!= 0)
1556 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1557 DestroyMenu(newMenu
);
1559 case IDM_GOTO_FORWARD
:
1560 newMenu
= CreatePopupMenu();
1561 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1562 hResult
= browserService
->GetTravelLog(&travelLog
);
1563 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1564 commandInfo
.cmdID
= 0x1d;
1565 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1566 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1567 travelLog
->CountEntries(browserService
) > 1)
1569 AppendMenuW(newMenu
, MF_SEPARATOR
, -1, L
"");
1571 if (LoadStringW(_AtlBaseModule
.GetResourceInstance(),
1572 IDS_HISTORYTEXT
, templateString
, sizeof(templateString
) / sizeof(wchar_t)) == 0)
1573 StringCbCopyW(templateString
, sizeof(templateString
), L
"&History\tCtrl+H");
1575 AppendMenuW(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, templateString
);
1577 params
.cbSize
= sizeof(params
);
1578 params
.rcExclude
= bounds
;
1579 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1580 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1581 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1583 V_VT(&parmIn
) = VT_I4
;
1585 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1587 else if (selectedItem
!= 0)
1588 hResult
= travelLog
->Travel(browserService
, selectedItem
);
1589 DestroyMenu(newMenu
);
1591 case gViewsCommandID
:
1593 CComVariant outValue
;
1596 V_VT(&inValue
) = VT_INT_PTR
;
1597 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1599 if (fCommandTarget
.p
!= NULL
)
1600 hResult
= fCommandTarget
->Exec(&fCommandCategory
, FCIDM_SHVIEW_AUTOARRANGE
, 1, &inValue
, &outValue
);
1601 // pvaOut is VT_I4 with value 0x403
1604 return TBDDRET_DEFAULT
;
1607 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1612 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1617 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1619 HMENU contextMenuBar
;
1621 POINT clickLocation
;
1623 RBHITTESTINFO hitTestInfo
;
1624 REBARBANDINFOW rebarBandInfo
;
1626 BOOL goButtonChecked
;
1628 clickLocation
.x
= LOWORD(lParam
);
1629 clickLocation
.y
= HIWORD(lParam
);
1630 hitTestInfo
.pt
= clickLocation
;
1631 ScreenToClient(&hitTestInfo
.pt
);
1632 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1633 if (hitTestInfo
.iBand
== -1)
1635 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1636 rebarBandInfo
.fMask
= RBBIM_ID
;
1637 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1638 bandID
= rebarBandInfo
.wID
;
1639 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1640 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1643 case ITBBID_MENUBAND
: // menu band
1644 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1645 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1646 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1648 case ITBBID_BRANDBAND
: // brand band
1649 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1650 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1651 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1653 case ITBBID_TOOLSBAND
: // tools band
1654 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1655 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1657 case ITBBID_ADDRESSBAND
: // navigation band
1658 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1659 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1665 // TODO: Implement show/hide toolbars
1666 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, FALSE
);
1667 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, FALSE
);
1668 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1669 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1671 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, fControlsBar
!= NULL
);
1672 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, fNavigationBar
!= NULL
);
1673 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1674 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1675 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, fLocked
);
1676 goButtonChecked
= SHRegGetBoolUSValueW(L
"Software\\Microsoft\\Internet Explorer\\Main", L
"ShowGoButton", FALSE
, TRUE
);
1677 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_GOBUTTON
, goButtonChecked
);
1679 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1680 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1681 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1684 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1686 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1688 case IDM_TOOLBARS_LINKSBAR
: // links
1690 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1691 LockUnlockToolbars(!fLocked
);
1693 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1694 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1696 case IDM_TOOLBARS_GOBUTTON
:
1697 SendMessage(fNavigationWindow
, WM_COMMAND
, IDM_TOOLBARS_GOBUTTON
, 0);
1701 DestroyMenu(contextMenuBar
);
1705 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1707 if (wParam
!= SIZE_MINIMIZED
)
1709 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1710 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1715 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1717 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1722 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1726 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1728 CComPtr
<IBrowserService
> browserService
;
1729 CComPtr
<ITravelLog
> travelLog
;
1730 TOOLTIPTEXTW
*pTTTW
;
1733 wchar_t tempString
[300];
1735 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1736 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1737 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1739 nID
= (UINT
)pNMHDR
->idFrom
;
1743 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1745 // TODO: Should this call QueryService?
1746 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1747 hResult
= browserService
->GetTravelLog(&travelLog
);
1748 hResult
= travelLog
->GetToolTipText(browserService
,
1749 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1750 0, tempString
, 299);
1751 if (FAILED_UNEXPECTEDLY(hResult
))
1759 wcsncpy (pTTTW
->szText
, tempString
, sizeof(pTTTW
->szText
) / sizeof(wchar_t));
1760 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1761 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1767 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1772 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1774 bHandled
= hResult
== S_OK
;
1776 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1778 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1780 NMHDR
*notifyHeader
;
1784 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1786 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1788 bHandled
= hResult
== S_OK
;
1790 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1793 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1799 if (wParam
& MK_CONTROL
)
1804 DWORD msgp
= GetMessagePos();
1806 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1807 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1812 fStartHeight
= rc
.bottom
- rc
.top
;
1820 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1826 DWORD msgp
= GetMessagePos();
1829 pt
.x
= GET_X_LPARAM(msgp
);
1830 pt
.y
= GET_Y_LPARAM(msgp
);
1832 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1838 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1844 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);