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