167c3d4aab7263c03d7124bdc19aa0f03ea7655c
[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 }
802 return hResult;
803 }
804
805 HRESULT CInternetToolbar::CreateAndInitBandProxy()
806 {
807 CComPtr<IServiceProvider> serviceProvider;
808 HRESULT hResult;
809
810 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
811 if (FAILED_UNEXPECTEDLY(hResult))
812 return hResult;
813 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
814 if (FAILED_UNEXPECTEDLY(hResult))
815 {
816 hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
817 if (FAILED_UNEXPECTEDLY(hResult))
818 return hResult;
819 hResult = fBandProxy->SetSite(fSite);
820 if (FAILED_UNEXPECTEDLY(hResult))
821 return hResult;
822 }
823 return S_OK;
824 }
825
826 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
827 {
828 return E_NOTIMPL;
829 }
830
831 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
832 {
833 HRESULT hr = S_FALSE;
834
835 if (fMenuBar)
836 hr = IUnknown_HasFocusIO(fMenuBar);
837 if (hr != S_FALSE)
838 return hr;
839
840 if (fControlsBar)
841 hr = IUnknown_HasFocusIO(fControlsBar);
842 if (hr != S_FALSE)
843 return hr;
844
845 if (fNavigationBar)
846 hr = IUnknown_HasFocusIO(fNavigationBar);
847 if (hr != S_FALSE)
848 return hr;
849
850 return S_FALSE;
851 }
852
853 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
854 {
855 HRESULT hr = S_FALSE;
856
857 if (fMenuBar)
858 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg);
859 if (hr == S_OK)
860 return hr;
861
862 if (fControlsBar)
863 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg);
864 if (hr == S_OK)
865 return hr;
866
867 if (fNavigationBar)
868 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg);
869 if (hr == S_OK)
870 return hr;
871
872 return S_FALSE;
873 }
874
875 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
876 {
877 if (lphwnd == NULL)
878 return E_POINTER;
879 *lphwnd = m_hWnd;
880 return S_OK;
881 }
882
883 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
884 {
885 return E_NOTIMPL;
886 }
887
888 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
889 {
890 HRESULT hResult;
891
892 // show the bar here
893 if (fShow)
894 {
895 hResult = ReserveBorderSpace();
896 if (FAILED_UNEXPECTEDLY(hResult))
897 return hResult;
898 }
899
900 if (fMenuBar)
901 {
902 hResult = IUnknown_ShowDW(fMenuBar, fShow);
903 if (FAILED_UNEXPECTEDLY(hResult))
904 return hResult;
905 }
906
907 if (fControlsBar)
908 {
909 hResult = IUnknown_ShowDW(fControlsBar, fShow);
910 if (FAILED_UNEXPECTEDLY(hResult))
911 return hResult;
912 }
913 if (fNavigationBar)
914 {
915 hResult = IUnknown_ShowDW(fNavigationBar, fShow);
916 if (FAILED_UNEXPECTEDLY(hResult))
917 return hResult;
918 }
919 if (fLogoBar)
920 {
921 hResult = IUnknown_ShowDW(fLogoBar, fShow);
922 if (FAILED_UNEXPECTEDLY(hResult))
923 return hResult;
924 }
925 return S_OK;
926 }
927
928 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
929 {
930 HRESULT hResult;
931
932 if (fMenuBar)
933 {
934 hResult = IUnknown_CloseDW(fMenuBar, dwReserved);
935 if (FAILED_UNEXPECTEDLY(hResult))
936 return hResult;
937 ReleaseCComPtrExpectZero(fMenuBar);
938 }
939 if (fControlsBar)
940 {
941 hResult = IUnknown_CloseDW(fControlsBar, dwReserved);
942 if (FAILED_UNEXPECTEDLY(hResult))
943 return hResult;
944 ReleaseCComPtrExpectZero(fControlsBar);
945 }
946 if (fNavigationBar)
947 {
948 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved);
949 if (FAILED_UNEXPECTEDLY(hResult))
950 return hResult;
951 ReleaseCComPtrExpectZero(fNavigationBar);
952 }
953 if (fLogoBar)
954 {
955 hResult = IUnknown_CloseDW(fLogoBar, dwReserved);
956 if (FAILED_UNEXPECTEDLY(hResult))
957 return hResult;
958 ReleaseCComPtrExpectZero(fLogoBar);
959 }
960 return S_OK;
961 }
962
963 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
964 IUnknown *punkToolbarSite, BOOL fReserved)
965 {
966 RECT neededBorderSpace;
967 RECT availableBorderSpace = *prcBorder;
968
969 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
970
971 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
972 // Let's make sure we fetch the actual size properly.
973 GetWindowRect(fMainReBar, &availableBorderSpace);
974 neededBorderSpace.left = 0;
975 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
976 if (!fLocked)
977 neededBorderSpace.top += 3;
978 neededBorderSpace.right = 0;
979 neededBorderSpace.bottom = 0;
980
981 CComPtr<IDockingWindowSite> dockingWindowSite;
982
983 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
984 if (FAILED_UNEXPECTEDLY(hResult))
985 return hResult;
986
987 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
988 if (FAILED_UNEXPECTEDLY(hResult))
989 return hResult;
990
991 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
992 if (FAILED_UNEXPECTEDLY(hResult))
993 return hResult;
994
995 return S_OK;
996 }
997
998 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
999 {
1000 if (pClassID == NULL)
1001 return E_POINTER;
1002 *pClassID = CLSID_InternetToolbar;
1003 return S_OK;
1004 }
1005
1006 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
1007 {
1008 return E_NOTIMPL;
1009 }
1010
1011 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
1012 {
1013 return E_NOTIMPL;
1014 }
1015
1016 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
1017 {
1018 return E_NOTIMPL;
1019 }
1020
1021 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
1022 {
1023 return E_NOTIMPL;
1024 }
1025
1026 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
1027 {
1028 CComPtr<IShellMenu> menuBar;
1029 CComPtr<IUnknown> logoBar;
1030 CComPtr<IUnknown> toolsBar;
1031 CComPtr<IUnknown> navigationBar;
1032 HRESULT hResult;
1033
1034 /* Create and attach the menubar to the rebar */
1035 hResult = CreateMenuBar(&menuBar);
1036 if (FAILED_UNEXPECTEDLY(hResult))
1037 return hResult;
1038 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1039
1040 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
1041 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
1042
1043 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1044 // and it will put them in their own row, sized to take up the whole row.
1045 #if 0
1046 /* Create and attach the brand/logo to the rebar */
1047 hResult = CreateBrandBand(&logoBar);
1048 if (FAILED_UNEXPECTEDLY(hResult))
1049 return hResult;
1050 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
1051 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
1052 #endif
1053
1054 /* Create and attach the standard toolbar to the rebar */
1055 hResult = CreateToolsBar(&toolsBar);
1056 if (FAILED_UNEXPECTEDLY(hResult))
1057 return hResult;
1058 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1059 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
1060 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow);
1061 if (FAILED_UNEXPECTEDLY(hResult))
1062 return hResult;
1063
1064 /* Create and attach the address/navigation toolbar to the rebar */
1065 hResult = CreateAddressBand(&navigationBar);
1066 if (FAILED_UNEXPECTEDLY(hResult))
1067 return hResult;
1068 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1069 fNavigationBar.Attach(navigationBar.Detach());
1070 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
1071
1072 return S_OK;
1073 }
1074
1075 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
1076 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
1077 {
1078 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1079 {
1080 while (cCmds != 0)
1081 {
1082 switch (prgCmds->cmdID)
1083 {
1084 case ITID_TEXTLABELS: // Text Labels state
1085 prgCmds->cmdf = OLECMDF_SUPPORTED;
1086 break;
1087 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
1088 prgCmds->cmdf = OLECMDF_SUPPORTED;
1089 if (fControlsBar)
1090 prgCmds->cmdf |= OLECMDF_LATCHED;
1091 break;
1092 case ITID_ADDRESSBANDSHOWN: // address bar visibility
1093 prgCmds->cmdf = OLECMDF_SUPPORTED;
1094 if (fNavigationBar)
1095 prgCmds->cmdf |= OLECMDF_LATCHED;
1096 break;
1097 case ITID_LINKSBANDSHOWN: // links bar visibility
1098 prgCmds->cmdf = 0;
1099 break;
1100 case ITID_MENUBANDSHOWN: // Menubar band visibility
1101 prgCmds->cmdf = OLECMDF_SUPPORTED;
1102 if (fMenuBar)
1103 prgCmds->cmdf |= OLECMDF_LATCHED;
1104 break;
1105 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
1106 prgCmds->cmdf = 0;
1107 break;
1108 case ITID_CUSTOMIZEENABLED: // customize enabled
1109 prgCmds->cmdf = OLECMDF_SUPPORTED;
1110 break;
1111 case ITID_TOOLBARLOCKED: // lock toolbars
1112 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1113 if (fLocked)
1114 prgCmds->cmdf |= OLECMDF_LATCHED;
1115 break;
1116 default:
1117 prgCmds->cmdf = 0;
1118 break;
1119 }
1120 prgCmds++;
1121 cCmds--;
1122 }
1123 return S_OK;
1124 }
1125 return E_FAIL;
1126 }
1127
1128 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
1129 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1130 {
1131 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1132 {
1133 switch (nCmdID)
1134 {
1135 case 1:
1136 // what do I do here?
1137 return S_OK;
1138 case ITID_TEXTLABELS:
1139 // toggle text labels
1140 return S_OK;
1141 case ITID_TOOLBARBANDSHOWN:
1142 // toggle toolbar band visibility
1143 return S_OK;
1144 case ITID_ADDRESSBANDSHOWN:
1145 // toggle address band visibility
1146 return S_OK;
1147 case ITID_LINKSBANDSHOWN:
1148 // toggle links band visibility
1149 return S_OK;
1150 case ITID_CUSTOMIZEENABLED:
1151 // run customize
1152 return S_OK;
1153 case ITID_TOOLBARLOCKED:
1154 return LockUnlockToolbars(!fLocked);
1155 }
1156 }
1157 return E_FAIL;
1158 }
1159
1160 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
1161 {
1162 return E_NOTIMPL;
1163 }
1164
1165 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1166 {
1167 return E_NOTIMPL;
1168 }
1169
1170 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1171 LCID lcid, DISPID *rgDispId)
1172 {
1173 return E_NOTIMPL;
1174 }
1175
1176 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1177 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1178 {
1179 HRESULT hResult;
1180
1181 switch(dispIdMember)
1182 {
1183 case DISPID_BEFORENAVIGATE:
1184 hResult = S_OK;
1185 break;
1186 case DISPID_DOWNLOADCOMPLETE:
1187 hResult = S_OK;
1188 break;
1189 case DISPID_COMMANDSTATECHANGE:
1190 if (pDispParams->cArgs != 2)
1191 return E_INVALIDARG;
1192 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
1193 return E_INVALIDARG;
1194 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
1195 V_I4(&pDispParams->rgvarg[1]));
1196 case DISPID_DOWNLOADBEGIN:
1197 hResult = S_OK;
1198 break;
1199 case DISPID_NAVIGATECOMPLETE2:
1200 hResult = S_OK;
1201 break;
1202 case DISPID_DOCUMENTCOMPLETE:
1203 hResult = S_OK;
1204 break;
1205 }
1206 return S_OK;
1207 }
1208
1209 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1210 {
1211 HRESULT hResult;
1212
1213 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14);
1214
1215 fCommandTarget.Release();
1216 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1217 if (FAILED_UNEXPECTEDLY(hResult))
1218 return hResult;
1219 fCommandCategory = *category;
1220 return S_OK;
1221 }
1222
1223 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1224 {
1225 return E_NOTIMPL;
1226 }
1227
1228 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1229 {
1230 return E_NOTIMPL;
1231 }
1232
1233 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1234 HINSTANCE param10, LPCTSTR param14, long *param18)
1235 {
1236 long result;
1237
1238 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1239 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1240 *param18 = result;
1241 if (result == -1)
1242 return E_FAIL;
1243 return S_OK;
1244 }
1245
1246 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1247 {
1248 return E_NOTIMPL;
1249 }
1250
1251 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1252 {
1253 if (theState == NULL)
1254 return E_POINTER;
1255 // map the command id
1256 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1257 return S_OK;
1258 }
1259
1260 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1261 {
1262 // map the command id
1263 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1264 return S_OK;
1265 }
1266
1267 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1268 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1269 {
1270 return E_NOTIMPL;
1271 }
1272
1273 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1274 {
1275 if (paramC == NULL)
1276 return E_POINTER;
1277 *paramC = MAKELONG(24, 24);
1278 return S_OK;
1279 }
1280
1281 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1282 WPARAM wParam, LPARAM lParam, LRESULT *result)
1283 {
1284 return E_NOTIMPL;
1285 }
1286
1287 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1288 HIMAGELIST param14, HIMAGELIST param18)
1289 {
1290 return E_NOTIMPL;
1291 }
1292
1293 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1294 {
1295 return E_NOTIMPL;
1296 }
1297
1298 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1299 {
1300 return E_NOTIMPL;
1301 }
1302
1303 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1304 {
1305 CComPtr<IBrowserService> browserService;
1306 HWND ownerWindow;
1307 HWND dockContainer;
1308 HRESULT hResult;
1309
1310 if (pUnkSite == NULL)
1311 {
1312 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1313 ::DestroyWindow(fMainReBar);
1314 DestroyWindow();
1315 fSite.Release();
1316 }
1317 else
1318 {
1319 // get window handle of owner
1320 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow);
1321 if (FAILED_UNEXPECTEDLY(hResult))
1322 return hResult;
1323 if (ownerWindow == NULL)
1324 return E_FAIL;
1325
1326 // create dock container
1327 fSite = pUnkSite;
1328 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
1329 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
1330 if (dockContainer == NULL)
1331 return E_FAIL;
1332 SubclassWindow(dockContainer);
1333
1334 // create rebar in dock container
1335 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
1336 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
1337 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
1338 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
1339 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
1340 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1341 if (fMainReBar == NULL)
1342 return E_FAIL;
1343
1344 // take advice to watch events
1345 hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1346 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
1347 }
1348 return S_OK;
1349 }
1350
1351 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1352 {
1353 if (ppvSite == NULL)
1354 return E_POINTER;
1355 if (fSite.p != NULL)
1356 return fSite->QueryInterface(riid, ppvSite);
1357 *ppvSite = NULL;
1358 return S_OK;
1359 }
1360
1361 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1362 {
1363 HRESULT hResult;
1364
1365 if (IsEqualIID(guidService, IID_IBandSite))
1366 return this->QueryInterface(riid, ppvObject);
1367 if (IsEqualIID(guidService, SID_IBandProxy))
1368 {
1369 if (fBandProxy.p == NULL)
1370 {
1371 hResult = CreateAndInitBandProxy();
1372 if (FAILED_UNEXPECTEDLY(hResult))
1373 return hResult;
1374 }
1375 return fBandProxy->QueryInterface(riid, ppvObject);
1376 }
1377 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1378 }
1379
1380 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1381 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1382 {
1383 HRESULT hResult;
1384
1385 if (fMenuBar)
1386 {
1387 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult);
1388 if (hResult != S_FALSE)
1389 return hResult;
1390 }
1391
1392 if (fNavigationBar)
1393 {
1394 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult);
1395 if (hResult != S_FALSE)
1396 return hResult;
1397 }
1398
1399 if (fLogoBar)
1400 {
1401 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult);
1402 if (hResult != S_FALSE)
1403 return hResult;
1404 }
1405
1406 return S_FALSE;
1407 }
1408
1409 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1410 {
1411 UNIMPLEMENTED;
1412 return E_NOTIMPL;
1413 }
1414
1415 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1416 {
1417 UNIMPLEMENTED;
1418 return E_NOTIMPL;
1419 }
1420
1421 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1422 {
1423 UNIMPLEMENTED;
1424 return E_NOTIMPL;
1425 }
1426
1427 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1428 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1429 {
1430 if (ppstb == NULL)
1431 return E_POINTER;
1432 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
1433 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1434 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1435 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1436 *ppstb = NULL;
1437 return E_FAIL;
1438 }
1439
1440 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1441 {
1442 UNIMPLEMENTED;
1443 return E_NOTIMPL;
1444 }
1445
1446 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1447 {
1448 UNIMPLEMENTED;
1449 return E_NOTIMPL;
1450 }
1451
1452 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1453 {
1454 UNIMPLEMENTED;
1455 return E_NOTIMPL;
1456 }
1457
1458 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1459 {
1460 UNIMPLEMENTED;
1461 return E_NOTIMPL;
1462 }
1463
1464 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1465 {
1466 UNIMPLEMENTED;
1467 return E_NOTIMPL;
1468 }
1469
1470 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1471 {
1472 CComPtr<IWebBrowser> webBrowser;
1473 HRESULT hResult;
1474
1475 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1476 if (FAILED_UNEXPECTEDLY(hResult))
1477 return 0;
1478 hResult = webBrowser->GoBack();
1479 return 1;
1480 }
1481
1482 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1483 {
1484 CComPtr<IWebBrowser> webBrowser;
1485 HRESULT hResult;
1486
1487 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1488 if (FAILED_UNEXPECTEDLY(hResult))
1489 return 0;
1490 hResult = webBrowser->GoForward();
1491 return 1;
1492 }
1493
1494 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1495 {
1496 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1497 return 1;
1498 }
1499
1500 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1501 {
1502 CComPtr<IObjectWithSite> objectWithSite;
1503 CComPtr<IContextMenu> contextMenu;
1504 CMINVOKECOMMANDINFO commandInfo;
1505 const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1506 HRESULT hResult;
1507
1508 // TODO: Query shell if this command is enabled first
1509
1510 memset(&commandInfo, 0, sizeof(commandInfo));
1511 commandInfo.cbSize = sizeof(commandInfo);
1512 commandInfo.hwnd = m_hWnd;
1513 commandInfo.lpParameters = searchGUID;
1514 commandInfo.nShow = SW_SHOWNORMAL;
1515
1516 hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1517 IID_PPV_ARG(IContextMenu, &contextMenu));
1518 if (FAILED_UNEXPECTEDLY(hResult))
1519 return 0;
1520 hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1521 if (FAILED_UNEXPECTEDLY(hResult))
1522 return 0;
1523 hResult = objectWithSite->SetSite(fSite);
1524 if (FAILED_UNEXPECTEDLY(hResult))
1525 return 0;
1526 hResult = contextMenu->InvokeCommand(&commandInfo);
1527 hResult = objectWithSite->SetSite(NULL);
1528 return 0;
1529 }
1530
1531 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1532 {
1533 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL);
1534 return 1;
1535 }
1536
1537 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1538 {
1539 HRESULT hResult;
1540
1541 if (fCommandTarget.p != NULL)
1542 {
1543 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1544 }
1545 return 1;
1546 }
1547
1548 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1549 {
1550 CComPtr<IBrowserService> browserService;
1551 CComPtr<IOleCommandTarget> commandTarget;
1552 CComPtr<ITravelLog> travelLog;
1553 NMTOOLBARW *notifyInfo;
1554 RECT bounds;
1555 HMENU newMenu;
1556 TPMPARAMS params;
1557 int selectedItem;
1558 VARIANT parmIn;
1559 OLECMD commandInfo;
1560 HRESULT hResult;
1561
1562 notifyInfo = (NMTOOLBARW *)pNMHDR;
1563 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1564 {
1565 // not from the toolbar, keep looking for a message handler
1566 bHandled = FALSE;
1567 return 0;
1568 }
1569 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1570 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1571 switch (notifyInfo->iItem)
1572 {
1573 case IDM_GOTO_BACK:
1574 newMenu = CreatePopupMenu();
1575 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1576 hResult = browserService->GetTravelLog(&travelLog);
1577 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1578 commandInfo.cmdID = 0x1d;
1579 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1580 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1581 travelLog->CountEntries(browserService) > 1)
1582 {
1583 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1584 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1585 }
1586 params.cbSize = sizeof (params);
1587 params.rcExclude = bounds;
1588 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1589 bounds.left, bounds.bottom, m_hWnd, &params);
1590 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1591 {
1592 V_VT(&parmIn) = VT_I4;
1593 V_I4(&parmIn) = 1;
1594 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1595 }
1596 else if (selectedItem != 0)
1597 hResult = travelLog->Travel(browserService, -selectedItem);
1598 DestroyMenu(newMenu);
1599 break;
1600 case IDM_GOTO_FORWARD:
1601 newMenu = CreatePopupMenu();
1602 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1603 hResult = browserService->GetTravelLog(&travelLog);
1604 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1605 commandInfo.cmdID = 0x1d;
1606 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1607 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1608 travelLog->CountEntries(browserService) > 1)
1609 {
1610 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1611 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1612 }
1613 params.cbSize = sizeof (params);
1614 params.rcExclude = bounds;
1615 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1616 bounds.left, bounds.bottom, m_hWnd, &params);
1617 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1618 {
1619 V_VT(&parmIn) = VT_I4;
1620 V_I4(&parmIn) = 1;
1621 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1622 }
1623 else if (selectedItem != 0)
1624 hResult = travelLog->Travel(browserService, selectedItem);
1625 DestroyMenu(newMenu);
1626 break;
1627 case gViewsCommandID:
1628 VARIANT inValue;
1629 CComVariant outValue;
1630 HRESULT hResult;
1631
1632 V_VT(&inValue) = VT_INT_PTR;
1633 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1634
1635 if (fCommandTarget.p != NULL)
1636 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue);
1637 // pvaOut is VT_I4 with value 0x403
1638 break;
1639 }
1640 return TBDDRET_DEFAULT;
1641 }
1642
1643 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1644 {
1645 return 1;
1646 }
1647
1648 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1649 {
1650 return 1;
1651 }
1652
1653 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1654 {
1655 HMENU contextMenuBar;
1656 HMENU contextMenu;
1657 POINT clickLocation;
1658 int command;
1659 RBHITTESTINFO hitTestInfo;
1660 REBARBANDINFOW rebarBandInfo;
1661 int bandID;
1662
1663 clickLocation.x = LOWORD(lParam);
1664 clickLocation.y = HIWORD(lParam);
1665 hitTestInfo.pt = clickLocation;
1666 ScreenToClient(&hitTestInfo.pt);
1667 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1668 if (hitTestInfo.iBand == -1)
1669 return 0;
1670 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1671 rebarBandInfo.fMask = RBBIM_ID;
1672 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1673 bandID = rebarBandInfo.wID;
1674 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1675 contextMenu = GetSubMenu(contextMenuBar, 0);
1676 switch (bandID)
1677 {
1678 case ITBBID_MENUBAND: // menu band
1679 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1680 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1681 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1682 break;
1683 case ITBBID_BRANDBAND: // brand band
1684 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1685 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1686 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1687 break;
1688 case ITBBID_TOOLSBAND: // tools band
1689 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1690 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1691 break;
1692 case ITBBID_ADDRESSBAND: // navigation band
1693 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1694 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1695 break;
1696 default:
1697 break;
1698 }
1699
1700 // TODO: Implement show/hide toolbars
1701 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, FALSE);
1702 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, FALSE);
1703 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1704 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1705
1706 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, fControlsBar != NULL);
1707 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, fNavigationBar != NULL);
1708 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1709 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1710 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked);
1711
1712 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1713 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1714 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1715 switch (command)
1716 {
1717 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1718 break;
1719 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1720 break;
1721 case IDM_TOOLBARS_LINKSBAR: // links
1722 break;
1723 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1724 LockUnlockToolbars(!fLocked);
1725 break;
1726 case IDM_TOOLBARS_CUSTOMIZE: // customize
1727 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1728 break;
1729 }
1730
1731 DestroyMenu(contextMenuBar);
1732 return 1;
1733 }
1734
1735 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1736 {
1737 if (wParam != SIZE_MINIMIZED)
1738 {
1739 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1740 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1741 }
1742 return 1;
1743 }
1744
1745 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1746 {
1747 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1748 {
1749 bHandled = FALSE;
1750 return 0;
1751 }
1752 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1753 return 1;
1754 }
1755
1756 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1757 {
1758 CComPtr<IBrowserService> browserService;
1759 CComPtr<ITravelLog> travelLog;
1760 TOOLTIPTEXTW *pTTTW;
1761 UINT nID;
1762 wchar_t tempString[300];
1763 HRESULT hResult;
1764
1765 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1766 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1767 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1768 else
1769 nID = (UINT)pNMHDR->idFrom;
1770
1771 if (nID != 0)
1772 {
1773 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1774 {
1775 // TODO: Should this call QueryService?
1776 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1777 hResult = browserService->GetTravelLog(&travelLog);
1778 hResult = travelLog->GetToolTipText(browserService,
1779 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1780 0, tempString, 299);
1781 if (FAILED_UNEXPECTEDLY(hResult))
1782 {
1783 bHandled = FALSE;
1784 return 0;
1785 }
1786 }
1787 else
1788 tempString[0] = 0;
1789 wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
1790 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1791 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1792 return 0;
1793 }
1794 return 0;
1795 }
1796
1797 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1798 {
1799 LRESULT theResult;
1800 HRESULT hResult;
1801
1802 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1803
1804 bHandled = hResult == S_OK;
1805
1806 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1807 }
1808 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1809 {
1810 NMHDR *notifyHeader;
1811 LRESULT theResult;
1812 HRESULT hResult;
1813
1814 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1815
1816 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1817
1818 bHandled = hResult == S_OK;
1819
1820 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1821 }
1822
1823 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1824 {
1825 bHandled = FALSE;
1826 if (fLocked)
1827 return 0;
1828
1829 if (wParam & MK_CONTROL)
1830 return 0;
1831
1832 fSizing = TRUE;
1833
1834 DWORD msgp = GetMessagePos();
1835
1836 fStartPosition.x = GET_X_LPARAM(msgp);
1837 fStartPosition.y = GET_Y_LPARAM(msgp);
1838
1839 RECT rc;
1840 GetWindowRect(m_hWnd, &rc);
1841
1842 fStartHeight = rc.bottom - rc.top;
1843
1844 SetCapture();
1845
1846 bHandled = TRUE;
1847 return 0;
1848 }
1849
1850 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1851 {
1852 bHandled = FALSE;
1853 if (!fSizing)
1854 return 0;
1855
1856 DWORD msgp = GetMessagePos();
1857
1858 POINT pt;
1859 pt.x = GET_X_LPARAM(msgp);
1860 pt.y = GET_Y_LPARAM(msgp);
1861
1862 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1863
1864 bHandled = TRUE;
1865 return 0;
1866 }
1867
1868 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1869 {
1870 bHandled = FALSE;
1871 if (!fSizing)
1872 return 0;
1873
1874 OnMouseMove(uMsg, wParam, lParam, bHandled);
1875
1876 fSizing = FALSE;
1877
1878 ReleaseCapture();
1879
1880 return 0;
1881 }
1882
1883 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1884 {
1885 return ShellObjectCreator<CInternetToolbar>(riid, ppv);
1886 }