fdd7aa46295866e605357fa3a0b6e1638945495d
[reactos.git] / reactos / dll / win32 / browseui / internettoolbar.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5 *
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.
10 *
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.
15 *
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
19 */
20
21 /*
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
24 */
25
26 #include "precomp.h"
27
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))
31
32 #if 1
33
34 interface IAugmentedShellFolder : public IShellFolder
35 {
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;
40 };
41
42 #endif
43
44 // navigation controls and menubar just send a message to parent window
45 /*
46 TODO:
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
54
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)
66 Implement IBandSite
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
70 Add theme support
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
78 */
79
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);
85
86 HRESULT IUnknown_RelayWinEvent(IUnknown * punk, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
87 {
88 CComPtr<IWinEventHandler> menuWinEventHandler;
89 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
90 if (FAILED_UNEXPECTEDLY(hResult))
91 return hResult;
92 hResult = menuWinEventHandler->IsWindowOwner(hWnd);
93 if (FAILED_UNEXPECTEDLY(hResult))
94 return hResult;
95 if (hResult == S_OK)
96 return menuWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
97 return S_FALSE;
98 }
99
100 HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow)
101 {
102 CComPtr<IDockingWindow> dockingWindow;
103 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
104 if (FAILED_UNEXPECTEDLY(hResult))
105 return hResult;
106 hResult = dockingWindow->ShowDW(fShow);
107 if (FAILED_UNEXPECTEDLY(hResult))
108 return hResult;
109 return S_OK;
110 }
111
112 HRESULT IUnknown_CloseDW(IUnknown * punk, DWORD dwReserved)
113 {
114 CComPtr<IDockingWindow> dockingWindow;
115 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
116 if (FAILED_UNEXPECTEDLY(hResult))
117 return hResult;
118 hResult = dockingWindow->CloseDW(dwReserved);
119 if (FAILED_UNEXPECTEDLY(hResult))
120 return hResult;
121 return S_OK;
122 }
123
124 class CInternetToolbar;
125
126 class CDockSite :
127 public CComObjectRootEx<CComMultiThreadModelNoCS>,
128 public IDockingWindowSite,
129 public IInputObjectSite,
130 public IOleCommandTarget,
131 public IServiceProvider
132 {
133 public:
134 enum {
135 ITF_NOGRIPPER = 1,
136 ITF_NOTITLE = 2,
137 ITF_NEWBANDALWAYS = 4,
138 ITF_GRIPPERALWAYS = 8,
139 ITF_FIXEDSIZE = 16
140 };
141 private:
142 CComPtr<IUnknown> fContainedBand; // the band inside us
143 CInternetToolbar *fToolbar; // our browser
144 HWND fRebarWindow;
145 HWND fChildWindow;
146 int fBandID;
147 public:
148 int fFlags;
149 private:
150 bool fInitialized;
151 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
152 DESKBANDINFO fDeskBandInfo;
153 public:
154 CDockSite();
155 ~CDockSite();
156 HRESULT Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags);
157 HRESULT GetRBBandInfo(REBARBANDINFOW &bandInfo);
158 private:
159
160 // *** IOleWindow methods ***
161 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
162 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
163
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);
168
169 // *** IInputObjectSite specific methods ***
170 virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus);
171
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);
177
178 // *** IServiceProvider methods ***
179 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
180
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)
187 END_COM_MAP()
188 };
189
190 CDockSite::CDockSite()
191 {
192 fToolbar = NULL;
193 fRebarWindow = NULL;
194 fChildWindow = NULL;
195 fBandID = 0;
196 fFlags = 0;
197 fInitialized = false;
198 memset(&fDeskBandInfo, 0, sizeof(fDeskBandInfo));
199 }
200
201 CDockSite::~CDockSite()
202 {
203 }
204
205 HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags)
206 {
207 TCHAR textBuffer[40];
208 REBARBANDINFOW bandInfo;
209 HRESULT hResult;
210
211 fContainedBand = containedBand;
212 fToolbar = browser;
213 fRebarWindow = hwnd;
214 fBandID = bandID;
215 fFlags = flags;
216 hResult = IUnknown_SetSite(containedBand, static_cast<IOleWindow *>(this));
217 if (FAILED_UNEXPECTEDLY(hResult))
218 return hResult;
219 hResult = IUnknown_GetWindow(containedBand, &fChildWindow);
220 if (FAILED_UNEXPECTEDLY(hResult))
221 return hResult;
222
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);
228
229 SendMessage(fRebarWindow, RB_GETBANDCOUNT, 0, 0);
230 SendMessage(fRebarWindow, RB_INSERTBANDW, -1, (LPARAM)&bandInfo);
231 fInitialized = true;
232 return S_OK;
233 }
234
235 HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
236 {
237 CComPtr<IDeskBand> deskBand;
238 HRESULT hResult;
239
240 hResult = fContainedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand));
241 if (FAILED_UNEXPECTEDLY(hResult))
242 return hResult;
243
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
248
249 bandInfo.fMask = RBBIM_LPARAM | RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_CHILDSIZE | RBBIM_CHILD |
250 RBBIM_TEXT | RBBIM_STYLE;
251
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;
269
270 if (fDeskBandInfo.dwModeFlags & DBIMF_BKCOLOR)
271 {
272 bandInfo.fMask |= RBBIM_COLORS;
273 bandInfo.clrFore = CLR_DEFAULT;
274 bandInfo.clrBack = fDeskBandInfo.crBkgnd;
275 }
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);
286 return S_OK;
287 }
288
289 HRESULT STDMETHODCALLTYPE CDockSite::GetWindow(HWND *lphwnd)
290 {
291 if (lphwnd == NULL)
292 return E_POINTER;
293 *lphwnd = fRebarWindow;
294 return S_OK;
295 }
296
297 HRESULT STDMETHODCALLTYPE CDockSite::ContextSensitiveHelp(BOOL fEnterMode)
298 {
299 return E_NOTIMPL;
300 }
301
302 HRESULT STDMETHODCALLTYPE CDockSite::GetBorderDW(IUnknown* punkObj, LPRECT prcBorder)
303 {
304 return E_NOTIMPL;
305 }
306
307 HRESULT STDMETHODCALLTYPE CDockSite::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
308 {
309 return E_NOTIMPL;
310 }
311
312 HRESULT STDMETHODCALLTYPE CDockSite::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
313 {
314 return E_NOTIMPL;
315 }
316
317 HRESULT STDMETHODCALLTYPE CDockSite::OnFocusChangeIS (IUnknown *punkObj, BOOL fSetFocus)
318 {
319 return E_NOTIMPL;
320 }
321
322 HRESULT STDMETHODCALLTYPE CDockSite::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
323 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
324 {
325 return E_NOTIMPL;
326 }
327
328 HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt,
329 VARIANT *pvaIn, VARIANT *pvaOut)
330 {
331 TCHAR textBuffer[40];
332 REBARBANDINFOW bandInfo;
333 int index;
334 HRESULT hResult;
335
336 if (IsEqualIID(*pguidCmdGroup, CGID_DeskBand))
337 {
338 switch (nCmdID)
339 {
340 case DBID_BANDINFOCHANGED:
341 if (fInitialized == false)
342 return S_OK;
343 if (V_VT(pvaIn) != VT_I4)
344 return E_INVALIDARG;
345 if (V_I4(pvaIn) != fBandID)
346 return E_FAIL;
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))
355 return hResult;
356 index = (int)SendMessage(fRebarWindow, RB_IDTOINDEX, fBandID, 0);
357 SendMessage(fRebarWindow, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
358 return S_OK;
359 }
360 }
361 return E_FAIL;
362 }
363
364 HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
365 {
366 if (IsEqualIID(guidService, SID_SMenuBandParent))
367 return this->QueryInterface(riid, ppvObject);
368
369 return fToolbar->QueryService(guidService, riid, ppvObject);
370 }
371
372 CMenuCallback::CMenuCallback()
373 {
374 }
375
376 CMenuCallback::~CMenuCallback()
377 {
378 }
379
380 static HRESULT BindToDesktop(LPCITEMIDLIST pidl, IShellFolder ** ppsfResult)
381 {
382 HRESULT hr;
383 CComPtr<IShellFolder> psfDesktop;
384
385 *ppsfResult = NULL;
386
387 hr = SHGetDesktopFolder(&psfDesktop);
388 if (FAILED(hr))
389 return hr;
390
391 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, ppsfResult));
392
393 return hr;
394 }
395
396 static HRESULT GetFavoritesFolder(IShellFolder ** ppsfFavorites, LPITEMIDLIST * ppidl)
397 {
398 HRESULT hr;
399 LPITEMIDLIST pidlUserFavorites;
400 LPITEMIDLIST pidlCommonFavorites;
401 CComPtr<IShellFolder> psfUserFavorites;
402 CComPtr<IShellFolder> psfCommonFavorites;
403 CComPtr<IAugmentedShellFolder> pasf;
404
405 if (ppsfFavorites)
406 *ppsfFavorites = NULL;
407
408 if (ppidl)
409 *ppidl = NULL;
410
411 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidlUserFavorites);
412 if (FAILED(hr))
413 {
414 WARN("Failed to get the USER favorites folder. Trying to run with just the COMMON one.\n");
415
416 hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_FAVORITES, &pidlCommonFavorites);
417 if (FAILED_UNEXPECTEDLY(hr))
418 return hr;
419
420 TRACE("COMMON favorites obtained.\n");
421 *ppidl = pidlCommonFavorites;
422 hr = BindToDesktop(pidlCommonFavorites, ppsfFavorites);
423 return hr;
424 }
425
426 hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_FAVORITES, &pidlCommonFavorites);
427 if (FAILED_UNEXPECTEDLY(hr))
428 {
429 WARN("Failed to get the COMMON favorites folder. Will use only the USER contents.\n");
430 *ppidl = pidlCommonFavorites;
431 hr = BindToDesktop(pidlUserFavorites, ppsfFavorites);
432 return hr;
433 }
434
435 TRACE("Both COMMON and USER favorites folders obtained, merging them...\n");
436
437 hr = BindToDesktop(pidlUserFavorites, &psfUserFavorites);
438 if (FAILED_UNEXPECTEDLY(hr))
439 return hr;
440
441 hr = BindToDesktop(pidlCommonFavorites, &psfCommonFavorites);
442 if (FAILED_UNEXPECTEDLY(hr))
443 return hr;
444
445 hr = CreateMergedFolder(IID_PPV_ARG(IAugmentedShellFolder, &pasf));
446 if (FAILED_UNEXPECTEDLY(hr))
447 {
448 *ppsfFavorites = psfUserFavorites.Detach();
449 *ppidl = pidlUserFavorites;
450 ILFree(pidlCommonFavorites);
451 return hr;
452 }
453
454 hr = pasf->AddNameSpace(NULL, psfUserFavorites, pidlUserFavorites, 0xFF00);
455 if (FAILED_UNEXPECTEDLY(hr))
456 return hr;
457
458 hr = pasf->AddNameSpace(NULL, psfCommonFavorites, pidlCommonFavorites, 0);
459 if (FAILED_UNEXPECTEDLY(hr))
460 return hr;
461
462 hr = pasf->QueryInterface(IID_PPV_ARG(IShellFolder, ppsfFavorites));
463 pasf.Release();
464
465 // TODO: obtain the folder's PIDL
466
467 ILFree(pidlCommonFavorites);
468 ILFree(pidlUserFavorites);
469
470 return hr;
471 }
472
473 HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, void **ppvObject)
474 {
475 CComPtr<IShellMenu> parentMenu;
476 CComPtr<IShellMenu> newMenu;
477 CComPtr<IShellFolder> favoritesFolder;
478 LPITEMIDLIST favoritesPIDL;
479 HWND ownerWindow;
480 HMENU parentHMenu;
481 HMENU favoritesHMenu;
482 HKEY orderRegKey;
483 DWORD disposition;
484 HRESULT hResult;
485 static const TCHAR szFavoritesKey[] =
486 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
487
488 if (!IsEqualIID(riid, IID_IShellMenu))
489 return E_FAIL;
490 if (psmd->uId != FCIDM_MENU_FAVORITES)
491 return E_FAIL;
492
493 // create favorites menu
494 hResult = psmd->punk->QueryInterface(IID_PPV_ARG(IShellMenu, &parentMenu));
495 if (FAILED_UNEXPECTEDLY(hResult))
496 return hResult;
497 hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL);
498 if (FAILED_UNEXPECTEDLY(hResult))
499 return hResult;
500 favoritesHMenu = GetSubMenu(parentHMenu, 3);
501 if (favoritesHMenu == NULL)
502 return E_FAIL;
503
504 if (fFavoritesMenu.p == NULL)
505 {
506 hResult = CreateMenuBand(IID_PPV_ARG(IShellMenu, &newMenu));
507 if (FAILED_UNEXPECTEDLY(hResult))
508 return hResult;
509 hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED);
510 if (FAILED_UNEXPECTEDLY(hResult))
511 return hResult;
512
513 RegCreateKeyEx(HKEY_CURRENT_USER, szFavoritesKey,
514 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &orderRegKey, &disposition);
515
516 hResult = GetFavoritesFolder(&favoritesFolder, &favoritesPIDL);
517 if (FAILED_UNEXPECTEDLY(hResult))
518 return hResult;
519
520 hResult = newMenu->SetShellFolder(favoritesFolder, favoritesPIDL, orderRegKey, SMSET_BOTTOM | SMINIT_CACHED | SMINV_ID);
521 if (favoritesPIDL)
522 ILFree(favoritesPIDL);
523
524 if (FAILED(hResult))
525 return hResult;
526
527 fFavoritesMenu = newMenu;
528 }
529
530 hResult = fFavoritesMenu->SetMenu(favoritesHMenu, ownerWindow, SMSET_TOP | SMSET_DONTOWN);
531 if (FAILED_UNEXPECTEDLY(hResult))
532 return hResult;
533
534 return fFavoritesMenu->QueryInterface(riid, ppvObject);
535 }
536
537 HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam)
538 {
539 switch (uMsg)
540 {
541 case SMC_INITMENU:
542 break;
543 case SMC_CREATE:
544 break;
545 case SMC_EXITMENU:
546 break;
547 case SMC_GETINFO:
548 {
549 SMINFO *infoPtr = reinterpret_cast<SMINFO *>(lParam);
550 if ((infoPtr->dwMask & SMIM_FLAGS) != 0)
551 {
552 if (psmd->uId == FCIDM_MENU_FAVORITES)
553 {
554 infoPtr->dwFlags |= SMIF_DROPCASCADE;
555 }
556 else
557 {
558 infoPtr->dwFlags |= SMIF_TRACKPOPUP;
559 }
560 }
561 if ((infoPtr->dwMask & SMIM_ICON) != 0)
562 infoPtr->iIcon = -1;
563 return S_OK;
564 }
565 case SMC_GETSFINFO:
566 break;
567 case SMC_GETOBJECT:
568 return GetObject(psmd, *reinterpret_cast<IID *>(wParam), reinterpret_cast<void **>(lParam));
569 case SMC_GETSFOBJECT:
570 break;
571 case SMC_EXEC:
572 PostMessageW(psmd->hwnd, WM_COMMAND, psmd->uId, 0);
573 break;
574 case SMC_SFEXEC:
575 SHInvokeDefaultCommand(psmd->hwnd, psmd->psf, psmd->pidlItem);
576 break;
577 case SMC_SFSELECTITEM:
578 break;
579 case 13:
580 // return tooltip
581 break;
582 case SMC_REFRESH:
583 break;
584 case SMC_DEMOTE:
585 break;
586 case SMC_PROMOTE:
587 break;
588 case 0x13:
589 break;
590 case SMC_DEFAULTICON:
591 break;
592 case SMC_NEWITEM:
593 break;
594 case SMC_CHEVRONEXPAND:
595 break;
596 case SMC_DISPLAYCHEVRONTIP:
597 break;
598 case SMC_SETSFOBJECT:
599 break;
600 case SMC_SHCHANGENOTIFY:
601 break;
602 case SMC_CHEVRONGETTIP:
603 break;
604 case SMC_SFDDRESTRICTED:
605 break;
606 case 0x35:
607 break;
608 case 49:
609 break;
610 case 0x10000000:
611 break;
612 }
613 return S_FALSE;
614 }
615
616 CInternetToolbar::CInternetToolbar()
617 {
618 fMainReBar = NULL;
619 fLocked = false;
620 fMenuBandWindow = NULL;
621 fNavigationWindow = NULL;
622 fMenuCallback = new CComObject<CMenuCallback>();
623 fToolbarWindow = NULL;
624 fAdviseCookie = 0;
625
626 fMenuCallback->AddRef();
627 }
628
629 CInternetToolbar::~CInternetToolbar()
630 {
631 }
632
633 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
634 {
635 CComPtr<CDockSite> newSite;
636
637 newSite = new CComObject<CDockSite>;
638 newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
639 }
640
641 HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
642 {
643 CComPtr<IDockingWindowSite> dockingWindowSite;
644 RECT availableBorderSpace;
645
646 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
647 if (FAILED_UNEXPECTEDLY(hResult))
648 return hResult;
649 hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
650 if (FAILED_UNEXPECTEDLY(hResult))
651 return hResult;
652
653 if (availableBorderSpace.top > maxHeight)
654 {
655 availableBorderSpace.top = maxHeight;
656 }
657
658 return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
659 }
660
661 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar)
662 {
663 CComPtr<IShellMenu> menubar;
664 CComPtr<IShellMenuCallback> callback;
665 VARIANT menuOut;
666 HWND ownerWindow;
667 HRESULT hResult;
668
669 if (!pMenuBar)
670 return E_POINTER;
671
672 *pMenuBar = NULL;
673
674 hResult = CreateMenuBand(IID_PPV_ARG(IShellMenu, &menubar));
675 if (FAILED_UNEXPECTEDLY(hResult))
676 return hResult;
677
678 hResult = fMenuCallback->QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
679 if (FAILED_UNEXPECTEDLY(hResult))
680 return hResult;
681
682 hResult = menubar->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
683 if (FAILED_UNEXPECTEDLY(hResult))
684 return hResult;
685
686 // Set Menu
687 {
688 hResult = IUnknown_Exec(fSite, CGID_Explorer, 0x35, 0, NULL, &menuOut);
689 if (FAILED_UNEXPECTEDLY(hResult))
690 return hResult;
691
692 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
693 return E_FAIL;
694
695 hResult = IUnknown_GetWindow(fSite, &ownerWindow);
696 if (FAILED_UNEXPECTEDLY(hResult))
697 return hResult;
698
699 HMENU hMenuBar = (HMENU) V_INTREF(&menuOut);
700
701 // FIXME: Figure out the proper way to do this.
702 HMENU hMenuFavs = GetSubMenu(hMenuBar, 3);
703 if (hMenuFavs)
704 {
705 DeleteMenu(hMenuFavs, IDM_FAVORITES_EMPTY, MF_BYCOMMAND);
706 }
707
708 hResult = menubar->SetMenu(hMenuBar, ownerWindow, SMSET_DONTOWN);
709 if (FAILED_UNEXPECTEDLY(hResult))
710 return hResult;
711 }
712
713 hResult = IUnknown_Exec(menubar, CGID_MenuBand, 3, 1, NULL, NULL);
714 if (FAILED_UNEXPECTEDLY(hResult))
715 return hResult;
716
717 *pMenuBar = menubar.Detach();
718
719 return S_OK;
720 }
721
722 HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
723 {
724 #if 1
725 return ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
726 #else
727 return CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
728 #endif
729 }
730
731 HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
732 {
733 return ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
734 }
735
736 HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
737 {
738 #if 1
739 return ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
740 #else
741 return CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
742 #endif
743 }
744
745 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
746 {
747 REBARBANDINFOW rebarBandInfo;
748 int bandCount;
749 CDockSite *dockSite;
750 HRESULT hResult;
751
752 if (locked != fLocked)
753 {
754 fLocked = locked;
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++)
759 {
760 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
761 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
762 if (dockSite != NULL)
763 {
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);
770 }
771 }
772 hResult = ReserveBorderSpace();
773
774 // TODO: refresh view menu?
775 }
776 return S_OK;
777 }
778
779 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
780 {
781 HRESULT hResult;
782
783 hResult = S_OK;
784 switch (commandID)
785 {
786 case -1:
787 // loop through buttons
788 //for buttons in CLSID_CommonButtons
789 // if up, QueryStatus for up state and update it
790 //
791 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
792 break;
793 case 1:
794 // forward
795 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0);
796 break;
797 case 2:
798 // back
799 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0);
800 break;
801 case 3:
802 // up
803 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_UPONELEVEL, newValue ? TBSTATE_ENABLED : 0);
804 break;
805 }
806 return hResult;
807 }
808
809 HRESULT CInternetToolbar::CreateAndInitBandProxy()
810 {
811 CComPtr<IServiceProvider> serviceProvider;
812 HRESULT hResult;
813
814 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
815 if (FAILED_UNEXPECTEDLY(hResult))
816 return hResult;
817 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
818 if (FAILED_UNEXPECTEDLY(hResult))
819 {
820 hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
821 if (FAILED_UNEXPECTEDLY(hResult))
822 return hResult;
823 hResult = fBandProxy->SetSite(fSite);
824 if (FAILED_UNEXPECTEDLY(hResult))
825 return hResult;
826 }
827 return S_OK;
828 }
829
830 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
831 {
832 return E_NOTIMPL;
833 }
834
835 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
836 {
837 HRESULT hr = S_FALSE;
838
839 if (fMenuBar)
840 hr = IUnknown_HasFocusIO(fMenuBar);
841 if (hr != S_FALSE)
842 return hr;
843
844 if (fControlsBar)
845 hr = IUnknown_HasFocusIO(fControlsBar);
846 if (hr != S_FALSE)
847 return hr;
848
849 if (fNavigationBar)
850 hr = IUnknown_HasFocusIO(fNavigationBar);
851 if (hr != S_FALSE)
852 return hr;
853
854 return S_FALSE;
855 }
856
857 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
858 {
859 HRESULT hr = S_FALSE;
860
861 if (fMenuBar)
862 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg);
863 if (hr == S_OK)
864 return hr;
865
866 if (fControlsBar)
867 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg);
868 if (hr == S_OK)
869 return hr;
870
871 if (fNavigationBar)
872 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg);
873 if (hr == S_OK)
874 return hr;
875
876 return S_FALSE;
877 }
878
879 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
880 {
881 if (lphwnd == NULL)
882 return E_POINTER;
883 *lphwnd = m_hWnd;
884 return S_OK;
885 }
886
887 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
888 {
889 return E_NOTIMPL;
890 }
891
892 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
893 {
894 HRESULT hResult;
895
896 // show the bar here
897 if (fShow)
898 {
899 hResult = ReserveBorderSpace();
900 if (FAILED_UNEXPECTEDLY(hResult))
901 return hResult;
902 }
903
904 if (fMenuBar)
905 {
906 hResult = IUnknown_ShowDW(fMenuBar, fShow);
907 if (FAILED_UNEXPECTEDLY(hResult))
908 return hResult;
909 }
910
911 if (fControlsBar)
912 {
913 hResult = IUnknown_ShowDW(fControlsBar, fShow);
914 if (FAILED_UNEXPECTEDLY(hResult))
915 return hResult;
916 }
917 if (fNavigationBar)
918 {
919 hResult = IUnknown_ShowDW(fNavigationBar, fShow);
920 if (FAILED_UNEXPECTEDLY(hResult))
921 return hResult;
922 }
923 if (fLogoBar)
924 {
925 hResult = IUnknown_ShowDW(fLogoBar, fShow);
926 if (FAILED_UNEXPECTEDLY(hResult))
927 return hResult;
928 }
929 return S_OK;
930 }
931
932 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
933 {
934 HRESULT hResult;
935
936 if (fMenuBar)
937 {
938 hResult = IUnknown_CloseDW(fMenuBar, dwReserved);
939 if (FAILED_UNEXPECTEDLY(hResult))
940 return hResult;
941 ReleaseCComPtrExpectZero(fMenuBar);
942 }
943 if (fControlsBar)
944 {
945 hResult = IUnknown_CloseDW(fControlsBar, dwReserved);
946 if (FAILED_UNEXPECTEDLY(hResult))
947 return hResult;
948 ReleaseCComPtrExpectZero(fControlsBar);
949 }
950 if (fNavigationBar)
951 {
952 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved);
953 if (FAILED_UNEXPECTEDLY(hResult))
954 return hResult;
955 ReleaseCComPtrExpectZero(fNavigationBar);
956 }
957 if (fLogoBar)
958 {
959 hResult = IUnknown_CloseDW(fLogoBar, dwReserved);
960 if (FAILED_UNEXPECTEDLY(hResult))
961 return hResult;
962 ReleaseCComPtrExpectZero(fLogoBar);
963 }
964 return S_OK;
965 }
966
967 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
968 IUnknown *punkToolbarSite, BOOL fReserved)
969 {
970 RECT neededBorderSpace;
971 RECT availableBorderSpace = *prcBorder;
972
973 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
974
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;
980 if (!fLocked)
981 neededBorderSpace.top += 3;
982 neededBorderSpace.right = 0;
983 neededBorderSpace.bottom = 0;
984
985 CComPtr<IDockingWindowSite> dockingWindowSite;
986
987 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
988 if (FAILED_UNEXPECTEDLY(hResult))
989 return hResult;
990
991 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
992 if (FAILED_UNEXPECTEDLY(hResult))
993 return hResult;
994
995 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
996 if (FAILED_UNEXPECTEDLY(hResult))
997 return hResult;
998
999 return S_OK;
1000 }
1001
1002 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
1003 {
1004 if (pClassID == NULL)
1005 return E_POINTER;
1006 *pClassID = CLSID_InternetToolbar;
1007 return S_OK;
1008 }
1009
1010 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
1011 {
1012 return E_NOTIMPL;
1013 }
1014
1015 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
1016 {
1017 return E_NOTIMPL;
1018 }
1019
1020 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
1021 {
1022 return E_NOTIMPL;
1023 }
1024
1025 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
1026 {
1027 return E_NOTIMPL;
1028 }
1029
1030 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
1031 {
1032 CComPtr<IShellMenu> menuBar;
1033 CComPtr<IUnknown> logoBar;
1034 CComPtr<IUnknown> toolsBar;
1035 CComPtr<IUnknown> navigationBar;
1036 HRESULT hResult;
1037
1038 /* Create and attach the menubar to the rebar */
1039 hResult = CreateMenuBar(&menuBar);
1040 if (FAILED_UNEXPECTEDLY(hResult))
1041 return hResult;
1042 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1043
1044 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
1045 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
1046
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.
1049 #if 0
1050 /* Create and attach the brand/logo to the rebar */
1051 hResult = CreateBrandBand(&logoBar);
1052 if (FAILED_UNEXPECTEDLY(hResult))
1053 return hResult;
1054 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
1055 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
1056 #endif
1057
1058 /* Create and attach the standard toolbar to the rebar */
1059 hResult = CreateToolsBar(&toolsBar);
1060 if (FAILED_UNEXPECTEDLY(hResult))
1061 return 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))
1066 return hResult;
1067
1068 /* Create and attach the address/navigation toolbar to the rebar */
1069 hResult = CreateAddressBand(&navigationBar);
1070 if (FAILED_UNEXPECTEDLY(hResult))
1071 return hResult;
1072 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1073 fNavigationBar.Attach(navigationBar.Detach());
1074 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
1075
1076 return S_OK;
1077 }
1078
1079 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
1080 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
1081 {
1082 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1083 {
1084 while (cCmds != 0)
1085 {
1086 switch (prgCmds->cmdID)
1087 {
1088 case ITID_TEXTLABELS: // Text Labels state
1089 prgCmds->cmdf = OLECMDF_SUPPORTED;
1090 break;
1091 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
1092 prgCmds->cmdf = OLECMDF_SUPPORTED;
1093 if (fControlsBar)
1094 prgCmds->cmdf |= OLECMDF_LATCHED;
1095 break;
1096 case ITID_ADDRESSBANDSHOWN: // address bar visibility
1097 prgCmds->cmdf = OLECMDF_SUPPORTED;
1098 if (fNavigationBar)
1099 prgCmds->cmdf |= OLECMDF_LATCHED;
1100 break;
1101 case ITID_LINKSBANDSHOWN: // links bar visibility
1102 prgCmds->cmdf = 0;
1103 break;
1104 case ITID_MENUBANDSHOWN: // Menubar band visibility
1105 prgCmds->cmdf = OLECMDF_SUPPORTED;
1106 if (fMenuBar)
1107 prgCmds->cmdf |= OLECMDF_LATCHED;
1108 break;
1109 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
1110 prgCmds->cmdf = 0;
1111 break;
1112 case ITID_CUSTOMIZEENABLED: // customize enabled
1113 prgCmds->cmdf = OLECMDF_SUPPORTED;
1114 break;
1115 case ITID_TOOLBARLOCKED: // lock toolbars
1116 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1117 if (fLocked)
1118 prgCmds->cmdf |= OLECMDF_LATCHED;
1119 break;
1120 default:
1121 prgCmds->cmdf = 0;
1122 break;
1123 }
1124 prgCmds++;
1125 cCmds--;
1126 }
1127 return S_OK;
1128 }
1129 return E_FAIL;
1130 }
1131
1132 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
1133 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1134 {
1135 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1136 {
1137 switch (nCmdID)
1138 {
1139 case 1:
1140 // what do I do here?
1141 return S_OK;
1142 case ITID_TEXTLABELS:
1143 // toggle text labels
1144 return S_OK;
1145 case ITID_TOOLBARBANDSHOWN:
1146 // toggle toolbar band visibility
1147 return S_OK;
1148 case ITID_ADDRESSBANDSHOWN:
1149 // toggle address band visibility
1150 return S_OK;
1151 case ITID_LINKSBANDSHOWN:
1152 // toggle links band visibility
1153 return S_OK;
1154 case ITID_CUSTOMIZEENABLED:
1155 // run customize
1156 return S_OK;
1157 case ITID_TOOLBARLOCKED:
1158 return LockUnlockToolbars(!fLocked);
1159 }
1160 }
1161 return E_FAIL;
1162 }
1163
1164 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
1165 {
1166 return E_NOTIMPL;
1167 }
1168
1169 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1170 {
1171 return E_NOTIMPL;
1172 }
1173
1174 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1175 LCID lcid, DISPID *rgDispId)
1176 {
1177 return E_NOTIMPL;
1178 }
1179
1180 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1181 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1182 {
1183 HRESULT hResult;
1184
1185 switch(dispIdMember)
1186 {
1187 case DISPID_BEFORENAVIGATE:
1188 hResult = S_OK;
1189 break;
1190 case DISPID_DOWNLOADCOMPLETE:
1191 hResult = S_OK;
1192 break;
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:
1201 hResult = S_OK;
1202 break;
1203 case DISPID_NAVIGATECOMPLETE2:
1204 hResult = S_OK;
1205 break;
1206 case DISPID_DOCUMENTCOMPLETE:
1207 hResult = S_OK;
1208 break;
1209 }
1210 return S_OK;
1211 }
1212
1213 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1214 {
1215 HRESULT hResult;
1216
1217 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14);
1218
1219 fCommandTarget.Release();
1220 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1221 if (FAILED_UNEXPECTEDLY(hResult))
1222 return hResult;
1223 fCommandCategory = *category;
1224 return S_OK;
1225 }
1226
1227 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1228 {
1229 return E_NOTIMPL;
1230 }
1231
1232 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1233 {
1234 return E_NOTIMPL;
1235 }
1236
1237 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1238 HINSTANCE param10, LPCTSTR param14, long *param18)
1239 {
1240 long result;
1241
1242 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1243 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1244 *param18 = result;
1245 if (result == -1)
1246 return E_FAIL;
1247 return S_OK;
1248 }
1249
1250 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1251 {
1252 return E_NOTIMPL;
1253 }
1254
1255 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1256 {
1257 if (theState == NULL)
1258 return E_POINTER;
1259 // map the command id
1260 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1261 return S_OK;
1262 }
1263
1264 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1265 {
1266 // map the command id
1267 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1268 return S_OK;
1269 }
1270
1271 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1272 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1273 {
1274 return E_NOTIMPL;
1275 }
1276
1277 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1278 {
1279 if (paramC == NULL)
1280 return E_POINTER;
1281 *paramC = MAKELONG(24, 24);
1282 return S_OK;
1283 }
1284
1285 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1286 WPARAM wParam, LPARAM lParam, LRESULT *result)
1287 {
1288 return E_NOTIMPL;
1289 }
1290
1291 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1292 HIMAGELIST param14, HIMAGELIST param18)
1293 {
1294 return E_NOTIMPL;
1295 }
1296
1297 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1298 {
1299 return E_NOTIMPL;
1300 }
1301
1302 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1303 {
1304 return E_NOTIMPL;
1305 }
1306
1307 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1308 {
1309 CComPtr<IBrowserService> browserService;
1310 HWND ownerWindow;
1311 HWND dockContainer;
1312 HRESULT hResult;
1313
1314 if (pUnkSite == NULL)
1315 {
1316 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1317 ::DestroyWindow(fMainReBar);
1318 DestroyWindow();
1319 fSite.Release();
1320 }
1321 else
1322 {
1323 // get window handle of owner
1324 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow);
1325 if (FAILED_UNEXPECTEDLY(hResult))
1326 return hResult;
1327 if (ownerWindow == NULL)
1328 return E_FAIL;
1329
1330 // create dock container
1331 fSite = pUnkSite;
1332 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
1333 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
1334 if (dockContainer == NULL)
1335 return E_FAIL;
1336 SubclassWindow(dockContainer);
1337
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)
1346 return E_FAIL;
1347
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);
1351 }
1352 return S_OK;
1353 }
1354
1355 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1356 {
1357 if (ppvSite == NULL)
1358 return E_POINTER;
1359 if (fSite.p != NULL)
1360 return fSite->QueryInterface(riid, ppvSite);
1361 *ppvSite = NULL;
1362 return S_OK;
1363 }
1364
1365 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1366 {
1367 HRESULT hResult;
1368
1369 if (IsEqualIID(guidService, IID_IBandSite))
1370 return this->QueryInterface(riid, ppvObject);
1371 if (IsEqualIID(guidService, SID_IBandProxy))
1372 {
1373 if (fBandProxy.p == NULL)
1374 {
1375 hResult = CreateAndInitBandProxy();
1376 if (FAILED_UNEXPECTEDLY(hResult))
1377 return hResult;
1378 }
1379 return fBandProxy->QueryInterface(riid, ppvObject);
1380 }
1381 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1382 }
1383
1384 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1385 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1386 {
1387 HRESULT hResult;
1388
1389 if (fMenuBar)
1390 {
1391 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult);
1392 if (hResult != S_FALSE)
1393 return hResult;
1394 }
1395
1396 if (fNavigationBar)
1397 {
1398 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult);
1399 if (hResult != S_FALSE)
1400 return hResult;
1401 }
1402
1403 if (fLogoBar)
1404 {
1405 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult);
1406 if (hResult != S_FALSE)
1407 return hResult;
1408 }
1409
1410 return S_FALSE;
1411 }
1412
1413 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1414 {
1415 UNIMPLEMENTED;
1416 return E_NOTIMPL;
1417 }
1418
1419 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1420 {
1421 UNIMPLEMENTED;
1422 return E_NOTIMPL;
1423 }
1424
1425 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1426 {
1427 UNIMPLEMENTED;
1428 return E_NOTIMPL;
1429 }
1430
1431 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1432 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1433 {
1434 if (ppstb == NULL)
1435 return E_POINTER;
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));
1440 *ppstb = NULL;
1441 return E_FAIL;
1442 }
1443
1444 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1445 {
1446 UNIMPLEMENTED;
1447 return E_NOTIMPL;
1448 }
1449
1450 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1451 {
1452 UNIMPLEMENTED;
1453 return E_NOTIMPL;
1454 }
1455
1456 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1457 {
1458 UNIMPLEMENTED;
1459 return E_NOTIMPL;
1460 }
1461
1462 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1463 {
1464 UNIMPLEMENTED;
1465 return E_NOTIMPL;
1466 }
1467
1468 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1469 {
1470 UNIMPLEMENTED;
1471 return E_NOTIMPL;
1472 }
1473
1474 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1475 {
1476 CComPtr<IWebBrowser> webBrowser;
1477 HRESULT hResult;
1478
1479 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1480 if (FAILED_UNEXPECTEDLY(hResult))
1481 return 0;
1482 hResult = webBrowser->GoBack();
1483 return 1;
1484 }
1485
1486 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1487 {
1488 CComPtr<IWebBrowser> webBrowser;
1489 HRESULT hResult;
1490
1491 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1492 if (FAILED_UNEXPECTEDLY(hResult))
1493 return 0;
1494 hResult = webBrowser->GoForward();
1495 return 1;
1496 }
1497
1498 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1499 {
1500 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1501 return 1;
1502 }
1503
1504 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1505 {
1506 return IUnknown_Exec(fSite, CLSID_CommonButtons, 0x123, 1, NULL, NULL);
1507 }
1508
1509 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1510 {
1511 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL);
1512 return 1;
1513 }
1514
1515 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1516 {
1517 HRESULT hResult;
1518
1519 if (fCommandTarget.p != NULL)
1520 {
1521 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1522 }
1523 return 1;
1524 }
1525
1526 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1527 {
1528 CComPtr<IBrowserService> browserService;
1529 CComPtr<IOleCommandTarget> commandTarget;
1530 CComPtr<ITravelLog> travelLog;
1531 NMTOOLBARW *notifyInfo;
1532 RECT bounds;
1533 HMENU newMenu;
1534 TPMPARAMS params;
1535 int selectedItem;
1536 VARIANT parmIn;
1537 OLECMD commandInfo;
1538 HRESULT hResult;
1539 wchar_t templateString[200];
1540
1541 notifyInfo = (NMTOOLBARW *)pNMHDR;
1542 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1543 {
1544 // not from the toolbar, keep looking for a message handler
1545 bHandled = FALSE;
1546 return 0;
1547 }
1548 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1549 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1550 switch (notifyInfo->iItem)
1551 {
1552 case IDM_GOTO_BACK:
1553 newMenu = CreatePopupMenu();
1554 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1555 hResult = browserService->GetTravelLog(&travelLog);
1556 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1557 commandInfo.cmdID = 0x1d;
1558 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1559 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1560 travelLog->CountEntries(browserService) > 1)
1561 {
1562 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1563
1564 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1565 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1566 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1567
1568 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1569 }
1570 params.cbSize = sizeof(params);
1571 params.rcExclude = bounds;
1572 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1573 bounds.left, bounds.bottom, m_hWnd, &params);
1574 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1575 {
1576 V_VT(&parmIn) = VT_I4;
1577 V_I4(&parmIn) = 1;
1578 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1579 }
1580 else if (selectedItem != 0)
1581 hResult = travelLog->Travel(browserService, -selectedItem);
1582 DestroyMenu(newMenu);
1583 break;
1584 case IDM_GOTO_FORWARD:
1585 newMenu = CreatePopupMenu();
1586 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1587 hResult = browserService->GetTravelLog(&travelLog);
1588 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1589 commandInfo.cmdID = 0x1d;
1590 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1591 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1592 travelLog->CountEntries(browserService) > 1)
1593 {
1594 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1595
1596 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1597 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1598 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1599
1600 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1601 }
1602 params.cbSize = sizeof(params);
1603 params.rcExclude = bounds;
1604 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1605 bounds.left, bounds.bottom, m_hWnd, &params);
1606 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1607 {
1608 V_VT(&parmIn) = VT_I4;
1609 V_I4(&parmIn) = 1;
1610 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1611 }
1612 else if (selectedItem != 0)
1613 hResult = travelLog->Travel(browserService, selectedItem);
1614 DestroyMenu(newMenu);
1615 break;
1616 case gViewsCommandID:
1617 VARIANT inValue;
1618 CComVariant outValue;
1619 HRESULT hResult;
1620
1621 V_VT(&inValue) = VT_INT_PTR;
1622 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1623
1624 if (fCommandTarget.p != NULL)
1625 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue);
1626 // pvaOut is VT_I4 with value 0x403
1627 break;
1628 }
1629 return TBDDRET_DEFAULT;
1630 }
1631
1632 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1633 {
1634 return 1;
1635 }
1636
1637 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1638 {
1639 return 1;
1640 }
1641
1642 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1643 {
1644 HMENU contextMenuBar;
1645 HMENU contextMenu;
1646 POINT clickLocation;
1647 int command;
1648 RBHITTESTINFO hitTestInfo;
1649 REBARBANDINFOW rebarBandInfo;
1650 int bandID;
1651 BOOL goButtonChecked;
1652
1653 clickLocation.x = LOWORD(lParam);
1654 clickLocation.y = HIWORD(lParam);
1655 hitTestInfo.pt = clickLocation;
1656 ScreenToClient(&hitTestInfo.pt);
1657 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1658 if (hitTestInfo.iBand == -1)
1659 return 0;
1660 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1661 rebarBandInfo.fMask = RBBIM_ID;
1662 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1663 bandID = rebarBandInfo.wID;
1664 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1665 contextMenu = GetSubMenu(contextMenuBar, 0);
1666 switch (bandID)
1667 {
1668 case ITBBID_MENUBAND: // menu band
1669 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1670 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1671 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1672 break;
1673 case ITBBID_BRANDBAND: // brand band
1674 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1675 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1676 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1677 break;
1678 case ITBBID_TOOLSBAND: // tools band
1679 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1680 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1681 break;
1682 case ITBBID_ADDRESSBAND: // navigation band
1683 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1684 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1685 break;
1686 default:
1687 break;
1688 }
1689
1690 // TODO: Implement show/hide toolbars
1691 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, FALSE);
1692 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, FALSE);
1693 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1694 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1695
1696 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, fControlsBar != NULL);
1697 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, fNavigationBar != NULL);
1698 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1699 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1700 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked);
1701 goButtonChecked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE);
1702 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, goButtonChecked);
1703
1704 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1705 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1706 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1707 switch (command)
1708 {
1709 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1710 break;
1711 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1712 break;
1713 case IDM_TOOLBARS_LINKSBAR: // links
1714 break;
1715 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1716 LockUnlockToolbars(!fLocked);
1717 break;
1718 case IDM_TOOLBARS_CUSTOMIZE: // customize
1719 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1720 break;
1721 case IDM_TOOLBARS_GOBUTTON:
1722 SendMessage(fNavigationWindow, WM_COMMAND, IDM_TOOLBARS_GOBUTTON, 0);
1723 break;
1724 }
1725
1726 DestroyMenu(contextMenuBar);
1727 return 1;
1728 }
1729
1730 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1731 {
1732 if (wParam != SIZE_MINIMIZED)
1733 {
1734 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1735 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1736 }
1737 return 1;
1738 }
1739
1740 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1741 {
1742 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1743 {
1744 bHandled = FALSE;
1745 return 0;
1746 }
1747 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1748 return 1;
1749 }
1750
1751 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1752 {
1753 CComPtr<IBrowserService> browserService;
1754 CComPtr<ITravelLog> travelLog;
1755 TOOLTIPTEXTW *pTTTW;
1756 UINT nID;
1757 HRESULT hResult;
1758 wchar_t tempString[300];
1759
1760 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1761 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1762 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1763 else
1764 nID = (UINT)pNMHDR->idFrom;
1765
1766 if (nID != 0)
1767 {
1768 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1769 {
1770 // TODO: Should this call QueryService?
1771 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1772 hResult = browserService->GetTravelLog(&travelLog);
1773 hResult = travelLog->GetToolTipText(browserService,
1774 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1775 0, tempString, 299);
1776 if (FAILED_UNEXPECTEDLY(hResult))
1777 {
1778 bHandled = FALSE;
1779 return 0;
1780 }
1781 }
1782 else
1783 tempString[0] = 0;
1784 wcsncpy (pTTTW->szText, tempString, sizeof(pTTTW->szText) / sizeof(wchar_t));
1785 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1786 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1787 return 0;
1788 }
1789 return 0;
1790 }
1791
1792 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1793 {
1794 LRESULT theResult;
1795 HRESULT hResult;
1796
1797 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1798
1799 bHandled = hResult == S_OK;
1800
1801 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1802 }
1803 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1804 {
1805 NMHDR *notifyHeader;
1806 LRESULT theResult;
1807 HRESULT hResult;
1808
1809 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1810
1811 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1812
1813 bHandled = hResult == S_OK;
1814
1815 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1816 }
1817
1818 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1819 {
1820 bHandled = FALSE;
1821 if (fLocked)
1822 return 0;
1823
1824 if (wParam & MK_CONTROL)
1825 return 0;
1826
1827 fSizing = TRUE;
1828
1829 DWORD msgp = GetMessagePos();
1830
1831 fStartPosition.x = GET_X_LPARAM(msgp);
1832 fStartPosition.y = GET_Y_LPARAM(msgp);
1833
1834 RECT rc;
1835 GetWindowRect(&rc);
1836
1837 fStartHeight = rc.bottom - rc.top;
1838
1839 SetCapture();
1840
1841 bHandled = TRUE;
1842 return 0;
1843 }
1844
1845 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1846 {
1847 bHandled = FALSE;
1848 if (!fSizing)
1849 return 0;
1850
1851 DWORD msgp = GetMessagePos();
1852
1853 POINT pt;
1854 pt.x = GET_X_LPARAM(msgp);
1855 pt.y = GET_Y_LPARAM(msgp);
1856
1857 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1858
1859 bHandled = TRUE;
1860 return 0;
1861 }
1862
1863 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1864 {
1865 bHandled = FALSE;
1866 if (!fSizing)
1867 return 0;
1868
1869 OnMouseMove(uMsg, wParam, lParam, bHandled);
1870
1871 fSizing = FALSE;
1872
1873 ReleaseCapture();
1874
1875 return 0;
1876 }
1877
1878 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1879 {
1880 return ShellObjectCreator<CInternetToolbar>(riid, ppv);
1881 }