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