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
);
940 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
941 IUnknown
*punkToolbarSite
, BOOL fReserved
)
943 RECT neededBorderSpace
;
944 RECT availableBorderSpace
= *prcBorder
;
946 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
948 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
949 // Let's make sure we fetch the actual size properly.
950 ::GetWindowRect(fMainReBar
, &availableBorderSpace
);
951 neededBorderSpace
.left
= 0;
952 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
954 neededBorderSpace
.top
+= 3;
955 neededBorderSpace
.right
= 0;
956 neededBorderSpace
.bottom
= 0;
958 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
960 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
961 if (FAILED_UNEXPECTEDLY(hResult
))
964 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
965 if (FAILED_UNEXPECTEDLY(hResult
))
968 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
969 if (FAILED_UNEXPECTEDLY(hResult
))
975 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
977 if (pClassID
== NULL
)
979 *pClassID
= CLSID_InternetToolbar
;
983 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
988 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
993 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
998 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1003 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
1005 CComPtr
<IShellMenu
> menuBar
;
1006 CComPtr
<IUnknown
> logoBar
;
1007 CComPtr
<IUnknown
> toolsBar
;
1008 CComPtr
<IUnknown
> navigationBar
;
1011 /* Create and attach the menubar to the rebar */
1012 hResult
= CreateMenuBar(&menuBar
);
1013 if (FAILED_UNEXPECTEDLY(hResult
))
1015 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1017 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
1018 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1020 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1021 // and it will put them in their own row, sized to take up the whole row.
1023 /* Create and attach the brand/logo to the rebar */
1024 hResult
= CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown
, &logoBar
));
1025 if (FAILED_UNEXPECTEDLY(hResult
))
1027 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1028 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1031 /* Create and attach the standard toolbar to the rebar */
1032 hResult
= CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown
, &toolsBar
));
1033 if (FAILED_UNEXPECTEDLY(hResult
))
1035 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1036 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1037 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1038 if (FAILED_UNEXPECTEDLY(hResult
))
1041 /* Create and attach the address/navigation toolbar to the rebar */
1042 hResult
= CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown
, &navigationBar
));
1043 if (FAILED_UNEXPECTEDLY(hResult
))
1045 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1046 fNavigationBar
.Attach(navigationBar
.Detach());
1047 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1052 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1053 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1055 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1059 switch (prgCmds
->cmdID
)
1061 case ITID_TEXTLABELS
: // Text Labels state
1062 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1064 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1065 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1067 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1069 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1070 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1072 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1074 case ITID_LINKSBANDSHOWN
: // links bar visibility
1077 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1078 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1080 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1082 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1085 case ITID_CUSTOMIZEENABLED
: // customize enabled
1086 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1088 case ITID_TOOLBARLOCKED
: // lock toolbars
1089 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1091 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1105 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1106 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1108 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1113 // what do I do here?
1115 case ITID_TEXTLABELS
:
1116 // toggle text labels
1118 case ITID_TOOLBARBANDSHOWN
:
1119 // toggle toolbar band visibility
1121 case ITID_ADDRESSBANDSHOWN
:
1122 // toggle address band visibility
1124 case ITID_LINKSBANDSHOWN
:
1125 // toggle links band visibility
1127 case ITID_CUSTOMIZEENABLED
:
1130 case ITID_TOOLBARLOCKED
:
1131 return LockUnlockToolbars(!fLocked
);
1137 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1142 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1147 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1148 LCID lcid
, DISPID
*rgDispId
)
1153 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1154 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1158 switch(dispIdMember
)
1160 case DISPID_BEFORENAVIGATE
:
1163 case DISPID_DOWNLOADCOMPLETE
:
1166 case DISPID_COMMANDSTATECHANGE
:
1167 if (pDispParams
->cArgs
!= 2)
1168 return E_INVALIDARG
;
1169 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1170 return E_INVALIDARG
;
1171 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1172 V_I4(&pDispParams
->rgvarg
[1]));
1173 case DISPID_DOWNLOADBEGIN
:
1176 case DISPID_NAVIGATECOMPLETE2
:
1179 case DISPID_DOCUMENTCOMPLETE
:
1186 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1190 TRACE("SetCommandTarget %p category %s param %d\n", theTarget
, wine_dbgstr_guid(category
), param14
);
1192 fCommandTarget
.Release();
1193 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1194 if (FAILED_UNEXPECTEDLY(hResult
))
1196 fCommandCategory
= *category
;
1200 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1205 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1210 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1211 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1215 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1216 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1223 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1228 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1230 if (theState
== NULL
)
1232 // map the command id
1233 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1237 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1239 // map the command id
1240 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1244 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1245 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1250 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1254 *paramC
= MAKELONG(24, 24);
1258 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1259 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1264 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1265 HIMAGELIST param14
, HIMAGELIST param18
)
1270 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1275 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1280 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1282 CComPtr
<IBrowserService
> browserService
;
1287 if (pUnkSite
== NULL
)
1289 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1290 ::DestroyWindow(fMainReBar
);
1296 // get window handle of owner
1297 hResult
= IUnknown_GetWindow(pUnkSite
, &ownerWindow
);
1298 if (FAILED_UNEXPECTEDLY(hResult
))
1300 if (ownerWindow
== NULL
)
1303 // create dock container
1305 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1306 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1307 if (dockContainer
== NULL
)
1309 SubclassWindow(dockContainer
);
1311 // create rebar in dock container
1312 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1313 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1314 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1315 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1316 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1317 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1318 if (fMainReBar
== NULL
)
1321 // take advice to watch events
1322 hResult
= IUnknown_QueryService(pUnkSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1323 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1328 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1330 if (ppvSite
== NULL
)
1332 if (fSite
.p
!= NULL
)
1333 return fSite
->QueryInterface(riid
, ppvSite
);
1338 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1342 if (IsEqualIID(guidService
, IID_IBandSite
))
1343 return this->QueryInterface(riid
, ppvObject
);
1344 if (IsEqualIID(guidService
, SID_IBandProxy
))
1346 if (fBandProxy
.p
== NULL
)
1348 hResult
= CreateAndInitBandProxy();
1349 if (FAILED_UNEXPECTEDLY(hResult
))
1352 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1354 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1357 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1358 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1364 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1365 if (hResult
!= S_FALSE
)
1371 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1372 if (hResult
!= S_FALSE
)
1378 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1379 if (hResult
!= S_FALSE
)
1386 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1392 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1398 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1404 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1405 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1409 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1410 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1411 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1412 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1417 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1423 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1429 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1435 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1441 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1447 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1449 CComPtr
<IWebBrowser
> webBrowser
;
1452 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1453 if (FAILED_UNEXPECTEDLY(hResult
))
1455 hResult
= webBrowser
->GoBack();
1459 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1461 CComPtr
<IWebBrowser
> webBrowser
;
1464 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1465 if (FAILED_UNEXPECTEDLY(hResult
))
1467 hResult
= webBrowser
->GoForward();
1471 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1473 IUnknown_Exec(fSite
, CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1477 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1479 return IUnknown_Exec(fSite
, CLSID_CommonButtons
, 0x123, 1, NULL
, NULL
);
1482 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1484 IUnknown_Exec(fSite
, CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1488 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1492 if (fCommandTarget
.p
!= NULL
)
1494 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1499 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1501 CComPtr
<IBrowserService
> browserService
;
1502 CComPtr
<IOleCommandTarget
> commandTarget
;
1503 CComPtr
<ITravelLog
> travelLog
;
1504 NMTOOLBARW
*notifyInfo
;
1512 wchar_t templateString
[200];
1514 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1515 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1517 // not from the toolbar, keep looking for a message handler
1521 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1522 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1523 switch (notifyInfo
->iItem
)
1526 newMenu
= CreatePopupMenu();
1527 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1528 hResult
= browserService
->GetTravelLog(&travelLog
);
1529 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1530 commandInfo
.cmdID
= 0x1d;
1531 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1532 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1533 travelLog
->CountEntries(browserService
) > 1)
1535 AppendMenuW(newMenu
, MF_SEPARATOR
, -1, L
"");
1537 if (LoadStringW(_AtlBaseModule
.GetResourceInstance(),
1538 IDS_HISTORYTEXT
, templateString
, sizeof(templateString
) / sizeof(wchar_t)) == 0)
1539 StringCbCopyW(templateString
, sizeof(templateString
), L
"&History\tCtrl+H");
1541 AppendMenuW(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, templateString
);
1543 params
.cbSize
= sizeof(params
);
1544 params
.rcExclude
= bounds
;
1545 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1546 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1547 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1549 V_VT(&parmIn
) = VT_I4
;
1551 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1553 else if (selectedItem
!= 0)
1554 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1555 DestroyMenu(newMenu
);
1557 case IDM_GOTO_FORWARD
:
1558 newMenu
= CreatePopupMenu();
1559 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1560 hResult
= browserService
->GetTravelLog(&travelLog
);
1561 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1562 commandInfo
.cmdID
= 0x1d;
1563 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1564 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1565 travelLog
->CountEntries(browserService
) > 1)
1567 AppendMenuW(newMenu
, MF_SEPARATOR
, -1, L
"");
1569 if (LoadStringW(_AtlBaseModule
.GetResourceInstance(),
1570 IDS_HISTORYTEXT
, templateString
, sizeof(templateString
) / sizeof(wchar_t)) == 0)
1571 StringCbCopyW(templateString
, sizeof(templateString
), L
"&History\tCtrl+H");
1573 AppendMenuW(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, templateString
);
1575 params
.cbSize
= sizeof(params
);
1576 params
.rcExclude
= bounds
;
1577 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1578 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1579 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1581 V_VT(&parmIn
) = VT_I4
;
1583 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1585 else if (selectedItem
!= 0)
1586 hResult
= travelLog
->Travel(browserService
, selectedItem
);
1587 DestroyMenu(newMenu
);
1589 case gViewsCommandID
:
1591 CComVariant outValue
;
1594 V_VT(&inValue
) = VT_INT_PTR
;
1595 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1597 if (fCommandTarget
.p
!= NULL
)
1598 hResult
= fCommandTarget
->Exec(&fCommandCategory
, FCIDM_SHVIEW_AUTOARRANGE
, 1, &inValue
, &outValue
);
1599 // pvaOut is VT_I4 with value 0x403
1602 return TBDDRET_DEFAULT
;
1605 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1610 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1615 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1617 HMENU contextMenuBar
;
1619 POINT clickLocation
;
1621 RBHITTESTINFO hitTestInfo
;
1622 REBARBANDINFOW rebarBandInfo
;
1624 BOOL goButtonChecked
;
1626 clickLocation
.x
= LOWORD(lParam
);
1627 clickLocation
.y
= HIWORD(lParam
);
1628 hitTestInfo
.pt
= clickLocation
;
1629 ScreenToClient(&hitTestInfo
.pt
);
1630 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1631 if (hitTestInfo
.iBand
== -1)
1633 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1634 rebarBandInfo
.fMask
= RBBIM_ID
;
1635 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1636 bandID
= rebarBandInfo
.wID
;
1637 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1638 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1641 case ITBBID_MENUBAND
: // menu band
1642 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1643 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1644 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1646 case ITBBID_BRANDBAND
: // brand band
1647 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1648 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1649 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1651 case ITBBID_TOOLSBAND
: // tools band
1652 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1653 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1655 case ITBBID_ADDRESSBAND
: // navigation band
1656 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1657 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1663 // TODO: Implement show/hide toolbars
1664 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, FALSE
);
1665 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, FALSE
);
1666 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1667 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1669 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, fControlsBar
!= NULL
);
1670 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, fNavigationBar
!= NULL
);
1671 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1672 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1673 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, fLocked
);
1674 goButtonChecked
= SHRegGetBoolUSValueW(L
"Software\\Microsoft\\Internet Explorer\\Main", L
"ShowGoButton", FALSE
, TRUE
);
1675 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_GOBUTTON
, goButtonChecked
);
1677 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1678 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1679 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1682 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1684 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1686 case IDM_TOOLBARS_LINKSBAR
: // links
1688 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1689 LockUnlockToolbars(!fLocked
);
1691 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1692 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1694 case IDM_TOOLBARS_GOBUTTON
:
1695 SendMessage(fNavigationWindow
, WM_COMMAND
, IDM_TOOLBARS_GOBUTTON
, 0);
1699 DestroyMenu(contextMenuBar
);
1703 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1705 if (wParam
!= SIZE_MINIMIZED
)
1707 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1708 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1713 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1715 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1720 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1724 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1726 CComPtr
<IBrowserService
> browserService
;
1727 CComPtr
<ITravelLog
> travelLog
;
1728 TOOLTIPTEXTW
*pTTTW
;
1731 wchar_t tempString
[300];
1733 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1734 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1735 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1737 nID
= (UINT
)pNMHDR
->idFrom
;
1741 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1743 // TODO: Should this call QueryService?
1744 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1745 hResult
= browserService
->GetTravelLog(&travelLog
);
1746 hResult
= travelLog
->GetToolTipText(browserService
,
1747 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1748 0, tempString
, 299);
1749 if (FAILED_UNEXPECTEDLY(hResult
))
1757 wcsncpy (pTTTW
->szText
, tempString
, sizeof(pTTTW
->szText
) / sizeof(wchar_t));
1758 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1759 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1765 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1770 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1772 bHandled
= hResult
== S_OK
;
1774 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1776 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1778 NMHDR
*notifyHeader
;
1782 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1784 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1786 bHandled
= hResult
== S_OK
;
1788 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1791 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1797 if (wParam
& MK_CONTROL
)
1802 DWORD msgp
= GetMessagePos();
1804 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1805 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1810 fStartHeight
= rc
.bottom
- rc
.top
;
1818 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1824 DWORD msgp
= GetMessagePos();
1827 pt
.x
= GET_X_LPARAM(msgp
);
1828 pt
.y
= GET_Y_LPARAM(msgp
);
1830 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1836 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1842 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);