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
);
81 extern HRESULT
CreateToolsBar(REFIID riid
, void **ppv
);
82 extern HRESULT
CreateBrandBand(REFIID riid
, void **ppv
);
83 extern HRESULT
CreateBandProxy(REFIID riid
, void **ppv
);
84 extern HRESULT
CreateAddressBand(REFIID riid
, void **ppv
);
86 HRESULT
IUnknown_RelayWinEvent(IUnknown
* punk
, HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
88 CComPtr
<IWinEventHandler
> menuWinEventHandler
;
89 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &menuWinEventHandler
));
90 if (FAILED_UNEXPECTEDLY(hResult
))
92 hResult
= menuWinEventHandler
->IsWindowOwner(hWnd
);
93 if (FAILED_UNEXPECTEDLY(hResult
))
96 return menuWinEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
100 HRESULT
IUnknown_ShowDW(IUnknown
* punk
, BOOL fShow
)
102 CComPtr
<IDockingWindow
> dockingWindow
;
103 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
104 if (FAILED_UNEXPECTEDLY(hResult
))
106 hResult
= dockingWindow
->ShowDW(fShow
);
107 if (FAILED_UNEXPECTEDLY(hResult
))
112 HRESULT
IUnknown_CloseDW(IUnknown
* punk
, DWORD dwReserved
)
114 CComPtr
<IDockingWindow
> dockingWindow
;
115 HRESULT hResult
= punk
->QueryInterface(IID_PPV_ARG(IDockingWindow
, &dockingWindow
));
116 if (FAILED_UNEXPECTEDLY(hResult
))
118 hResult
= dockingWindow
->CloseDW(dwReserved
);
119 if (FAILED_UNEXPECTEDLY(hResult
))
124 class CInternetToolbar
;
127 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
128 public IDockingWindowSite
,
129 public IInputObjectSite
,
130 public IOleCommandTarget
,
131 public IServiceProvider
137 ITF_NEWBANDALWAYS
= 4,
138 ITF_GRIPPERALWAYS
= 8,
142 CComPtr
<IUnknown
> fContainedBand
; // the band inside us
143 CInternetToolbar
*fToolbar
; // our browser
151 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
152 DESKBANDINFO fDeskBandInfo
;
156 HRESULT
Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
);
157 HRESULT
GetRBBandInfo(REBARBANDINFOW
&bandInfo
);
160 // *** IOleWindow methods ***
161 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
162 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
164 // *** IDockingWindow methods ***
165 virtual HRESULT STDMETHODCALLTYPE
GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
);
166 virtual HRESULT STDMETHODCALLTYPE
RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
167 virtual HRESULT STDMETHODCALLTYPE
SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
);
169 // *** IInputObjectSite specific methods ***
170 virtual HRESULT STDMETHODCALLTYPE
OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
);
172 // *** IOleCommandTarget specific methods ***
173 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
174 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
175 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
176 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
178 // *** IServiceProvider methods ***
179 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
181 BEGIN_COM_MAP(CDockSite
)
182 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
183 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite
, IDockingWindowSite
)
184 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite
, IInputObjectSite
)
185 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
186 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
190 CDockSite::CDockSite()
197 fInitialized
= false;
198 memset(&fDeskBandInfo
, 0, sizeof(fDeskBandInfo
));
201 CDockSite::~CDockSite()
205 HRESULT
CDockSite::Initialize(IUnknown
*containedBand
, CInternetToolbar
*browser
, HWND hwnd
, int bandID
, int flags
)
207 TCHAR textBuffer
[40];
208 REBARBANDINFOW bandInfo
;
211 fContainedBand
= containedBand
;
216 hResult
= IUnknown_SetSite(containedBand
, static_cast<IOleWindow
*>(this));
217 if (FAILED_UNEXPECTEDLY(hResult
))
219 hResult
= IUnknown_GetWindow(containedBand
, &fChildWindow
);
220 if (FAILED_UNEXPECTEDLY(hResult
))
223 memset(&bandInfo
, 0, sizeof(bandInfo
));
224 bandInfo
.cbSize
= sizeof(bandInfo
);
225 bandInfo
.lpText
= textBuffer
;
226 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
227 hResult
= GetRBBandInfo(bandInfo
);
229 SendMessage(fRebarWindow
, RB_GETBANDCOUNT
, 0, 0);
230 SendMessage(fRebarWindow
, RB_INSERTBANDW
, -1, (LPARAM
)&bandInfo
);
235 HRESULT
CDockSite::GetRBBandInfo(REBARBANDINFOW
&bandInfo
)
237 CComPtr
<IDeskBand
> deskBand
;
240 hResult
= fContainedBand
->QueryInterface(IID_PPV_ARG(IDeskBand
, &deskBand
));
241 if (FAILED_UNEXPECTEDLY(hResult
))
244 fDeskBandInfo
.dwMask
= DBIM_BKCOLOR
| DBIM_MODEFLAGS
| DBIM_TITLE
| DBIM_ACTUAL
|
245 DBIM_INTEGRAL
| DBIM_MAXSIZE
| DBIM_MINSIZE
;
246 hResult
= deskBand
->GetBandInfo(fBandID
, 0, &fDeskBandInfo
);
247 // result of call is ignored
249 bandInfo
.fMask
= RBBIM_LPARAM
| RBBIM_IDEALSIZE
| RBBIM_ID
| RBBIM_CHILDSIZE
| RBBIM_CHILD
|
250 RBBIM_TEXT
| RBBIM_STYLE
;
252 bandInfo
.fStyle
= RBBS_FIXEDBMP
;
253 if (fDeskBandInfo
.dwModeFlags
& DBIMF_VARIABLEHEIGHT
)
254 bandInfo
.fStyle
|= RBBS_VARIABLEHEIGHT
;
255 if (fDeskBandInfo
.dwModeFlags
& DBIMF_USECHEVRON
)
256 bandInfo
.fStyle
|= RBBS_USECHEVRON
;
257 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BREAK
)
258 bandInfo
.fStyle
|= RBBS_BREAK
;
259 if (fDeskBandInfo
.dwModeFlags
& DBIMF_TOPALIGN
)
260 bandInfo
.fStyle
|= RBBS_TOPALIGN
;
261 if (fFlags
& ITF_NOGRIPPER
|| fToolbar
->fLocked
)
262 bandInfo
.fStyle
|= RBBS_NOGRIPPER
;
263 if (fFlags
& ITF_NOTITLE
)
264 bandInfo
.fStyle
|= RBBS_HIDETITLE
;
265 if (fFlags
& ITF_GRIPPERALWAYS
&& !fToolbar
->fLocked
)
266 bandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
267 if (fFlags
& ITF_FIXEDSIZE
)
268 bandInfo
.fStyle
|= RBBS_FIXEDSIZE
;
270 if (fDeskBandInfo
.dwModeFlags
& DBIMF_BKCOLOR
)
272 bandInfo
.fMask
|= RBBIM_COLORS
;
273 bandInfo
.clrFore
= CLR_DEFAULT
;
274 bandInfo
.clrBack
= fDeskBandInfo
.crBkgnd
;
276 wcsncpy(bandInfo
.lpText
, fDeskBandInfo
.wszTitle
, bandInfo
.cch
);
277 bandInfo
.hwndChild
= fChildWindow
;
278 bandInfo
.cxMinChild
= fDeskBandInfo
.ptMinSize
.x
;
279 bandInfo
.cyMinChild
= fDeskBandInfo
.ptMinSize
.y
;
280 bandInfo
.wID
= fBandID
;
281 bandInfo
.cyChild
= fDeskBandInfo
.ptActual
.y
;
282 bandInfo
.cyMaxChild
= fDeskBandInfo
.ptMaxSize
.y
;
283 bandInfo
.cyIntegral
= fDeskBandInfo
.ptIntegral
.y
;
284 bandInfo
.cxIdeal
= fDeskBandInfo
.ptActual
.x
;
285 bandInfo
.lParam
= reinterpret_cast<LPARAM
>(this);
289 HRESULT STDMETHODCALLTYPE
CDockSite::GetWindow(HWND
*lphwnd
)
293 *lphwnd
= fRebarWindow
;
297 HRESULT STDMETHODCALLTYPE
CDockSite::ContextSensitiveHelp(BOOL fEnterMode
)
302 HRESULT STDMETHODCALLTYPE
CDockSite::GetBorderDW(IUnknown
* punkObj
, LPRECT prcBorder
)
307 HRESULT STDMETHODCALLTYPE
CDockSite::RequestBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
312 HRESULT STDMETHODCALLTYPE
CDockSite::SetBorderSpaceDW(IUnknown
* punkObj
, LPCBORDERWIDTHS pbw
)
317 HRESULT STDMETHODCALLTYPE
CDockSite::OnFocusChangeIS (IUnknown
*punkObj
, BOOL fSetFocus
)
322 HRESULT STDMETHODCALLTYPE
CDockSite::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
,
323 OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
328 HRESULT STDMETHODCALLTYPE
CDockSite::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
,
329 VARIANT
*pvaIn
, VARIANT
*pvaOut
)
331 TCHAR textBuffer
[40];
332 REBARBANDINFOW bandInfo
;
336 if (IsEqualIID(*pguidCmdGroup
, CGID_DeskBand
))
340 case DBID_BANDINFOCHANGED
:
341 if (fInitialized
== false)
343 if (V_VT(pvaIn
) != VT_I4
)
345 if (V_I4(pvaIn
) != fBandID
)
347 // deskband information changed
348 // call GetBandInfo and refresh information in rebar
349 memset(&bandInfo
, 0, sizeof(bandInfo
));
350 bandInfo
.cbSize
= sizeof(bandInfo
);
351 bandInfo
.lpText
= textBuffer
;
352 bandInfo
.cch
= sizeof(textBuffer
) / sizeof(TCHAR
);
353 hResult
= GetRBBandInfo(bandInfo
);
354 if (FAILED_UNEXPECTEDLY(hResult
))
356 index
= (int)SendMessage(fRebarWindow
, RB_IDTOINDEX
, fBandID
, 0);
357 SendMessage(fRebarWindow
, RB_SETBANDINFOW
, index
, (LPARAM
)&bandInfo
);
364 HRESULT STDMETHODCALLTYPE
CDockSite::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
366 if (IsEqualIID(guidService
, SID_SMenuBandParent
))
367 return this->QueryInterface(riid
, ppvObject
);
369 return fToolbar
->QueryService(guidService
, riid
, ppvObject
);
372 CMenuCallback::CMenuCallback()
376 CMenuCallback::~CMenuCallback()
380 static HRESULT
BindToDesktop(LPCITEMIDLIST pidl
, IShellFolder
** ppsfResult
)
383 CComPtr
<IShellFolder
> psfDesktop
;
387 hr
= SHGetDesktopFolder(&psfDesktop
);
391 hr
= psfDesktop
->BindToObject(pidl
, NULL
, IID_PPV_ARG(IShellFolder
, ppsfResult
));
396 static HRESULT
GetFavoritesFolder(IShellFolder
** ppsfFavorites
, LPITEMIDLIST
* ppidl
)
399 LPITEMIDLIST pidlUserFavorites
;
400 LPITEMIDLIST pidlCommonFavorites
;
401 CComPtr
<IShellFolder
> psfUserFavorites
;
402 CComPtr
<IShellFolder
> psfCommonFavorites
;
403 CComPtr
<IAugmentedShellFolder
> pasf
;
406 *ppsfFavorites
= NULL
;
411 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_FAVORITES
, &pidlUserFavorites
);
414 WARN("Failed to get the USER favorites folder. Trying to run with just the COMMON one.\n");
416 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_COMMON_FAVORITES
, &pidlCommonFavorites
);
417 if (FAILED_UNEXPECTEDLY(hr
))
420 TRACE("COMMON favorites obtained.\n");
421 *ppidl
= pidlCommonFavorites
;
422 hr
= BindToDesktop(pidlCommonFavorites
, ppsfFavorites
);
426 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_COMMON_FAVORITES
, &pidlCommonFavorites
);
427 if (FAILED_UNEXPECTEDLY(hr
))
429 WARN("Failed to get the COMMON favorites folder. Will use only the USER contents.\n");
430 *ppidl
= pidlCommonFavorites
;
431 hr
= BindToDesktop(pidlUserFavorites
, ppsfFavorites
);
435 TRACE("Both COMMON and USER favorites folders obtained, merging them...\n");
437 hr
= BindToDesktop(pidlUserFavorites
, &psfUserFavorites
);
438 if (FAILED_UNEXPECTEDLY(hr
))
441 hr
= BindToDesktop(pidlCommonFavorites
, &psfCommonFavorites
);
442 if (FAILED_UNEXPECTEDLY(hr
))
445 hr
= CreateMergedFolder(IID_PPV_ARG(IAugmentedShellFolder
, &pasf
));
446 if (FAILED_UNEXPECTEDLY(hr
))
448 *ppsfFavorites
= psfUserFavorites
.Detach();
449 *ppidl
= pidlUserFavorites
;
450 ILFree(pidlCommonFavorites
);
454 hr
= pasf
->AddNameSpace(NULL
, psfUserFavorites
, pidlUserFavorites
, 0xFF00);
455 if (FAILED_UNEXPECTEDLY(hr
))
458 hr
= pasf
->AddNameSpace(NULL
, psfCommonFavorites
, pidlCommonFavorites
, 0);
459 if (FAILED_UNEXPECTEDLY(hr
))
462 hr
= pasf
->QueryInterface(IID_PPV_ARG(IShellFolder
, ppsfFavorites
));
465 // TODO: obtain the folder's PIDL
467 ILFree(pidlCommonFavorites
);
468 ILFree(pidlUserFavorites
);
473 HRESULT STDMETHODCALLTYPE
CMenuCallback::GetObject(LPSMDATA psmd
, REFIID riid
, void **ppvObject
)
475 CComPtr
<IShellMenu
> parentMenu
;
476 CComPtr
<IShellMenu
> newMenu
;
477 CComPtr
<IShellFolder
> favoritesFolder
;
478 LPITEMIDLIST favoritesPIDL
;
481 HMENU favoritesHMenu
;
485 static const TCHAR szFavoritesKey
[] =
486 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
488 if (!IsEqualIID(riid
, IID_IShellMenu
))
490 if (psmd
->uId
!= FCIDM_MENU_FAVORITES
)
493 // create favorites menu
494 hResult
= psmd
->punk
->QueryInterface(IID_PPV_ARG(IShellMenu
, &parentMenu
));
495 if (FAILED_UNEXPECTEDLY(hResult
))
497 hResult
= parentMenu
->GetMenu(&parentHMenu
, &ownerWindow
, NULL
);
498 if (FAILED_UNEXPECTEDLY(hResult
))
500 favoritesHMenu
= GetSubMenu(parentHMenu
, 3);
501 if (favoritesHMenu
== NULL
)
504 if (fFavoritesMenu
.p
== NULL
)
506 hResult
= CreateMenuBand(IID_PPV_ARG(IShellMenu
, &newMenu
));
507 if (FAILED_UNEXPECTEDLY(hResult
))
509 hResult
= newMenu
->Initialize(this, FCIDM_MENU_FAVORITES
, -1, SMINIT_VERTICAL
| SMINIT_CACHED
);
510 if (FAILED_UNEXPECTEDLY(hResult
))
513 RegCreateKeyEx(HKEY_CURRENT_USER
, szFavoritesKey
,
514 0, NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
, &orderRegKey
, &disposition
);
516 hResult
= GetFavoritesFolder(&favoritesFolder
, &favoritesPIDL
);
517 if (FAILED_UNEXPECTEDLY(hResult
))
520 hResult
= newMenu
->SetShellFolder(favoritesFolder
, favoritesPIDL
, orderRegKey
, SMSET_BOTTOM
| SMINIT_CACHED
| SMINV_ID
);
522 ILFree(favoritesPIDL
);
527 fFavoritesMenu
= newMenu
;
530 hResult
= fFavoritesMenu
->SetMenu(favoritesHMenu
, ownerWindow
, SMSET_TOP
| SMSET_DONTOWN
);
531 if (FAILED_UNEXPECTEDLY(hResult
))
534 return fFavoritesMenu
->QueryInterface(riid
, ppvObject
);
537 HRESULT STDMETHODCALLTYPE
CMenuCallback::CallbackSM(LPSMDATA psmd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
549 SMINFO
*infoPtr
= reinterpret_cast<SMINFO
*>(lParam
);
550 if ((infoPtr
->dwMask
& SMIM_FLAGS
) != 0)
552 if (psmd
->uId
== FCIDM_MENU_FAVORITES
)
554 infoPtr
->dwFlags
|= SMIF_DROPCASCADE
;
558 infoPtr
->dwFlags
|= SMIF_TRACKPOPUP
;
561 if ((infoPtr
->dwMask
& SMIM_ICON
) != 0)
568 return GetObject(psmd
, *reinterpret_cast<IID
*>(wParam
), reinterpret_cast<void **>(lParam
));
569 case SMC_GETSFOBJECT
:
572 PostMessageW(psmd
->hwnd
, WM_COMMAND
, psmd
->uId
, 0);
575 SHInvokeDefaultCommand(psmd
->hwnd
, psmd
->psf
, psmd
->pidlItem
);
577 case SMC_SFSELECTITEM
:
590 case SMC_DEFAULTICON
:
594 case SMC_CHEVRONEXPAND
:
596 case SMC_DISPLAYCHEVRONTIP
:
598 case SMC_SETSFOBJECT
:
600 case SMC_SHCHANGENOTIFY
:
602 case SMC_CHEVRONGETTIP
:
604 case SMC_SFDDRESTRICTED
:
616 CInternetToolbar::CInternetToolbar()
620 fMenuBandWindow
= NULL
;
621 fNavigationWindow
= NULL
;
622 fMenuCallback
= new CComObject
<CMenuCallback
>();
623 fToolbarWindow
= NULL
;
626 fMenuCallback
->AddRef();
629 CInternetToolbar::~CInternetToolbar()
633 void CInternetToolbar::AddDockItem(IUnknown
*newItem
, int bandID
, int flags
)
635 CComPtr
<CDockSite
> newSite
;
637 newSite
= new CComObject
<CDockSite
>;
638 newSite
->Initialize(newItem
, this, fMainReBar
, bandID
, flags
);
641 HRESULT
CInternetToolbar::ReserveBorderSpace(LONG maxHeight
)
643 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
644 RECT availableBorderSpace
;
646 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
647 if (FAILED_UNEXPECTEDLY(hResult
))
649 hResult
= dockingWindowSite
->GetBorderDW(static_cast<IDockingWindow
*>(this), &availableBorderSpace
);
650 if (FAILED_UNEXPECTEDLY(hResult
))
653 if (availableBorderSpace
.top
> maxHeight
)
655 availableBorderSpace
.top
= maxHeight
;
658 return ResizeBorderDW(&availableBorderSpace
, fSite
, FALSE
);
661 HRESULT
CInternetToolbar::CreateMenuBar(IShellMenu
**pMenuBar
)
663 CComPtr
<IShellMenu
> menubar
;
664 CComPtr
<IShellMenuCallback
> callback
;
674 hResult
= CreateMenuBand(IID_PPV_ARG(IShellMenu
, &menubar
));
675 if (FAILED_UNEXPECTEDLY(hResult
))
678 hResult
= fMenuCallback
->QueryInterface(IID_PPV_ARG(IShellMenuCallback
, &callback
));
679 if (FAILED_UNEXPECTEDLY(hResult
))
682 hResult
= menubar
->Initialize(callback
, -1, ANCESTORDEFAULT
, SMINIT_HORIZONTAL
| SMINIT_TOPLEVEL
);
683 if (FAILED_UNEXPECTEDLY(hResult
))
688 hResult
= IUnknown_Exec(fSite
, CGID_Explorer
, 0x35, 0, NULL
, &menuOut
);
689 if (FAILED_UNEXPECTEDLY(hResult
))
692 if (V_VT(&menuOut
) != VT_INT_PTR
|| V_INTREF(&menuOut
) == NULL
)
695 hResult
= IUnknown_GetWindow(fSite
, &ownerWindow
);
696 if (FAILED_UNEXPECTEDLY(hResult
))
699 HMENU hMenuBar
= (HMENU
) V_INTREF(&menuOut
);
701 // FIXME: Figure out the proper way to do this.
702 HMENU hMenuFavs
= GetSubMenu(hMenuBar
, 3);
705 DeleteMenu(hMenuFavs
, IDM_FAVORITES_EMPTY
, MF_BYCOMMAND
);
708 hResult
= menubar
->SetMenu(hMenuBar
, ownerWindow
, SMSET_DONTOWN
);
709 if (FAILED_UNEXPECTEDLY(hResult
))
713 hResult
= IUnknown_Exec(menubar
, CGID_MenuBand
, 3, 1, NULL
, NULL
);
714 if (FAILED_UNEXPECTEDLY(hResult
))
717 *pMenuBar
= menubar
.Detach();
722 HRESULT
CInternetToolbar::CreateBrandBand(IUnknown
**logoBar
)
725 return ::CreateBrandBand(IID_PPV_ARG(IUnknown
, logoBar
));
727 return CoCreateInstance(CLSID_BrandBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, logoBar
));
731 HRESULT
CInternetToolbar::CreateToolsBar(IUnknown
**toolsBar
)
733 return ::CreateToolsBar(IID_PPV_ARG(IUnknown
, toolsBar
));
736 HRESULT
CInternetToolbar::CreateAddressBand(IUnknown
**toolsBar
)
739 return ::CreateAddressBand(IID_PPV_ARG(IUnknown
, toolsBar
));
741 return CoCreateInstance(CLSID_SH_AddressBand
, NULL
, CLSCTX_INPROC_SERVER
, IID_PPV_ARG(IUnknown
, toolsBar
));
745 HRESULT
CInternetToolbar::LockUnlockToolbars(bool locked
)
747 REBARBANDINFOW rebarBandInfo
;
752 if (locked
!= fLocked
)
755 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
756 rebarBandInfo
.fMask
= RBBIM_STYLE
| RBBIM_LPARAM
;
757 bandCount
= (int)SendMessage(fMainReBar
, RB_GETBANDCOUNT
, 0, 0);
758 for (INT x
= 0; x
< bandCount
; x
++)
760 SendMessage(fMainReBar
, RB_GETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
761 dockSite
= reinterpret_cast<CDockSite
*>(rebarBandInfo
.lParam
);
762 if (dockSite
!= NULL
)
764 rebarBandInfo
.fStyle
&= ~(RBBS_NOGRIPPER
| RBBS_GRIPPERALWAYS
);
765 if (dockSite
->fFlags
& CDockSite::ITF_NOGRIPPER
|| fLocked
)
766 rebarBandInfo
.fStyle
|= RBBS_NOGRIPPER
;
767 if (dockSite
->fFlags
& CDockSite::ITF_GRIPPERALWAYS
&& !fLocked
)
768 rebarBandInfo
.fStyle
|= RBBS_GRIPPERALWAYS
;
769 SendMessage(fMainReBar
, RB_SETBANDINFOW
, x
, (LPARAM
)&rebarBandInfo
);
772 hResult
= ReserveBorderSpace();
774 // TODO: refresh view menu?
779 HRESULT
CInternetToolbar::CommandStateChanged(bool newValue
, int commandID
)
787 // loop through buttons
788 //for buttons in CLSID_CommonButtons
789 // if up, QueryStatus for up state and update it
791 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
795 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_FORWARD
, newValue
? TBSTATE_ENABLED
: 0);
799 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_BACK
, newValue
? TBSTATE_ENABLED
: 0);
803 hResult
= SetState(&CLSID_CommonButtons
, IDM_GOTO_UPONELEVEL
, newValue
? TBSTATE_ENABLED
: 0);
809 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
811 CComPtr
<IServiceProvider
> serviceProvider
;
814 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
815 if (FAILED_UNEXPECTEDLY(hResult
))
817 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
818 if (FAILED_UNEXPECTEDLY(hResult
))
820 hResult
= CreateBandProxy(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
821 if (FAILED_UNEXPECTEDLY(hResult
))
823 hResult
= fBandProxy
->SetSite(fSite
);
824 if (FAILED_UNEXPECTEDLY(hResult
))
830 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
835 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
837 HRESULT hr
= S_FALSE
;
840 hr
= IUnknown_HasFocusIO(fMenuBar
);
845 hr
= IUnknown_HasFocusIO(fControlsBar
);
850 hr
= IUnknown_HasFocusIO(fNavigationBar
);
857 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
859 HRESULT hr
= S_FALSE
;
862 hr
= IUnknown_TranslateAcceleratorIO(fMenuBar
, lpMsg
);
867 hr
= IUnknown_TranslateAcceleratorIO(fControlsBar
, lpMsg
);
872 hr
= IUnknown_TranslateAcceleratorIO(fNavigationBar
, lpMsg
);
879 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
887 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
892 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
899 hResult
= ReserveBorderSpace();
900 if (FAILED_UNEXPECTEDLY(hResult
))
906 hResult
= IUnknown_ShowDW(fMenuBar
, fShow
);
907 if (FAILED_UNEXPECTEDLY(hResult
))
913 hResult
= IUnknown_ShowDW(fControlsBar
, fShow
);
914 if (FAILED_UNEXPECTEDLY(hResult
))
919 hResult
= IUnknown_ShowDW(fNavigationBar
, fShow
);
920 if (FAILED_UNEXPECTEDLY(hResult
))
925 hResult
= IUnknown_ShowDW(fLogoBar
, fShow
);
926 if (FAILED_UNEXPECTEDLY(hResult
))
932 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
938 hResult
= IUnknown_CloseDW(fMenuBar
, dwReserved
);
939 if (FAILED_UNEXPECTEDLY(hResult
))
941 ReleaseCComPtrExpectZero(fMenuBar
);
945 hResult
= IUnknown_CloseDW(fControlsBar
, dwReserved
);
946 if (FAILED_UNEXPECTEDLY(hResult
))
948 ReleaseCComPtrExpectZero(fControlsBar
);
952 hResult
= IUnknown_CloseDW(fNavigationBar
, dwReserved
);
953 if (FAILED_UNEXPECTEDLY(hResult
))
955 ReleaseCComPtrExpectZero(fNavigationBar
);
959 hResult
= IUnknown_CloseDW(fLogoBar
, dwReserved
);
960 if (FAILED_UNEXPECTEDLY(hResult
))
962 ReleaseCComPtrExpectZero(fLogoBar
);
967 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
968 IUnknown
*punkToolbarSite
, BOOL fReserved
)
970 RECT neededBorderSpace
;
971 RECT availableBorderSpace
= *prcBorder
;
973 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
975 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
976 // Let's make sure we fetch the actual size properly.
977 GetWindowRect(fMainReBar
, &availableBorderSpace
);
978 neededBorderSpace
.left
= 0;
979 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
981 neededBorderSpace
.top
+= 3;
982 neededBorderSpace
.right
= 0;
983 neededBorderSpace
.bottom
= 0;
985 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
987 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
988 if (FAILED_UNEXPECTEDLY(hResult
))
991 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
992 if (FAILED_UNEXPECTEDLY(hResult
))
995 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
996 if (FAILED_UNEXPECTEDLY(hResult
))
1002 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
1004 if (pClassID
== NULL
)
1006 *pClassID
= CLSID_InternetToolbar
;
1010 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
1015 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
1020 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
1025 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1030 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
1032 CComPtr
<IShellMenu
> menuBar
;
1033 CComPtr
<IUnknown
> logoBar
;
1034 CComPtr
<IUnknown
> toolsBar
;
1035 CComPtr
<IUnknown
> navigationBar
;
1038 /* Create and attach the menubar to the rebar */
1039 hResult
= CreateMenuBar(&menuBar
);
1040 if (FAILED_UNEXPECTEDLY(hResult
))
1042 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1044 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
1045 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1047 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1048 // and it will put them in their own row, sized to take up the whole row.
1050 /* Create and attach the brand/logo to the rebar */
1051 hResult
= CreateBrandBand(&logoBar
);
1052 if (FAILED_UNEXPECTEDLY(hResult
))
1054 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1055 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1058 /* Create and attach the standard toolbar to the rebar */
1059 hResult
= CreateToolsBar(&toolsBar
);
1060 if (FAILED_UNEXPECTEDLY(hResult
))
1062 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1063 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1064 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1065 if (FAILED_UNEXPECTEDLY(hResult
))
1068 /* Create and attach the address/navigation toolbar to the rebar */
1069 hResult
= CreateAddressBand(&navigationBar
);
1070 if (FAILED_UNEXPECTEDLY(hResult
))
1072 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1073 fNavigationBar
.Attach(navigationBar
.Detach());
1074 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1079 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1080 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1082 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1086 switch (prgCmds
->cmdID
)
1088 case ITID_TEXTLABELS
: // Text Labels state
1089 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1091 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1092 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1094 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1096 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1097 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1099 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1101 case ITID_LINKSBANDSHOWN
: // links bar visibility
1104 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1105 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1107 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1109 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1112 case ITID_CUSTOMIZEENABLED
: // customize enabled
1113 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1115 case ITID_TOOLBARLOCKED
: // lock toolbars
1116 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1118 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1132 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1133 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1135 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1140 // what do I do here?
1142 case ITID_TEXTLABELS
:
1143 // toggle text labels
1145 case ITID_TOOLBARBANDSHOWN
:
1146 // toggle toolbar band visibility
1148 case ITID_ADDRESSBANDSHOWN
:
1149 // toggle address band visibility
1151 case ITID_LINKSBANDSHOWN
:
1152 // toggle links band visibility
1154 case ITID_CUSTOMIZEENABLED
:
1157 case ITID_TOOLBARLOCKED
:
1158 return LockUnlockToolbars(!fLocked
);
1164 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1169 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1174 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1175 LCID lcid
, DISPID
*rgDispId
)
1180 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1181 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1185 switch(dispIdMember
)
1187 case DISPID_BEFORENAVIGATE
:
1190 case DISPID_DOWNLOADCOMPLETE
:
1193 case DISPID_COMMANDSTATECHANGE
:
1194 if (pDispParams
->cArgs
!= 2)
1195 return E_INVALIDARG
;
1196 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1197 return E_INVALIDARG
;
1198 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1199 V_I4(&pDispParams
->rgvarg
[1]));
1200 case DISPID_DOWNLOADBEGIN
:
1203 case DISPID_NAVIGATECOMPLETE2
:
1206 case DISPID_DOCUMENTCOMPLETE
:
1213 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1217 TRACE("SetCommandTarget %p category %s param %d\n", theTarget
, wine_dbgstr_guid(category
), param14
);
1219 fCommandTarget
.Release();
1220 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1221 if (FAILED_UNEXPECTEDLY(hResult
))
1223 fCommandCategory
= *category
;
1227 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1232 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1237 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1238 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1242 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1243 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1250 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1255 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1257 if (theState
== NULL
)
1259 // map the command id
1260 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1264 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1266 // map the command id
1267 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1271 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1272 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1277 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1281 *paramC
= MAKELONG(24, 24);
1285 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1286 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1291 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1292 HIMAGELIST param14
, HIMAGELIST param18
)
1297 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1302 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1307 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1309 CComPtr
<IBrowserService
> browserService
;
1314 if (pUnkSite
== NULL
)
1316 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1317 ::DestroyWindow(fMainReBar
);
1323 // get window handle of owner
1324 hResult
= IUnknown_GetWindow(pUnkSite
, &ownerWindow
);
1325 if (FAILED_UNEXPECTEDLY(hResult
))
1327 if (ownerWindow
== NULL
)
1330 // create dock container
1332 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1333 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1334 if (dockContainer
== NULL
)
1336 SubclassWindow(dockContainer
);
1338 // create rebar in dock container
1339 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1340 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1341 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1342 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1343 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1344 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1345 if (fMainReBar
== NULL
)
1348 // take advice to watch events
1349 hResult
= IUnknown_QueryService(pUnkSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1350 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1355 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1357 if (ppvSite
== NULL
)
1359 if (fSite
.p
!= NULL
)
1360 return fSite
->QueryInterface(riid
, ppvSite
);
1365 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1369 if (IsEqualIID(guidService
, IID_IBandSite
))
1370 return this->QueryInterface(riid
, ppvObject
);
1371 if (IsEqualIID(guidService
, SID_IBandProxy
))
1373 if (fBandProxy
.p
== NULL
)
1375 hResult
= CreateAndInitBandProxy();
1376 if (FAILED_UNEXPECTEDLY(hResult
))
1379 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1381 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1384 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1385 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1391 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1392 if (hResult
!= S_FALSE
)
1398 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1399 if (hResult
!= S_FALSE
)
1405 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1406 if (hResult
!= S_FALSE
)
1413 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1419 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1425 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1431 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1432 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1436 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1437 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1438 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1439 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1444 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1450 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1456 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1462 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1468 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1474 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1476 CComPtr
<IWebBrowser
> webBrowser
;
1479 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1480 if (FAILED_UNEXPECTEDLY(hResult
))
1482 hResult
= webBrowser
->GoBack();
1486 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1488 CComPtr
<IWebBrowser
> webBrowser
;
1491 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1492 if (FAILED_UNEXPECTEDLY(hResult
))
1494 hResult
= webBrowser
->GoForward();
1498 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1500 IUnknown_Exec(fSite
, CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1504 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1506 CComPtr
<IObjectWithSite
> objectWithSite
;
1507 CComPtr
<IContextMenu
> contextMenu
;
1508 CMINVOKECOMMANDINFO commandInfo
;
1509 const char *searchGUID
= "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1512 // TODO: Query shell if this command is enabled first
1514 memset(&commandInfo
, 0, sizeof(commandInfo
));
1515 commandInfo
.cbSize
= sizeof(commandInfo
);
1516 commandInfo
.hwnd
= m_hWnd
;
1517 commandInfo
.lpParameters
= searchGUID
;
1518 commandInfo
.nShow
= SW_SHOWNORMAL
;
1520 hResult
= CoCreateInstance(CLSID_ShellSearchExt
, NULL
, CLSCTX_INPROC_SERVER
,
1521 IID_PPV_ARG(IContextMenu
, &contextMenu
));
1522 if (FAILED_UNEXPECTEDLY(hResult
))
1524 hResult
= contextMenu
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &objectWithSite
));
1525 if (FAILED_UNEXPECTEDLY(hResult
))
1527 hResult
= objectWithSite
->SetSite(fSite
);
1528 if (FAILED_UNEXPECTEDLY(hResult
))
1530 hResult
= contextMenu
->InvokeCommand(&commandInfo
);
1531 hResult
= objectWithSite
->SetSite(NULL
);
1535 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1537 IUnknown_Exec(fSite
, CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1541 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1545 if (fCommandTarget
.p
!= NULL
)
1547 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1552 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1554 CComPtr
<IBrowserService
> browserService
;
1555 CComPtr
<IOleCommandTarget
> commandTarget
;
1556 CComPtr
<ITravelLog
> travelLog
;
1557 NMTOOLBARW
*notifyInfo
;
1566 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1567 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1569 // not from the toolbar, keep looking for a message handler
1573 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1574 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1575 switch (notifyInfo
->iItem
)
1578 newMenu
= CreatePopupMenu();
1579 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1580 hResult
= browserService
->GetTravelLog(&travelLog
);
1581 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1582 commandInfo
.cmdID
= 0x1d;
1583 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1584 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1585 travelLog
->CountEntries(browserService
) > 1)
1587 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1588 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1590 params
.cbSize
= sizeof (params
);
1591 params
.rcExclude
= bounds
;
1592 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1593 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1594 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1596 V_VT(&parmIn
) = VT_I4
;
1598 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1600 else if (selectedItem
!= 0)
1601 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1602 DestroyMenu(newMenu
);
1604 case IDM_GOTO_FORWARD
:
1605 newMenu
= CreatePopupMenu();
1606 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1607 hResult
= browserService
->GetTravelLog(&travelLog
);
1608 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1609 commandInfo
.cmdID
= 0x1d;
1610 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1611 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1612 travelLog
->CountEntries(browserService
) > 1)
1614 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1615 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1617 params
.cbSize
= sizeof (params
);
1618 params
.rcExclude
= bounds
;
1619 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1620 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1621 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1623 V_VT(&parmIn
) = VT_I4
;
1625 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1627 else if (selectedItem
!= 0)
1628 hResult
= travelLog
->Travel(browserService
, selectedItem
);
1629 DestroyMenu(newMenu
);
1631 case gViewsCommandID
:
1633 CComVariant outValue
;
1636 V_VT(&inValue
) = VT_INT_PTR
;
1637 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1639 if (fCommandTarget
.p
!= NULL
)
1640 hResult
= fCommandTarget
->Exec(&fCommandCategory
, FCIDM_SHVIEW_AUTOARRANGE
, 1, &inValue
, &outValue
);
1641 // pvaOut is VT_I4 with value 0x403
1644 return TBDDRET_DEFAULT
;
1647 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1652 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1657 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1659 HMENU contextMenuBar
;
1661 POINT clickLocation
;
1663 RBHITTESTINFO hitTestInfo
;
1664 REBARBANDINFOW rebarBandInfo
;
1667 clickLocation
.x
= LOWORD(lParam
);
1668 clickLocation
.y
= HIWORD(lParam
);
1669 hitTestInfo
.pt
= clickLocation
;
1670 ScreenToClient(&hitTestInfo
.pt
);
1671 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1672 if (hitTestInfo
.iBand
== -1)
1674 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1675 rebarBandInfo
.fMask
= RBBIM_ID
;
1676 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1677 bandID
= rebarBandInfo
.wID
;
1678 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1679 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1682 case ITBBID_MENUBAND
: // menu band
1683 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1684 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1685 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1687 case ITBBID_BRANDBAND
: // brand band
1688 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1689 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1690 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1692 case ITBBID_TOOLSBAND
: // tools band
1693 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1694 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1696 case ITBBID_ADDRESSBAND
: // navigation band
1697 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1698 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1704 // TODO: Implement show/hide toolbars
1705 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, FALSE
);
1706 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, FALSE
);
1707 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1708 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1710 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, fControlsBar
!= NULL
);
1711 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, fNavigationBar
!= NULL
);
1712 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1713 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1714 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, fLocked
);
1716 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1717 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1718 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1721 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1723 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1725 case IDM_TOOLBARS_LINKSBAR
: // links
1727 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1728 LockUnlockToolbars(!fLocked
);
1730 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1731 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1735 DestroyMenu(contextMenuBar
);
1739 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1741 if (wParam
!= SIZE_MINIMIZED
)
1743 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1744 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1749 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1751 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1756 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1760 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1762 CComPtr
<IBrowserService
> browserService
;
1763 CComPtr
<ITravelLog
> travelLog
;
1764 TOOLTIPTEXTW
*pTTTW
;
1766 wchar_t tempString
[300];
1769 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1770 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1771 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1773 nID
= (UINT
)pNMHDR
->idFrom
;
1777 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1779 // TODO: Should this call QueryService?
1780 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1781 hResult
= browserService
->GetTravelLog(&travelLog
);
1782 hResult
= travelLog
->GetToolTipText(browserService
,
1783 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1784 0, tempString
, 299);
1785 if (FAILED_UNEXPECTEDLY(hResult
))
1793 wcsncpy (pTTTW
->szText
, tempString
, sizeof (pTTTW
->szText
) / sizeof (wchar_t));
1794 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1795 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1801 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1806 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1808 bHandled
= hResult
== S_OK
;
1810 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1812 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1814 NMHDR
*notifyHeader
;
1818 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1820 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1822 bHandled
= hResult
== S_OK
;
1824 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1827 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1833 if (wParam
& MK_CONTROL
)
1838 DWORD msgp
= GetMessagePos();
1840 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1841 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1844 GetWindowRect(m_hWnd
, &rc
);
1846 fStartHeight
= rc
.bottom
- rc
.top
;
1854 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1860 DWORD msgp
= GetMessagePos();
1863 pt
.x
= GET_X_LPARAM(msgp
);
1864 pt
.y
= GET_Y_LPARAM(msgp
);
1866 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1872 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1878 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);
1887 HRESULT
CreateInternetToolbar(REFIID riid
, void **ppv
)
1889 return ShellObjectCreator
<CInternetToolbar
>(riid
, ppv
);