969382a4c93bf7d247803fbef48020350978e5cc
[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 CComPtr<IObjectWithSite> objectWithSite;
1507 CComPtr<IContextMenu> contextMenu;
1508 CMINVOKECOMMANDINFO commandInfo;
1509 const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1510 HRESULT hResult;
1511
1512 // TODO: Query shell if this command is enabled first
1513
1514 memset(&commandInfo, 0, sizeof(commandInfo));
1515 commandInfo.cbSize = sizeof(commandInfo);
1516 commandInfo.hwnd = m_hWnd;
1517 commandInfo.lpParameters = searchGUID;
1518 commandInfo.nShow = SW_SHOWNORMAL;
1519
1520 hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1521 IID_PPV_ARG(IContextMenu, &contextMenu));
1522 if (FAILED_UNEXPECTEDLY(hResult))
1523 return 0;
1524 hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1525 if (FAILED_UNEXPECTEDLY(hResult))
1526 return 0;
1527 hResult = objectWithSite->SetSite(fSite);
1528 if (FAILED_UNEXPECTEDLY(hResult))
1529 return 0;
1530 hResult = contextMenu->InvokeCommand(&commandInfo);
1531 hResult = objectWithSite->SetSite(NULL);
1532 return 0;
1533 }
1534
1535 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1536 {
1537 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL);
1538 return 1;
1539 }
1540
1541 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1542 {
1543 HRESULT hResult;
1544
1545 if (fCommandTarget.p != NULL)
1546 {
1547 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1548 }
1549 return 1;
1550 }
1551
1552 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1553 {
1554 CComPtr<IBrowserService> browserService;
1555 CComPtr<IOleCommandTarget> commandTarget;
1556 CComPtr<ITravelLog> travelLog;
1557 NMTOOLBARW *notifyInfo;
1558 RECT bounds;
1559 HMENU newMenu;
1560 TPMPARAMS params;
1561 int selectedItem;
1562 VARIANT parmIn;
1563 OLECMD commandInfo;
1564 HRESULT hResult;
1565
1566 notifyInfo = (NMTOOLBARW *)pNMHDR;
1567 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1568 {
1569 // not from the toolbar, keep looking for a message handler
1570 bHandled = FALSE;
1571 return 0;
1572 }
1573 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1574 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1575 switch (notifyInfo->iItem)
1576 {
1577 case IDM_GOTO_BACK:
1578 newMenu = CreatePopupMenu();
1579 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1580 hResult = browserService->GetTravelLog(&travelLog);
1581 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1582 commandInfo.cmdID = 0x1d;
1583 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1584 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1585 travelLog->CountEntries(browserService) > 1)
1586 {
1587 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1588 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1589 }
1590 params.cbSize = sizeof (params);
1591 params.rcExclude = bounds;
1592 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1593 bounds.left, bounds.bottom, m_hWnd, &params);
1594 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1595 {
1596 V_VT(&parmIn) = VT_I4;
1597 V_I4(&parmIn) = 1;
1598 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1599 }
1600 else if (selectedItem != 0)
1601 hResult = travelLog->Travel(browserService, -selectedItem);
1602 DestroyMenu(newMenu);
1603 break;
1604 case IDM_GOTO_FORWARD:
1605 newMenu = CreatePopupMenu();
1606 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1607 hResult = browserService->GetTravelLog(&travelLog);
1608 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1609 commandInfo.cmdID = 0x1d;
1610 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1611 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1612 travelLog->CountEntries(browserService) > 1)
1613 {
1614 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1615 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1616 }
1617 params.cbSize = sizeof (params);
1618 params.rcExclude = bounds;
1619 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1620 bounds.left, bounds.bottom, m_hWnd, &params);
1621 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1622 {
1623 V_VT(&parmIn) = VT_I4;
1624 V_I4(&parmIn) = 1;
1625 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1626 }
1627 else if (selectedItem != 0)
1628 hResult = travelLog->Travel(browserService, selectedItem);
1629 DestroyMenu(newMenu);
1630 break;
1631 case gViewsCommandID:
1632 VARIANT inValue;
1633 CComVariant outValue;
1634 HRESULT hResult;
1635
1636 V_VT(&inValue) = VT_INT_PTR;
1637 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1638
1639 if (fCommandTarget.p != NULL)
1640 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue);
1641 // pvaOut is VT_I4 with value 0x403
1642 break;
1643 }
1644 return TBDDRET_DEFAULT;
1645 }
1646
1647 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1648 {
1649 return 1;
1650 }
1651
1652 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1653 {
1654 return 1;
1655 }
1656
1657 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1658 {
1659 HMENU contextMenuBar;
1660 HMENU contextMenu;
1661 POINT clickLocation;
1662 int command;
1663 RBHITTESTINFO hitTestInfo;
1664 REBARBANDINFOW rebarBandInfo;
1665 int bandID;
1666
1667 clickLocation.x = LOWORD(lParam);
1668 clickLocation.y = HIWORD(lParam);
1669 hitTestInfo.pt = clickLocation;
1670 ScreenToClient(&hitTestInfo.pt);
1671 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1672 if (hitTestInfo.iBand == -1)
1673 return 0;
1674 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1675 rebarBandInfo.fMask = RBBIM_ID;
1676 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1677 bandID = rebarBandInfo.wID;
1678 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1679 contextMenu = GetSubMenu(contextMenuBar, 0);
1680 switch (bandID)
1681 {
1682 case ITBBID_MENUBAND: // menu band
1683 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1684 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1685 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1686 break;
1687 case ITBBID_BRANDBAND: // brand band
1688 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1689 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1690 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1691 break;
1692 case ITBBID_TOOLSBAND: // tools band
1693 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1694 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1695 break;
1696 case ITBBID_ADDRESSBAND: // navigation band
1697 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1698 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1699 break;
1700 default:
1701 break;
1702 }
1703
1704 // TODO: Implement show/hide toolbars
1705 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, FALSE);
1706 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, FALSE);
1707 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1708 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1709
1710 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, fControlsBar != NULL);
1711 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, fNavigationBar != NULL);
1712 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1713 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1714 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked);
1715
1716 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1717 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1718 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1719 switch (command)
1720 {
1721 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1722 break;
1723 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1724 break;
1725 case IDM_TOOLBARS_LINKSBAR: // links
1726 break;
1727 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1728 LockUnlockToolbars(!fLocked);
1729 break;
1730 case IDM_TOOLBARS_CUSTOMIZE: // customize
1731 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1732 break;
1733 }
1734
1735 DestroyMenu(contextMenuBar);
1736 return 1;
1737 }
1738
1739 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1740 {
1741 if (wParam != SIZE_MINIMIZED)
1742 {
1743 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1744 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1745 }
1746 return 1;
1747 }
1748
1749 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1750 {
1751 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1752 {
1753 bHandled = FALSE;
1754 return 0;
1755 }
1756 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1757 return 1;
1758 }
1759
1760 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1761 {
1762 CComPtr<IBrowserService> browserService;
1763 CComPtr<ITravelLog> travelLog;
1764 TOOLTIPTEXTW *pTTTW;
1765 UINT nID;
1766 wchar_t tempString[300];
1767 HRESULT hResult;
1768
1769 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1770 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1771 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1772 else
1773 nID = (UINT)pNMHDR->idFrom;
1774
1775 if (nID != 0)
1776 {
1777 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1778 {
1779 // TODO: Should this call QueryService?
1780 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1781 hResult = browserService->GetTravelLog(&travelLog);
1782 hResult = travelLog->GetToolTipText(browserService,
1783 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1784 0, tempString, 299);
1785 if (FAILED_UNEXPECTEDLY(hResult))
1786 {
1787 bHandled = FALSE;
1788 return 0;
1789 }
1790 }
1791 else
1792 tempString[0] = 0;
1793 wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
1794 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1795 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1796 return 0;
1797 }
1798 return 0;
1799 }
1800
1801 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1802 {
1803 LRESULT theResult;
1804 HRESULT hResult;
1805
1806 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1807
1808 bHandled = hResult == S_OK;
1809
1810 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1811 }
1812 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1813 {
1814 NMHDR *notifyHeader;
1815 LRESULT theResult;
1816 HRESULT hResult;
1817
1818 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1819
1820 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1821
1822 bHandled = hResult == S_OK;
1823
1824 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1825 }
1826
1827 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1828 {
1829 bHandled = FALSE;
1830 if (fLocked)
1831 return 0;
1832
1833 if (wParam & MK_CONTROL)
1834 return 0;
1835
1836 fSizing = TRUE;
1837
1838 DWORD msgp = GetMessagePos();
1839
1840 fStartPosition.x = GET_X_LPARAM(msgp);
1841 fStartPosition.y = GET_Y_LPARAM(msgp);
1842
1843 RECT rc;
1844 GetWindowRect(m_hWnd, &rc);
1845
1846 fStartHeight = rc.bottom - rc.top;
1847
1848 SetCapture();
1849
1850 bHandled = TRUE;
1851 return 0;
1852 }
1853
1854 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1855 {
1856 bHandled = FALSE;
1857 if (!fSizing)
1858 return 0;
1859
1860 DWORD msgp = GetMessagePos();
1861
1862 POINT pt;
1863 pt.x = GET_X_LPARAM(msgp);
1864 pt.y = GET_Y_LPARAM(msgp);
1865
1866 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1867
1868 bHandled = TRUE;
1869 return 0;
1870 }
1871
1872 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1873 {
1874 bHandled = FALSE;
1875 if (!fSizing)
1876 return 0;
1877
1878 OnMouseMove(uMsg, wParam, lParam, bHandled);
1879
1880 fSizing = FALSE;
1881
1882 ReleaseCapture();
1883
1884 return 0;
1885 }
1886
1887 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1888 {
1889 return ShellObjectCreator<CInternetToolbar>(riid, ppv);
1890 }