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);
805 HRESULT
CInternetToolbar::CreateAndInitBandProxy()
807 CComPtr
<IServiceProvider
> serviceProvider
;
810 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IServiceProvider
, &serviceProvider
));
811 if (FAILED_UNEXPECTEDLY(hResult
))
813 hResult
= serviceProvider
->QueryService(SID_IBandProxy
, IID_PPV_ARG(IBandProxy
, &fBandProxy
));
814 if (FAILED_UNEXPECTEDLY(hResult
))
816 hResult
= CreateBandProxy(IID_PPV_ARG(IBandProxy
, &fBandProxy
));
817 if (FAILED_UNEXPECTEDLY(hResult
))
819 hResult
= fBandProxy
->SetSite(fSite
);
820 if (FAILED_UNEXPECTEDLY(hResult
))
826 HRESULT STDMETHODCALLTYPE
CInternetToolbar::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
831 HRESULT STDMETHODCALLTYPE
CInternetToolbar::HasFocusIO()
833 HRESULT hr
= S_FALSE
;
836 hr
= IUnknown_HasFocusIO(fMenuBar
);
841 hr
= IUnknown_HasFocusIO(fControlsBar
);
846 hr
= IUnknown_HasFocusIO(fNavigationBar
);
853 HRESULT STDMETHODCALLTYPE
CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg
)
855 HRESULT hr
= S_FALSE
;
858 hr
= IUnknown_TranslateAcceleratorIO(fMenuBar
, lpMsg
);
863 hr
= IUnknown_TranslateAcceleratorIO(fControlsBar
, lpMsg
);
868 hr
= IUnknown_TranslateAcceleratorIO(fNavigationBar
, lpMsg
);
875 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetWindow(HWND
*lphwnd
)
883 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode
)
888 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ShowDW(BOOL fShow
)
895 hResult
= ReserveBorderSpace();
896 if (FAILED_UNEXPECTEDLY(hResult
))
902 hResult
= IUnknown_ShowDW(fMenuBar
, fShow
);
903 if (FAILED_UNEXPECTEDLY(hResult
))
909 hResult
= IUnknown_ShowDW(fControlsBar
, fShow
);
910 if (FAILED_UNEXPECTEDLY(hResult
))
915 hResult
= IUnknown_ShowDW(fNavigationBar
, fShow
);
916 if (FAILED_UNEXPECTEDLY(hResult
))
921 hResult
= IUnknown_ShowDW(fLogoBar
, fShow
);
922 if (FAILED_UNEXPECTEDLY(hResult
))
928 HRESULT STDMETHODCALLTYPE
CInternetToolbar::CloseDW(DWORD dwReserved
)
934 hResult
= IUnknown_CloseDW(fMenuBar
, dwReserved
);
935 if (FAILED_UNEXPECTEDLY(hResult
))
937 ReleaseCComPtrExpectZero(fMenuBar
);
941 hResult
= IUnknown_CloseDW(fControlsBar
, dwReserved
);
942 if (FAILED_UNEXPECTEDLY(hResult
))
944 ReleaseCComPtrExpectZero(fControlsBar
);
948 hResult
= IUnknown_CloseDW(fNavigationBar
, dwReserved
);
949 if (FAILED_UNEXPECTEDLY(hResult
))
951 ReleaseCComPtrExpectZero(fNavigationBar
);
955 hResult
= IUnknown_CloseDW(fLogoBar
, dwReserved
);
956 if (FAILED_UNEXPECTEDLY(hResult
))
958 ReleaseCComPtrExpectZero(fLogoBar
);
963 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder
,
964 IUnknown
*punkToolbarSite
, BOOL fReserved
)
966 RECT neededBorderSpace
;
967 RECT availableBorderSpace
= *prcBorder
;
969 SendMessage(fMainReBar
, RB_SIZETORECT
, RBSTR_CHANGERECT
, reinterpret_cast<LPARAM
>(&availableBorderSpace
));
971 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
972 // Let's make sure we fetch the actual size properly.
973 GetWindowRect(fMainReBar
, &availableBorderSpace
);
974 neededBorderSpace
.left
= 0;
975 neededBorderSpace
.top
= availableBorderSpace
.bottom
- availableBorderSpace
.top
;
977 neededBorderSpace
.top
+= 3;
978 neededBorderSpace
.right
= 0;
979 neededBorderSpace
.bottom
= 0;
981 CComPtr
<IDockingWindowSite
> dockingWindowSite
;
983 HRESULT hResult
= fSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &dockingWindowSite
));
984 if (FAILED_UNEXPECTEDLY(hResult
))
987 hResult
= dockingWindowSite
->RequestBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
988 if (FAILED_UNEXPECTEDLY(hResult
))
991 hResult
= dockingWindowSite
->SetBorderSpaceDW(static_cast<IDockingWindow
*>(this), &neededBorderSpace
);
992 if (FAILED_UNEXPECTEDLY(hResult
))
998 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetClassID(CLSID
*pClassID
)
1000 if (pClassID
== NULL
)
1002 *pClassID
= CLSID_InternetToolbar
;
1006 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsDirty()
1011 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Load(IStream
*pStm
)
1016 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Save(IStream
*pStm
, BOOL fClearDirty
)
1021 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1026 HRESULT STDMETHODCALLTYPE
CInternetToolbar::InitNew()
1028 CComPtr
<IShellMenu
> menuBar
;
1029 CComPtr
<IUnknown
> logoBar
;
1030 CComPtr
<IUnknown
> toolsBar
;
1031 CComPtr
<IUnknown
> navigationBar
;
1034 /* Create and attach the menubar to the rebar */
1035 hResult
= CreateMenuBar(&menuBar
);
1036 if (FAILED_UNEXPECTEDLY(hResult
))
1038 AddDockItem(menuBar
, ITBBID_MENUBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1040 hResult
= IUnknown_GetWindow(menuBar
, &fMenuBandWindow
);
1041 fMenuBar
.Attach(menuBar
.Detach()); // transfer the ref count
1043 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1044 // and it will put them in their own row, sized to take up the whole row.
1046 /* Create and attach the brand/logo to the rebar */
1047 hResult
= CreateBrandBand(&logoBar
);
1048 if (FAILED_UNEXPECTEDLY(hResult
))
1050 AddDockItem(logoBar
, ITBBID_BRANDBAND
, CDockSite::ITF_NOGRIPPER
| CDockSite::ITF_NOTITLE
| CDockSite::ITF_FIXEDSIZE
);
1051 fLogoBar
.Attach(logoBar
.Detach()); // transfer the ref count
1054 /* Create and attach the standard toolbar to the rebar */
1055 hResult
= CreateToolsBar(&toolsBar
);
1056 if (FAILED_UNEXPECTEDLY(hResult
))
1058 AddDockItem(toolsBar
, ITBBID_TOOLSBAND
, CDockSite::ITF_NOTITLE
| CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1059 fControlsBar
.Attach(toolsBar
.Detach()); // transfer the ref count
1060 hResult
= IUnknown_GetWindow(fControlsBar
, &fToolbarWindow
);
1061 if (FAILED_UNEXPECTEDLY(hResult
))
1064 /* Create and attach the address/navigation toolbar to the rebar */
1065 hResult
= CreateAddressBand(&navigationBar
);
1066 if (FAILED_UNEXPECTEDLY(hResult
))
1068 AddDockItem(navigationBar
, ITBBID_ADDRESSBAND
, CDockSite::ITF_NEWBANDALWAYS
| CDockSite::ITF_GRIPPERALWAYS
);
1069 fNavigationBar
.Attach(navigationBar
.Detach());
1070 hResult
= IUnknown_GetWindow(fNavigationBar
, &fNavigationWindow
);
1075 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryStatus(const GUID
*pguidCmdGroup
,
1076 ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
1078 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1082 switch (prgCmds
->cmdID
)
1084 case ITID_TEXTLABELS
: // Text Labels state
1085 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1087 case ITID_TOOLBARBANDSHOWN
: // toolbar visibility
1088 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1090 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1092 case ITID_ADDRESSBANDSHOWN
: // address bar visibility
1093 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1095 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1097 case ITID_LINKSBANDSHOWN
: // links bar visibility
1100 case ITID_MENUBANDSHOWN
: // Menubar band visibility
1101 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1103 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1105 case ITID_AUTOHIDEENABLED
: // Auto hide enabled/disabled
1108 case ITID_CUSTOMIZEENABLED
: // customize enabled
1109 prgCmds
->cmdf
= OLECMDF_SUPPORTED
;
1111 case ITID_TOOLBARLOCKED
: // lock toolbars
1112 prgCmds
->cmdf
= OLECMDF_SUPPORTED
| OLECMDF_ENABLED
;
1114 prgCmds
->cmdf
|= OLECMDF_LATCHED
;
1128 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
1129 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1131 if (IsEqualIID(*pguidCmdGroup
, CGID_PrivCITCommands
))
1136 // what do I do here?
1138 case ITID_TEXTLABELS
:
1139 // toggle text labels
1141 case ITID_TOOLBARBANDSHOWN
:
1142 // toggle toolbar band visibility
1144 case ITID_ADDRESSBANDSHOWN
:
1145 // toggle address band visibility
1147 case ITID_LINKSBANDSHOWN
:
1148 // toggle links band visibility
1150 case ITID_CUSTOMIZEENABLED
:
1153 case ITID_TOOLBARLOCKED
:
1154 return LockUnlockToolbars(!fLocked
);
1160 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfoCount(UINT
*pctinfo
)
1165 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
1170 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetIDsOfNames(REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1171 LCID lcid
, DISPID
*rgDispId
)
1176 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1177 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1181 switch(dispIdMember
)
1183 case DISPID_BEFORENAVIGATE
:
1186 case DISPID_DOWNLOADCOMPLETE
:
1189 case DISPID_COMMANDSTATECHANGE
:
1190 if (pDispParams
->cArgs
!= 2)
1191 return E_INVALIDARG
;
1192 if (V_VT(&pDispParams
->rgvarg
[0]) != VT_BOOL
|| V_VT(&pDispParams
->rgvarg
[1]) != VT_I4
)
1193 return E_INVALIDARG
;
1194 return CommandStateChanged(V_BOOL(&pDispParams
->rgvarg
[0]) != VARIANT_FALSE
,
1195 V_I4(&pDispParams
->rgvarg
[1]));
1196 case DISPID_DOWNLOADBEGIN
:
1199 case DISPID_NAVIGATECOMPLETE2
:
1202 case DISPID_DOCUMENTCOMPLETE
:
1209 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetCommandTarget(IUnknown
*theTarget
, GUID
*category
, long param14
)
1213 TRACE("SetCommandTarget %p category %s param %d\n", theTarget
, wine_dbgstr_guid(category
), param14
);
1215 fCommandTarget
.Release();
1216 hResult
= theTarget
->QueryInterface(IID_PPV_ARG(IOleCommandTarget
, &fCommandTarget
));
1217 if (FAILED_UNEXPECTEDLY(hResult
))
1219 fCommandCategory
= *category
;
1223 HRESULT STDMETHODCALLTYPE
CInternetToolbar::Unknown1()
1228 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddButtons(const GUID
*pguidCmdGroup
, long buttonCount
, TBBUTTON
*buttons
)
1233 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddString(const GUID
*pguidCmdGroup
,
1234 HINSTANCE param10
, LPCTSTR param14
, long *param18
)
1238 result
= (long)::SendMessage(fToolbarWindow
, TB_ADDSTRINGW
,
1239 reinterpret_cast<WPARAM
>(param10
), reinterpret_cast<LPARAM
>(param14
));
1246 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1251 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetState(const GUID
*pguidCmdGroup
, long commandID
, long *theState
)
1253 if (theState
== NULL
)
1255 // map the command id
1256 *theState
= (long)::SendMessage(fToolbarWindow
, TB_GETSTATE
, commandID
, 0);
1260 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetState(const GUID
*pguidCmdGroup
, long commandID
, long theState
)
1262 // map the command id
1263 ::SendMessage(fToolbarWindow
, TB_SETSTATE
, commandID
, MAKELONG(theState
, 0));
1267 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBitmap(const GUID
*pguidCmdGroup
, long param10
, long buttonCount
,
1268 TBADDBITMAP
*lParam
, long *newIndex
, COLORREF param20
)
1273 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBitmapSize(long *paramC
)
1277 *paramC
= MAKELONG(24, 24);
1281 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SendToolbarMsg(const GUID
*pguidCmdGroup
, UINT uMsg
,
1282 WPARAM wParam
, LPARAM lParam
, LRESULT
*result
)
1287 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetImageList(const GUID
*pguidCmdGroup
, HIMAGELIST param10
,
1288 HIMAGELIST param14
, HIMAGELIST param18
)
1293 HRESULT STDMETHODCALLTYPE
CInternetToolbar::ModifyButton(const GUID
*pguidCmdGroup
, long param10
, long param14
)
1298 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnChange(LONG lEvent
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
1303 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetSite(IUnknown
*pUnkSite
)
1305 CComPtr
<IBrowserService
> browserService
;
1310 if (pUnkSite
== NULL
)
1312 hResult
= AtlUnadvise(fSite
, DIID_DWebBrowserEvents
, fAdviseCookie
);
1313 ::DestroyWindow(fMainReBar
);
1319 // get window handle of owner
1320 hResult
= IUnknown_GetWindow(pUnkSite
, &ownerWindow
);
1321 if (FAILED_UNEXPECTEDLY(hResult
))
1323 if (ownerWindow
== NULL
)
1326 // create dock container
1328 dockContainer
= SHCreateWorkerWindowW(0, ownerWindow
, 0,
1329 WS_VISIBLE
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
, NULL
, 0);
1330 if (dockContainer
== NULL
)
1332 SubclassWindow(dockContainer
);
1334 // create rebar in dock container
1335 DWORD style
= WS_VISIBLE
| WS_BORDER
| WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
1336 RBS_VARHEIGHT
| RBS_BANDBORDERS
| RBS_REGISTERDROP
| RBS_AUTOSIZE
| RBS_DBLCLKTOGGLE
|
1337 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_TOP
;
1338 DWORD exStyle
= WS_EX_LEFT
| WS_EX_LTRREADING
| WS_EX_RIGHTSCROLLBAR
| WS_EX_TOOLWINDOW
;
1339 fMainReBar
= CreateWindowEx(exStyle
, REBARCLASSNAMEW
, NULL
, style
,
1340 0, 0, 700, 60, dockContainer
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
1341 if (fMainReBar
== NULL
)
1344 // take advice to watch events
1345 hResult
= IUnknown_QueryService(pUnkSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1346 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
1351 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetSite(REFIID riid
, void **ppvSite
)
1353 if (ppvSite
== NULL
)
1355 if (fSite
.p
!= NULL
)
1356 return fSite
->QueryInterface(riid
, ppvSite
);
1361 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1365 if (IsEqualIID(guidService
, IID_IBandSite
))
1366 return this->QueryInterface(riid
, ppvObject
);
1367 if (IsEqualIID(guidService
, SID_IBandProxy
))
1369 if (fBandProxy
.p
== NULL
)
1371 hResult
= CreateAndInitBandProxy();
1372 if (FAILED_UNEXPECTEDLY(hResult
))
1375 return fBandProxy
->QueryInterface(riid
, ppvObject
);
1377 return IUnknown_QueryService(fSite
, guidService
, riid
, ppvObject
);
1380 HRESULT STDMETHODCALLTYPE
CInternetToolbar::OnWinEvent(
1381 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1387 hResult
= IUnknown_RelayWinEvent(fMenuBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1388 if (hResult
!= S_FALSE
)
1394 hResult
= IUnknown_RelayWinEvent(fNavigationBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1395 if (hResult
!= S_FALSE
)
1401 hResult
= IUnknown_RelayWinEvent(fLogoBar
, hWnd
, uMsg
, wParam
, lParam
, theResult
);
1402 if (hResult
!= S_FALSE
)
1409 HRESULT STDMETHODCALLTYPE
CInternetToolbar::IsWindowOwner(HWND hWnd
)
1415 HRESULT STDMETHODCALLTYPE
CInternetToolbar::AddBand(IUnknown
*punk
)
1421 HRESULT STDMETHODCALLTYPE
CInternetToolbar::EnumBands(UINT uBand
, DWORD
*pdwBandID
)
1427 HRESULT STDMETHODCALLTYPE
CInternetToolbar::QueryBand(DWORD dwBandID
,
1428 IDeskBand
**ppstb
, DWORD
*pdwState
, LPWSTR pszName
, int cchName
)
1432 if (dwBandID
== ITBBID_MENUBAND
&& fMenuBar
.p
!= NULL
)
1433 return fMenuBar
->QueryInterface(IID_PPV_ARG(IDeskBand
, ppstb
));
1434 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1435 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1440 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandState(DWORD dwBandID
, DWORD dwMask
, DWORD dwState
)
1446 HRESULT STDMETHODCALLTYPE
CInternetToolbar::RemoveBand(DWORD dwBandID
)
1452 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandObject(DWORD dwBandID
, REFIID riid
, void **ppv
)
1458 HRESULT STDMETHODCALLTYPE
CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO
*pbsinfo
)
1464 HRESULT STDMETHODCALLTYPE
CInternetToolbar::GetBandSiteInfo(BANDSITEINFO
*pbsinfo
)
1470 LRESULT
CInternetToolbar::OnTravelBack(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1472 CComPtr
<IWebBrowser
> webBrowser
;
1475 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1476 if (FAILED_UNEXPECTEDLY(hResult
))
1478 hResult
= webBrowser
->GoBack();
1482 LRESULT
CInternetToolbar::OnTravelForward(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1484 CComPtr
<IWebBrowser
> webBrowser
;
1487 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IWebBrowser
, &webBrowser
));
1488 if (FAILED_UNEXPECTEDLY(hResult
))
1490 hResult
= webBrowser
->GoForward();
1494 LRESULT
CInternetToolbar::OnUpLevel(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1496 IUnknown_Exec(fSite
, CGID_ShellBrowser
, IDM_GOTO_UPONELEVEL
, 0, NULL
, NULL
);
1500 LRESULT
CInternetToolbar::OnSearch(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1502 CComPtr
<IObjectWithSite
> objectWithSite
;
1503 CComPtr
<IContextMenu
> contextMenu
;
1504 CMINVOKECOMMANDINFO commandInfo
;
1505 const char *searchGUID
= "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1508 // TODO: Query shell if this command is enabled first
1510 memset(&commandInfo
, 0, sizeof(commandInfo
));
1511 commandInfo
.cbSize
= sizeof(commandInfo
);
1512 commandInfo
.hwnd
= m_hWnd
;
1513 commandInfo
.lpParameters
= searchGUID
;
1514 commandInfo
.nShow
= SW_SHOWNORMAL
;
1516 hResult
= CoCreateInstance(CLSID_ShellSearchExt
, NULL
, CLSCTX_INPROC_SERVER
,
1517 IID_PPV_ARG(IContextMenu
, &contextMenu
));
1518 if (FAILED_UNEXPECTEDLY(hResult
))
1520 hResult
= contextMenu
->QueryInterface(IID_PPV_ARG(IObjectWithSite
, &objectWithSite
));
1521 if (FAILED_UNEXPECTEDLY(hResult
))
1523 hResult
= objectWithSite
->SetSite(fSite
);
1524 if (FAILED_UNEXPECTEDLY(hResult
))
1526 hResult
= contextMenu
->InvokeCommand(&commandInfo
);
1527 hResult
= objectWithSite
->SetSite(NULL
);
1531 LRESULT
CInternetToolbar::OnFolders(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1533 IUnknown_Exec(fSite
, CGID_Explorer
, 0x23, 0, NULL
, NULL
);
1537 LRESULT
CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
&bHandled
)
1541 if (fCommandTarget
.p
!= NULL
)
1543 hResult
= fCommandTarget
->Exec(&fCommandCategory
, wID
, 0, NULL
, NULL
);
1548 LRESULT
CInternetToolbar::OnMenuDropDown(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1550 CComPtr
<IBrowserService
> browserService
;
1551 CComPtr
<IOleCommandTarget
> commandTarget
;
1552 CComPtr
<ITravelLog
> travelLog
;
1553 NMTOOLBARW
*notifyInfo
;
1562 notifyInfo
= (NMTOOLBARW
*)pNMHDR
;
1563 if (notifyInfo
->hdr
.hwndFrom
!= fToolbarWindow
)
1565 // not from the toolbar, keep looking for a message handler
1569 SendMessage(fToolbarWindow
, TB_GETRECT
, notifyInfo
->iItem
, reinterpret_cast<LPARAM
>(&bounds
));
1570 ::MapWindowPoints(fToolbarWindow
, NULL
, reinterpret_cast<POINT
*>(&bounds
), 2);
1571 switch (notifyInfo
->iItem
)
1574 newMenu
= CreatePopupMenu();
1575 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1576 hResult
= browserService
->GetTravelLog(&travelLog
);
1577 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_BACK
);
1578 commandInfo
.cmdID
= 0x1d;
1579 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1580 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1581 travelLog
->CountEntries(browserService
) > 1)
1583 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1584 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1586 params
.cbSize
= sizeof (params
);
1587 params
.rcExclude
= bounds
;
1588 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1589 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1590 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1592 V_VT(&parmIn
) = VT_I4
;
1594 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1596 else if (selectedItem
!= 0)
1597 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1598 DestroyMenu(newMenu
);
1600 case IDM_GOTO_FORWARD
:
1601 newMenu
= CreatePopupMenu();
1602 hResult
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
1603 hResult
= browserService
->GetTravelLog(&travelLog
);
1604 hResult
= travelLog
->InsertMenuEntries(browserService
, newMenu
, 0, 1, 9, TLMENUF_FORE
);
1605 commandInfo
.cmdID
= 0x1d;
1606 hResult
= IUnknown_QueryStatus(browserService
, CGID_Explorer
, 1, &commandInfo
, NULL
);
1607 if ((commandInfo
.cmdf
& (OLECMDF_ENABLED
| OLECMDF_LATCHED
)) == OLECMDF_ENABLED
&&
1608 travelLog
->CountEntries(browserService
) > 1)
1610 AppendMenu(newMenu
, MF_SEPARATOR
, -1, L
"");
1611 AppendMenu(newMenu
, MF_STRING
/* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY
, L
"&History\tCtrl+H");
1613 params
.cbSize
= sizeof (params
);
1614 params
.rcExclude
= bounds
;
1615 selectedItem
= TrackPopupMenuEx(newMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RETURNCMD
,
1616 bounds
.left
, bounds
.bottom
, m_hWnd
, ¶ms
);
1617 if (selectedItem
== IDM_EXPLORERBAR_HISTORY
)
1619 V_VT(&parmIn
) = VT_I4
;
1621 Exec(&CGID_Explorer
, 0x1d, 2, &parmIn
, NULL
);
1623 else if (selectedItem
!= 0)
1624 hResult
= travelLog
->Travel(browserService
, -selectedItem
);
1625 DestroyMenu(newMenu
);
1627 case gViewsCommandID
:
1629 CComVariant outValue
;
1632 V_VT(&inValue
) = VT_INT_PTR
;
1633 V_INTREF(&inValue
) = reinterpret_cast<INT
*>(&bounds
);
1635 if (fCommandTarget
.p
!= NULL
)
1636 hResult
= fCommandTarget
->Exec(&fCommandCategory
, FCIDM_SHVIEW_AUTOARRANGE
, 1, &inValue
, &outValue
);
1637 // pvaOut is VT_I4 with value 0x403
1640 return TBDDRET_DEFAULT
;
1643 LRESULT
CInternetToolbar::OnQueryInsert(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1648 LRESULT
CInternetToolbar::OnQueryDelete(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1653 LRESULT
CInternetToolbar::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1655 HMENU contextMenuBar
;
1657 POINT clickLocation
;
1659 RBHITTESTINFO hitTestInfo
;
1660 REBARBANDINFOW rebarBandInfo
;
1663 clickLocation
.x
= LOWORD(lParam
);
1664 clickLocation
.y
= HIWORD(lParam
);
1665 hitTestInfo
.pt
= clickLocation
;
1666 ScreenToClient(&hitTestInfo
.pt
);
1667 SendMessage(fMainReBar
, RB_HITTEST
, 0, (LPARAM
)&hitTestInfo
);
1668 if (hitTestInfo
.iBand
== -1)
1670 rebarBandInfo
.cbSize
= sizeof(rebarBandInfo
);
1671 rebarBandInfo
.fMask
= RBBIM_ID
;
1672 SendMessage(fMainReBar
, RB_GETBANDINFOW
, hitTestInfo
.iBand
, (LPARAM
)&rebarBandInfo
);
1673 bandID
= rebarBandInfo
.wID
;
1674 contextMenuBar
= LoadMenu(_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU
));
1675 contextMenu
= GetSubMenu(contextMenuBar
, 0);
1678 case ITBBID_MENUBAND
: // menu band
1679 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1680 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1681 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1683 case ITBBID_BRANDBAND
: // brand band
1684 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1685 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1686 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1688 case ITBBID_TOOLSBAND
: // tools band
1689 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1690 DeleteMenu(contextMenu
, IDM_TOOLBARS_GOBUTTON
, MF_BYCOMMAND
);
1692 case ITBBID_ADDRESSBAND
: // navigation band
1693 DeleteMenu(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, MF_BYCOMMAND
);
1694 DeleteMenu(contextMenu
, IDM_TOOLBARS_TEXTLABELS
, MF_BYCOMMAND
);
1700 // TODO: Implement show/hide toolbars
1701 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, FALSE
);
1702 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, FALSE
);
1703 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1704 SHEnableMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1706 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_STANDARDBUTTONS
, fControlsBar
!= NULL
);
1707 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_ADDRESSBAR
, fNavigationBar
!= NULL
);
1708 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LINKSBAR
, FALSE
);
1709 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_CUSTOMIZE
, FALSE
);
1710 SHCheckMenuItem(contextMenu
, IDM_TOOLBARS_LOCKTOOLBARS
, fLocked
);
1712 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1713 command
= TrackPopupMenu(contextMenu
, TPM_LEFTALIGN
| TPM_TOPALIGN
| TPM_RIGHTBUTTON
| TPM_RETURNCMD
,
1714 clickLocation
.x
, clickLocation
.y
, 0, m_hWnd
, NULL
);
1717 case IDM_TOOLBARS_STANDARDBUTTONS
: // standard buttons
1719 case IDM_TOOLBARS_ADDRESSBAR
: // address bar
1721 case IDM_TOOLBARS_LINKSBAR
: // links
1723 case IDM_TOOLBARS_LOCKTOOLBARS
: // lock the toolbars
1724 LockUnlockToolbars(!fLocked
);
1726 case IDM_TOOLBARS_CUSTOMIZE
: // customize
1727 SendMessage(fToolbarWindow
, TB_CUSTOMIZE
, 0, 0);
1731 DestroyMenu(contextMenuBar
);
1735 LRESULT
CInternetToolbar::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1737 if (wParam
!= SIZE_MINIMIZED
)
1739 ::SetWindowPos(fMainReBar
, NULL
, 0, 0, LOWORD(lParam
), HIWORD(lParam
),
1740 SWP_NOOWNERZORDER
| SWP_NOZORDER
| SWP_NOMOVE
);
1745 LRESULT
CInternetToolbar::OnSetCursor(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1747 if ((short)lParam
!= HTCLIENT
|| (HWND
)wParam
!= m_hWnd
)
1752 SetCursor(LoadCursor(NULL
, IDC_SIZENS
));
1756 LRESULT
CInternetToolbar::OnTipText(UINT idControl
, NMHDR
*pNMHDR
, BOOL
&bHandled
)
1758 CComPtr
<IBrowserService
> browserService
;
1759 CComPtr
<ITravelLog
> travelLog
;
1760 TOOLTIPTEXTW
*pTTTW
;
1762 wchar_t tempString
[300];
1765 pTTTW
= reinterpret_cast<TOOLTIPTEXTW
*>(pNMHDR
);
1766 if ((pTTTW
->uFlags
& TTF_IDISHWND
) != 0)
1767 nID
= ::GetDlgCtrlID((HWND
)pNMHDR
->idFrom
);
1769 nID
= (UINT
)pNMHDR
->idFrom
;
1773 if (nID
== (UINT
)IDM_GOTO_BACK
|| nID
== (UINT
)IDM_GOTO_FORWARD
)
1775 // TODO: Should this call QueryService?
1776 hResult
= fSite
->QueryInterface(IID_PPV_ARG(IBrowserService
, &browserService
));
1777 hResult
= browserService
->GetTravelLog(&travelLog
);
1778 hResult
= travelLog
->GetToolTipText(browserService
,
1779 (nID
== (UINT
)IDM_GOTO_BACK
) ? TLOG_BACK
: TLOG_FORE
,
1780 0, tempString
, 299);
1781 if (FAILED_UNEXPECTEDLY(hResult
))
1789 wcsncpy (pTTTW
->szText
, tempString
, sizeof (pTTTW
->szText
) / sizeof (wchar_t));
1790 ::SetWindowPos(pNMHDR
->hwndFrom
, HWND_TOP
, 0, 0, 0, 0,
1791 SWP_NOOWNERZORDER
| SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
1797 LRESULT
CInternetToolbar::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1802 hResult
= OnWinEvent((HWND
) lParam
, uMsg
, wParam
, lParam
, &theResult
);
1804 bHandled
= hResult
== S_OK
;
1806 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1808 LRESULT
CInternetToolbar::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1810 NMHDR
*notifyHeader
;
1814 notifyHeader
= reinterpret_cast<NMHDR
*>(lParam
);
1816 hResult
= OnWinEvent(notifyHeader
->hwndFrom
, uMsg
, wParam
, lParam
, &theResult
);
1818 bHandled
= hResult
== S_OK
;
1820 return FAILED_UNEXPECTEDLY(hResult
) ? 0 : theResult
;
1823 LRESULT
CInternetToolbar::OnLDown(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1829 if (wParam
& MK_CONTROL
)
1834 DWORD msgp
= GetMessagePos();
1836 fStartPosition
.x
= GET_X_LPARAM(msgp
);
1837 fStartPosition
.y
= GET_Y_LPARAM(msgp
);
1840 GetWindowRect(m_hWnd
, &rc
);
1842 fStartHeight
= rc
.bottom
- rc
.top
;
1850 LRESULT
CInternetToolbar::OnMouseMove(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1856 DWORD msgp
= GetMessagePos();
1859 pt
.x
= GET_X_LPARAM(msgp
);
1860 pt
.y
= GET_Y_LPARAM(msgp
);
1862 ReserveBorderSpace(fStartHeight
- fStartPosition
.y
+ pt
.y
);
1868 LRESULT
CInternetToolbar::OnLUp(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1874 OnMouseMove(uMsg
, wParam
, lParam
, bHandled
);
1883 HRESULT
CreateInternetToolbar(REFIID riid
, void **ppv
)
1885 return ShellObjectCreator
<CInternetToolbar
>(riid
, ppv
);