[TASKMGR] Process page: Allow using "Open File Location" functionality without runnin...
[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 STDMETHOD(AddNameSpace)(LPGUID, IShellFolder *, LPCITEMIDLIST, ULONG) PURE;
33 STDMETHOD(GetNameSpaceID)(LPCITEMIDLIST, LPGUID) PURE;
34 STDMETHOD(QueryNameSpace)(ULONG, LPGUID, IShellFolder **) PURE;
35 STDMETHOD(EnumNameSpace)(ULONG, PULONG) PURE;
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 STDMETHOD(GetWindow)(HWND *lphwnd) override;
154 STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override;
155
156 // *** IDockingWindow methods ***
157 STDMETHOD(GetBorderDW)(IUnknown* punkObj, LPRECT prcBorder) override;
158 STDMETHOD(RequestBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override;
159 STDMETHOD(SetBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override;
160
161 // *** IInputObjectSite specific methods ***
162 STDMETHOD(OnFocusChangeIS)(IUnknown *punkObj, BOOL fSetFocus) override;
163
164 // *** IOleCommandTarget specific methods ***
165 STDMETHOD(QueryStatus)(const GUID *pguidCmdGroup, ULONG cCmds,
166 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) override;
167 STDMETHOD(Exec)(const GUID *pguidCmdGroup, DWORD nCmdID,
168 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override;
169
170 // *** IServiceProvider methods ***
171 STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override;
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->pSettings->fLocked)
254 bandInfo.fStyle |= RBBS_NOGRIPPER;
255 if (fFlags & ITF_NOTITLE)
256 bandInfo.fStyle |= RBBS_HIDETITLE;
257 if ((fFlags & ITF_GRIPPERALWAYS) && !fToolbar->pSettings->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 fMenuBandWindow = NULL;
612 fNavigationWindow = NULL;
613 fMenuCallback = new CComObject<CMenuCallback>();
614 fToolbarWindow = NULL;
615 fAdviseCookie = 0;
616 pSettings = NULL;
617 }
618
619 CInternetToolbar::~CInternetToolbar()
620 {
621 }
622
623 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
624 {
625 CComPtr<CDockSite> newSite;
626
627 newSite = new CComObject<CDockSite>;
628 newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
629 }
630
631 HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
632 {
633 CComPtr<IDockingWindowSite> dockingWindowSite;
634 RECT availableBorderSpace;
635
636 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
637 if (FAILED_UNEXPECTEDLY(hResult))
638 return hResult;
639 hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
640 if (FAILED_UNEXPECTEDLY(hResult))
641 return hResult;
642
643 if (maxHeight && availableBorderSpace.bottom - availableBorderSpace.top > maxHeight)
644 {
645 availableBorderSpace.bottom = availableBorderSpace.top + maxHeight;
646 }
647
648 return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
649 }
650
651 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar)
652 {
653 CComPtr<IShellMenu> menubar;
654 CComPtr<IShellMenuCallback> callback;
655 VARIANT menuOut;
656 HWND ownerWindow;
657 HRESULT hResult;
658
659 if (!pMenuBar)
660 return E_POINTER;
661
662 *pMenuBar = NULL;
663
664 hResult = CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu, &menubar));
665 if (FAILED_UNEXPECTEDLY(hResult))
666 return hResult;
667
668 hResult = fMenuCallback->QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
669 if (FAILED_UNEXPECTEDLY(hResult))
670 return hResult;
671
672 hResult = menubar->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
673 if (FAILED_UNEXPECTEDLY(hResult))
674 return hResult;
675
676 // Set Menu
677 {
678 hResult = IUnknown_Exec(fSite, CGID_Explorer, 0x35, 0, NULL, &menuOut);
679 if (FAILED_UNEXPECTEDLY(hResult))
680 return hResult;
681
682 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
683 return E_FAIL;
684
685 hResult = IUnknown_GetWindow(fSite, &ownerWindow);
686 if (FAILED_UNEXPECTEDLY(hResult))
687 return hResult;
688
689 HMENU hMenuBar = (HMENU) V_INTREF(&menuOut);
690
691 // FIXME: Figure out the proper way to do this.
692 HMENU hMenuFavs = GetSubMenu(hMenuBar, 3);
693 if (hMenuFavs)
694 {
695 DeleteMenu(hMenuFavs, IDM_FAVORITES_EMPTY, MF_BYCOMMAND);
696 }
697
698 hResult = menubar->SetMenu(hMenuBar, ownerWindow, SMSET_DONTOWN);
699 if (FAILED_UNEXPECTEDLY(hResult))
700 return hResult;
701 }
702
703 hResult = IUnknown_Exec(menubar, CGID_MenuBand, 3, 1, NULL, NULL);
704 if (FAILED_UNEXPECTEDLY(hResult))
705 return hResult;
706
707 *pMenuBar = menubar.Detach();
708
709 return S_OK;
710 }
711
712 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
713 {
714 if (locked != !!pSettings->fLocked)
715 {
716 pSettings->fLocked = (BOOL)locked;
717 pSettings->Save();
718 RefreshLockedToolbarState();
719 }
720 return S_OK;
721 }
722
723 void CInternetToolbar::RefreshLockedToolbarState()
724 {
725 REBARBANDINFOW rebarBandInfo;
726 int bandCount;
727 CDockSite *dockSite;
728
729 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
730 rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
731 bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
732 for (INT x = 0; x < bandCount; x++)
733 {
734 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
735 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
736 if (dockSite != NULL)
737 {
738 rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
739 if ((dockSite->fFlags & CDockSite::ITF_NOGRIPPER) || pSettings->fLocked)
740 rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
741 if ((dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS) && !pSettings->fLocked)
742 rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
743 SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
744 }
745 }
746 ReserveBorderSpace(0);
747 }
748
749 HRESULT CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd)
750 {
751 long state = 0;
752 if (pcmd->cmdf & OLECMDF_ENABLED)
753 state |= TBSTATE_ENABLED;
754 if (pcmd->cmdf & OLECMDF_LATCHED)
755 state |= TBSTATE_CHECKED;
756 return SetState(pguidCmdGroup, commandID, state);
757 }
758
759 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
760 {
761 HRESULT hResult;
762
763 hResult = S_OK;
764 switch (commandID)
765 {
766 case -1:
767 // loop through buttons
768 //for buttons in CLSID_CommonButtons
769 // if up, QueryStatus for up state and update it
770 //
771 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
772
773 OLECMD commandList[4];
774 commandList[0].cmdID = 0x1c;
775 commandList[1].cmdID = 0x1d;
776 commandList[2].cmdID = 0x1e;
777 commandList[3].cmdID = 0x23;
778 IUnknown_QueryStatus(fSite, CGID_Explorer, 4, commandList, NULL);
779 SetState(&CLSID_CommonButtons, gSearchCommandID, &commandList[0]);
780 SetState(&CLSID_CommonButtons, gFoldersCommandID, &commandList[3]);
781 //SetState(&CLSID_CommonButtons, gFavoritesCommandID, &commandList[2]);
782 //SetState(&CLSID_CommonButtons, gHistoryCommandID, &commandList[1]);
783
784 break;
785 case 1:
786 // forward
787 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0);
788 break;
789 case 2:
790 // back
791 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0);
792 break;
793 case 3:
794 // up
795 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_UPONELEVEL, newValue ? TBSTATE_ENABLED : 0);
796 break;
797 }
798 return hResult;
799 }
800
801 HRESULT CInternetToolbar::CreateAndInitBandProxy()
802 {
803 CComPtr<IServiceProvider> serviceProvider;
804 HRESULT hResult;
805
806 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
807 if (FAILED_UNEXPECTEDLY(hResult))
808 return hResult;
809 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
810 if (FAILED_UNEXPECTEDLY(hResult))
811 {
812 hResult = CBandProxy_CreateInstance(IID_PPV_ARG(IBandProxy, &fBandProxy));
813 if (FAILED_UNEXPECTEDLY(hResult))
814 return hResult;
815 hResult = fBandProxy->SetSite(fSite);
816 if (FAILED_UNEXPECTEDLY(hResult))
817 return hResult;
818 }
819 return S_OK;
820 }
821
822 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
823 {
824 return E_NOTIMPL;
825 }
826
827 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
828 {
829 HRESULT hr = S_FALSE;
830
831 if (fMenuBar)
832 hr = IUnknown_HasFocusIO(fMenuBar);
833 if (hr != S_FALSE)
834 return hr;
835
836 if (fControlsBar)
837 hr = IUnknown_HasFocusIO(fControlsBar);
838 if (hr != S_FALSE)
839 return hr;
840
841 if (fNavigationBar)
842 hr = IUnknown_HasFocusIO(fNavigationBar);
843 if (hr != S_FALSE)
844 return hr;
845
846 return S_FALSE;
847 }
848
849 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
850 {
851 HRESULT hr = S_FALSE;
852
853 if (fMenuBar)
854 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg);
855 if (hr == S_OK)
856 return hr;
857
858 if (fControlsBar)
859 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg);
860 if (hr == S_OK)
861 return hr;
862
863 if (fNavigationBar)
864 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg);
865 if (hr == S_OK)
866 return hr;
867
868 return S_FALSE;
869 }
870
871 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
872 {
873 if (lphwnd == NULL)
874 return E_POINTER;
875 *lphwnd = m_hWnd;
876 return S_OK;
877 }
878
879 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
880 {
881 return E_NOTIMPL;
882 }
883
884 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
885 {
886 HRESULT hResult;
887
888 // show the bar here
889 if (fShow)
890 {
891 hResult = ReserveBorderSpace();
892 if (FAILED_UNEXPECTEDLY(hResult))
893 return hResult;
894 }
895
896 if (fMenuBar)
897 {
898 hResult = IUnknown_ShowDW(fMenuBar, fShow);
899 if (FAILED_UNEXPECTEDLY(hResult))
900 return hResult;
901 }
902
903 if (fControlsBar)
904 {
905 hResult = IUnknown_ShowDW(fControlsBar, fShow);
906 if (FAILED_UNEXPECTEDLY(hResult))
907 return hResult;
908 }
909 if (fNavigationBar)
910 {
911 hResult = IUnknown_ShowDW(fNavigationBar, fShow);
912 if (FAILED_UNEXPECTEDLY(hResult))
913 return hResult;
914 }
915 if (fLogoBar)
916 {
917 hResult = IUnknown_ShowDW(fLogoBar, fShow);
918 if (FAILED_UNEXPECTEDLY(hResult))
919 return hResult;
920 }
921 return S_OK;
922 }
923
924 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
925 {
926 HRESULT hResult;
927
928 if (fMenuBar)
929 {
930 hResult = IUnknown_CloseDW(fMenuBar, dwReserved);
931 if (FAILED_UNEXPECTEDLY(hResult))
932 return hResult;
933 ReleaseCComPtrExpectZero(fMenuBar);
934 }
935 if (fControlsBar)
936 {
937 hResult = IUnknown_CloseDW(fControlsBar, dwReserved);
938 if (FAILED_UNEXPECTEDLY(hResult))
939 return hResult;
940 ReleaseCComPtrExpectZero(fControlsBar);
941 }
942 if (fNavigationBar)
943 {
944 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved);
945 if (FAILED_UNEXPECTEDLY(hResult))
946 return hResult;
947 ReleaseCComPtrExpectZero(fNavigationBar);
948 }
949 if (fLogoBar)
950 {
951 hResult = IUnknown_CloseDW(fLogoBar, dwReserved);
952 if (FAILED_UNEXPECTEDLY(hResult))
953 return hResult;
954 ReleaseCComPtrExpectZero(fLogoBar);
955 }
956
957 SetSite(NULL);
958 return S_OK;
959 }
960
961 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
962 IUnknown *punkToolbarSite, BOOL fReserved)
963 {
964 RECT neededBorderSpace;
965 RECT availableBorderSpace = *prcBorder;
966
967 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
968
969 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
970 // Let's make sure we fetch the actual size properly.
971 ::GetWindowRect(fMainReBar, &availableBorderSpace);
972 neededBorderSpace.left = 0;
973 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
974 if (!pSettings->fLocked)
975 neededBorderSpace.top += 3;
976 neededBorderSpace.right = 0;
977 neededBorderSpace.bottom = 0;
978
979 CComPtr<IDockingWindowSite> dockingWindowSite;
980
981 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
982 if (FAILED_UNEXPECTEDLY(hResult))
983 return hResult;
984
985 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
986 if (FAILED_UNEXPECTEDLY(hResult))
987 return hResult;
988
989 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
990 if (FAILED_UNEXPECTEDLY(hResult))
991 return hResult;
992
993 return S_OK;
994 }
995
996 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
997 {
998 if (pClassID == NULL)
999 return E_POINTER;
1000 *pClassID = CLSID_InternetToolbar;
1001 return S_OK;
1002 }
1003
1004 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
1005 {
1006 return E_NOTIMPL;
1007 }
1008
1009 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
1010 {
1011 return E_NOTIMPL;
1012 }
1013
1014 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
1015 {
1016 return E_NOTIMPL;
1017 }
1018
1019 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
1020 {
1021 return E_NOTIMPL;
1022 }
1023
1024 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
1025 {
1026 CComPtr<IShellMenu> menuBar;
1027 CComPtr<IUnknown> logoBar;
1028 CComPtr<IUnknown> toolsBar;
1029 CComPtr<IUnknown> navigationBar;
1030 HRESULT hResult;
1031
1032 /* Create and attach the menubar to the rebar */
1033 hResult = CreateMenuBar(&menuBar);
1034 if (FAILED_UNEXPECTEDLY(hResult))
1035 return hResult;
1036 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1037
1038 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
1039 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
1040
1041 // FIXME: The ROS Rebar does not properly support fixed-size items such as the brandband,
1042 // and it will put them in their own row, sized to take up the whole row.
1043 #if 0
1044 /* Create and attach the brand/logo to the rebar */
1045 hResult = CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown, &logoBar));
1046 if (FAILED_UNEXPECTEDLY(hResult))
1047 return hResult;
1048 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
1049 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
1050 #endif
1051
1052 /* Create and attach the standard toolbar to the rebar */
1053 hResult = CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown, &toolsBar));
1054 if (FAILED_UNEXPECTEDLY(hResult))
1055 return hResult;
1056 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1057 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
1058 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow);
1059 if (FAILED_UNEXPECTEDLY(hResult))
1060 return hResult;
1061
1062 /* Create and attach the address/navigation toolbar to the rebar */
1063 hResult = CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown, &navigationBar));
1064 if (FAILED_UNEXPECTEDLY(hResult))
1065 return hResult;
1066 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1067 fNavigationBar.Attach(navigationBar.Detach());
1068 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
1069
1070 return S_OK;
1071 }
1072
1073 HRESULT CInternetToolbar::IsBandVisible(int BandID)
1074 {
1075 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0);
1076
1077 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE};
1078 SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo);
1079
1080 return (bandInfo.fStyle & RBBS_HIDDEN) ? S_FALSE : S_OK;
1081 }
1082
1083 HRESULT CInternetToolbar::ToggleBandVisibility(int BandID)
1084 {
1085 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0);
1086
1087 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE};
1088 SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo);
1089
1090 if (bandInfo.fStyle & RBBS_HIDDEN)
1091 bandInfo.fStyle &= ~RBBS_HIDDEN;
1092 else
1093 bandInfo.fStyle |= RBBS_HIDDEN;
1094
1095 SendMessage(fMainReBar, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
1096
1097 ReserveBorderSpace(0);
1098 return S_OK;
1099 }
1100
1101 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
1102 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
1103 {
1104 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1105 {
1106 while (cCmds != 0)
1107 {
1108 switch (prgCmds->cmdID)
1109 {
1110 case ITID_TEXTLABELS: // Text Labels state
1111 prgCmds->cmdf = OLECMDF_SUPPORTED;
1112 break;
1113 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
1114 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1115 if (IsBandVisible(ITBBID_TOOLSBAND) == S_OK)
1116 prgCmds->cmdf |= OLECMDF_LATCHED;
1117 break;
1118 case ITID_ADDRESSBANDSHOWN: // address bar visibility
1119 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1120 if (IsBandVisible(ITBBID_ADDRESSBAND) == S_OK)
1121 prgCmds->cmdf |= OLECMDF_LATCHED;
1122 break;
1123 case ITID_LINKSBANDSHOWN: // links bar visibility
1124 prgCmds->cmdf = 0;
1125 break;
1126 case ITID_MENUBANDSHOWN: // Menubar band visibility
1127 prgCmds->cmdf = OLECMDF_SUPPORTED;
1128 if (fMenuBar)
1129 prgCmds->cmdf |= OLECMDF_LATCHED;
1130 break;
1131 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
1132 prgCmds->cmdf = 0;
1133 break;
1134 case ITID_CUSTOMIZEENABLED: // customize enabled
1135 prgCmds->cmdf = OLECMDF_SUPPORTED;
1136 break;
1137 case ITID_TOOLBARLOCKED: // lock toolbars
1138 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1139 if (pSettings->fLocked)
1140 prgCmds->cmdf |= OLECMDF_LATCHED;
1141 break;
1142 default:
1143 prgCmds->cmdf = 0;
1144 break;
1145 }
1146 prgCmds++;
1147 cCmds--;
1148 }
1149 return S_OK;
1150 }
1151 return E_FAIL;
1152 }
1153
1154 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
1155 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1156 {
1157 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1158 {
1159 switch (nCmdID)
1160 {
1161 case 1:
1162 // what do I do here?
1163 return S_OK;
1164 case ITID_TEXTLABELS:
1165 // toggle text labels
1166 return S_OK;
1167 case ITID_TOOLBARBANDSHOWN:
1168 return ToggleBandVisibility(ITBBID_TOOLSBAND);
1169 case ITID_ADDRESSBANDSHOWN:
1170 return ToggleBandVisibility(ITBBID_ADDRESSBAND);
1171 case ITID_LINKSBANDSHOWN:
1172 // toggle links band visibility
1173 return S_OK;
1174 case ITID_CUSTOMIZEENABLED:
1175 // run customize
1176 return S_OK;
1177 case ITID_TOOLBARLOCKED:
1178 return LockUnlockToolbars(!pSettings->fLocked);
1179 }
1180 }
1181 return E_FAIL;
1182 }
1183
1184 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
1185 {
1186 return E_NOTIMPL;
1187 }
1188
1189 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1190 {
1191 return E_NOTIMPL;
1192 }
1193
1194 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1195 LCID lcid, DISPID *rgDispId)
1196 {
1197 return E_NOTIMPL;
1198 }
1199
1200 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1201 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1202 {
1203 HRESULT hResult;
1204
1205 switch(dispIdMember)
1206 {
1207 case DISPID_BEFORENAVIGATE:
1208 hResult = S_OK;
1209 break;
1210 case DISPID_DOWNLOADCOMPLETE:
1211 hResult = S_OK;
1212 break;
1213 case DISPID_COMMANDSTATECHANGE:
1214 if (pDispParams->cArgs != 2)
1215 return E_INVALIDARG;
1216 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
1217 return E_INVALIDARG;
1218 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
1219 V_I4(&pDispParams->rgvarg[1]));
1220 case DISPID_DOWNLOADBEGIN:
1221 hResult = S_OK;
1222 break;
1223 case DISPID_NAVIGATECOMPLETE2:
1224 hResult = S_OK;
1225 break;
1226 case DISPID_DOCUMENTCOMPLETE:
1227 hResult = S_OK;
1228 break;
1229 }
1230 return S_OK;
1231 }
1232
1233 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1234 {
1235 HRESULT hResult;
1236
1237 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14);
1238
1239 fCommandTarget.Release();
1240 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1241 if (FAILED_UNEXPECTEDLY(hResult))
1242 return hResult;
1243 fCommandCategory = *category;
1244 return S_OK;
1245 }
1246
1247 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1248 {
1249 return E_NOTIMPL;
1250 }
1251
1252 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1253 {
1254 return E_NOTIMPL;
1255 }
1256
1257 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1258 HINSTANCE param10, LPCTSTR param14, long *param18)
1259 {
1260 long result;
1261
1262 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1263 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1264 *param18 = result;
1265 if (result == -1)
1266 return E_FAIL;
1267 return S_OK;
1268 }
1269
1270 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1271 {
1272 return E_NOTIMPL;
1273 }
1274
1275 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1276 {
1277 if (theState == NULL)
1278 return E_POINTER;
1279 // map the command id
1280 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1281 return S_OK;
1282 }
1283
1284 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1285 {
1286 // map the command id
1287 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1288 return S_OK;
1289 }
1290
1291 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1292 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1293 {
1294 return E_NOTIMPL;
1295 }
1296
1297 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1298 {
1299 if (paramC == NULL)
1300 return E_POINTER;
1301 *paramC = MAKELONG(24, 24);
1302 return S_OK;
1303 }
1304
1305 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1306 WPARAM wParam, LPARAM lParam, LRESULT *result)
1307 {
1308 return E_NOTIMPL;
1309 }
1310
1311 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1312 HIMAGELIST param14, HIMAGELIST param18)
1313 {
1314 return E_NOTIMPL;
1315 }
1316
1317 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1318 {
1319 return E_NOTIMPL;
1320 }
1321
1322 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1323 {
1324 return E_NOTIMPL;
1325 }
1326
1327 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1328 {
1329 CComPtr<IBrowserService> browserService;
1330 HWND ownerWindow;
1331 HWND dockContainer;
1332 HRESULT hResult;
1333
1334 if (pUnkSite == NULL)
1335 {
1336 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1337 ::DestroyWindow(fMainReBar);
1338 DestroyWindow();
1339 fSite.Release();
1340 }
1341 else
1342 {
1343 // get window handle of owner
1344 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow);
1345 if (FAILED_UNEXPECTEDLY(hResult))
1346 return hResult;
1347 if (ownerWindow == NULL)
1348 return E_FAIL;
1349
1350 // Get settings from owner window
1351 ::SendMessageW(ownerWindow, BWM_GETSETTINGSPTR, 0, (LPARAM)&pSettings);
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 IUnknown_Exec(fSite, CGID_Explorer, 0x1c, 1, NULL, NULL);
1530 return 1;
1531 }
1532
1533 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1534 {
1535 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL);
1536 return 1;
1537 }
1538
1539 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1540 {
1541 HRESULT hResult;
1542
1543 if (fCommandTarget.p != NULL)
1544 {
1545 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1546 if (FAILED(hResult))
1547 {
1548 ::SendMessageW(::GetParent(m_hWnd), WM_COMMAND, wID, 0);
1549 }
1550 }
1551 return 1;
1552 }
1553
1554 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1555 {
1556 CComPtr<IBrowserService> browserService;
1557 CComPtr<IOleCommandTarget> commandTarget;
1558 CComPtr<ITravelLog> travelLog;
1559 NMTOOLBARW *notifyInfo;
1560 RECT bounds;
1561 HMENU newMenu;
1562 TPMPARAMS params;
1563 int selectedItem;
1564 VARIANT parmIn;
1565 OLECMD commandInfo;
1566 HRESULT hResult;
1567 wchar_t templateString[200];
1568
1569 notifyInfo = (NMTOOLBARW *)pNMHDR;
1570 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1571 {
1572 // not from the toolbar, keep looking for a message handler
1573 bHandled = FALSE;
1574 return 0;
1575 }
1576 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1577 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1578 switch (notifyInfo->iItem)
1579 {
1580 case IDM_GOTO_BACK:
1581 newMenu = CreatePopupMenu();
1582 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1583 hResult = browserService->GetTravelLog(&travelLog);
1584 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1585 commandInfo.cmdID = 0x1d;
1586 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1587 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1588 travelLog->CountEntries(browserService) > 1)
1589 {
1590 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1591
1592 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1593 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1594 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1595
1596 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1597 }
1598 params.cbSize = sizeof(params);
1599 params.rcExclude = bounds;
1600 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1601 bounds.left, bounds.bottom, m_hWnd, &params);
1602 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1603 {
1604 V_VT(&parmIn) = VT_I4;
1605 V_I4(&parmIn) = 1;
1606 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1607 }
1608 else if (selectedItem != 0)
1609 hResult = travelLog->Travel(browserService, -selectedItem);
1610 DestroyMenu(newMenu);
1611 break;
1612 case IDM_GOTO_FORWARD:
1613 newMenu = CreatePopupMenu();
1614 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1615 hResult = browserService->GetTravelLog(&travelLog);
1616 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1617 commandInfo.cmdID = 0x1d;
1618 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1619 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1620 travelLog->CountEntries(browserService) > 1)
1621 {
1622 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1623
1624 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1625 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1626 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1627
1628 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1629 }
1630 params.cbSize = sizeof(params);
1631 params.rcExclude = bounds;
1632 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1633 bounds.left, bounds.bottom, m_hWnd, &params);
1634 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1635 {
1636 V_VT(&parmIn) = VT_I4;
1637 V_I4(&parmIn) = 1;
1638 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1639 }
1640 else if (selectedItem != 0)
1641 hResult = travelLog->Travel(browserService, selectedItem);
1642 DestroyMenu(newMenu);
1643 break;
1644 case gViewsCommandID:
1645 VARIANT inValue;
1646 CComVariant outValue;
1647 HRESULT hResult;
1648
1649 V_VT(&inValue) = VT_INT_PTR;
1650 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1651
1652 if (fCommandTarget.p != NULL)
1653 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue);
1654 // pvaOut is VT_I4 with value 0x403
1655 break;
1656 }
1657 return TBDDRET_DEFAULT;
1658 }
1659
1660 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1661 {
1662 return 1;
1663 }
1664
1665 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1666 {
1667 return 1;
1668 }
1669
1670 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1671 {
1672 HMENU contextMenuBar;
1673 HMENU contextMenu;
1674 POINT clickLocation;
1675 int command;
1676 RBHITTESTINFO hitTestInfo;
1677 REBARBANDINFOW rebarBandInfo;
1678 int bandID;
1679
1680 clickLocation.x = LOWORD(lParam);
1681 clickLocation.y = HIWORD(lParam);
1682 hitTestInfo.pt = clickLocation;
1683 ScreenToClient(&hitTestInfo.pt);
1684 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1685 if (hitTestInfo.iBand == -1)
1686 return 0;
1687
1688 pSettings->Load();
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, pSettings->fLocked);
1726 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, pSettings->fShowGoButton);
1727
1728 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1729 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1730 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1731 switch (command)
1732 {
1733 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1734 ToggleBandVisibility(ITBBID_TOOLSBAND);
1735 break;
1736 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1737 ToggleBandVisibility(ITBBID_ADDRESSBAND);
1738 break;
1739 case IDM_TOOLBARS_LINKSBAR: // links
1740 break;
1741 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1742 LockUnlockToolbars(!pSettings->fLocked);
1743 break;
1744 case IDM_TOOLBARS_CUSTOMIZE: // customize
1745 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1746 break;
1747 case IDM_TOOLBARS_GOBUTTON:
1748 SendMessage(fNavigationWindow, WM_COMMAND, IDM_TOOLBARS_GOBUTTON, 0);
1749 break;
1750 }
1751
1752 DestroyMenu(contextMenuBar);
1753 return 1;
1754 }
1755
1756 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1757 {
1758 if (wParam != SIZE_MINIMIZED)
1759 {
1760 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1761 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1762 }
1763 return 1;
1764 }
1765
1766 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1767 {
1768 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1769 {
1770 bHandled = FALSE;
1771 return 0;
1772 }
1773 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1774 return 1;
1775 }
1776
1777 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1778 {
1779 CComPtr<IBrowserService> browserService;
1780 CComPtr<ITravelLog> travelLog;
1781 TOOLTIPTEXTW *pTTTW;
1782 UINT nID;
1783 HRESULT hResult;
1784 wchar_t tempString[300];
1785
1786 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1787 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1788 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1789 else
1790 nID = (UINT)pNMHDR->idFrom;
1791
1792 if (nID != 0)
1793 {
1794 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1795 {
1796 // TODO: Should this call QueryService?
1797 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1798 hResult = browserService->GetTravelLog(&travelLog);
1799 hResult = travelLog->GetToolTipText(browserService,
1800 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1801 0, tempString, 299);
1802 if (FAILED_UNEXPECTEDLY(hResult))
1803 {
1804 bHandled = FALSE;
1805 return 0;
1806 }
1807 }
1808 else
1809 tempString[0] = 0;
1810 wcsncpy (pTTTW->szText, tempString, sizeof(pTTTW->szText) / sizeof(wchar_t));
1811 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1812 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1813 return 0;
1814 }
1815 return 0;
1816 }
1817
1818 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1819 {
1820 LRESULT theResult;
1821 HRESULT hResult;
1822
1823 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1824
1825 bHandled = hResult == S_OK;
1826
1827 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1828 }
1829 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1830 {
1831 NMHDR *notifyHeader;
1832 LRESULT theResult;
1833 HRESULT hResult;
1834
1835 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1836
1837 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1838
1839 bHandled = hResult == S_OK;
1840
1841 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1842 }
1843
1844 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1845 {
1846 bHandled = FALSE;
1847 if (pSettings->fLocked)
1848 return 0;
1849
1850 if (wParam & MK_CONTROL)
1851 return 0;
1852
1853 fSizing = TRUE;
1854
1855 DWORD msgp = GetMessagePos();
1856
1857 fStartPosition.x = GET_X_LPARAM(msgp);
1858 fStartPosition.y = GET_Y_LPARAM(msgp);
1859
1860 RECT rc;
1861 GetWindowRect(&rc);
1862
1863 fStartHeight = rc.bottom - rc.top;
1864
1865 SetCapture();
1866
1867 bHandled = TRUE;
1868 return 0;
1869 }
1870
1871 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1872 {
1873 bHandled = FALSE;
1874 if (!fSizing)
1875 return 0;
1876
1877 DWORD msgp = GetMessagePos();
1878
1879 POINT pt;
1880 pt.x = GET_X_LPARAM(msgp);
1881 pt.y = GET_Y_LPARAM(msgp);
1882
1883 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1884
1885 bHandled = TRUE;
1886 return 0;
1887 }
1888
1889 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1890 {
1891 bHandled = FALSE;
1892 if (!fSizing)
1893 return 0;
1894
1895 OnMouseMove(uMsg, wParam, lParam, bHandled);
1896
1897 fSizing = FALSE;
1898
1899 ReleaseCapture();
1900
1901 return 0;
1902 }
1903
1904 LRESULT CInternetToolbar::OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1905 {
1906 HRESULT hr;
1907 HWND hwndMenu;
1908
1909 hr = IUnknown_GetWindow(fMenuBar, &hwndMenu);
1910 if (FAILED_UNEXPECTEDLY(hr))
1911 return 0;
1912
1913 CComPtr<IWinEventHandler> menuWinEventHandler;
1914 hr = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1915 if (FAILED_UNEXPECTEDLY(hr))
1916 return 0;
1917
1918 LRESULT lres;
1919 hr = menuWinEventHandler->OnWinEvent(hwndMenu, uMsg, wParam, lParam, &lres);
1920 if (FAILED_UNEXPECTEDLY(hr))
1921 return 0;
1922
1923 return lres;
1924 }
1925
1926 LRESULT CInternetToolbar::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
1927 {
1928 /* Refresh toolbar locked state */
1929 RefreshLockedToolbarState();
1930
1931 return 0;
1932 }