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