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