[BROWSEUI]
[reactos.git] / reactos / dll / win32 / browseui / internettoolbar.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /*
22 Implements a class that knows how to hold and manage the menu band, brand band,
23 toolbar, and address band for an explorer window
24 */
25
26 #include "precomp.h"
27
28 /* FIXME, I can't include windowsx because it conflicts with some #defines */
29 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
30 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
31
32 #if 1
33
34 interface IAugmentedShellFolder : public IShellFolder
35 {
36 virtual HRESULT STDMETHODCALLTYPE AddNameSpace(LPGUID, IShellFolder *, LPCITEMIDLIST, ULONG) = 0;
37 virtual HRESULT STDMETHODCALLTYPE GetNameSpaceID(LPCITEMIDLIST, LPGUID) = 0;
38 virtual HRESULT STDMETHODCALLTYPE QueryNameSpace(ULONG, LPGUID, IShellFolder **) = 0;
39 virtual HRESULT STDMETHODCALLTYPE EnumNameSpace(ULONG, PULONG) = 0;
40 };
41
42 #endif
43
44 // navigation controls and menubar just send a message to parent window
45 /*
46 TODO:
47 ****Implement BandProxy methods
48 ****Add QueryStatus handler for built-in bands
49 ****Enable/Disable up, search, and folders commands appropriately
50 **Why are explorer toolbar separators a nonstandard width?
51 **Remove "(Empty)" item from Favorites menu. Probably something missing in CMenuCallback::CallbackSM
52 **Chevron menu on menuband doesn't work
53 **Fix CInternetToolbar::QueryBand to be generic
54
55 ****Fix context menu to strip divider when menu shown for menu band
56 ****Fix context menu to have items checked appropriately
57 ****Implement -1 command id update
58 ****When bands are rearranged, resize the internet toolbar and fix height of brand band
59 ****Right clicking on the browse back and forward toolbar buttons displays the same as pulldown menus
60 Implement show/hide of bands
61 Why is the background color of my toolbars different from explorer?
62 Internet Toolbar command handler should get the target for the command and call Exec on the target.
63 For commands built in to the Internet Toolbar, its Exec handles the command
64 When window width is changed, brand band flashes badly
65 Add all bands with correct ids (system bands now add with correct ids)
66 Implement IBandSite
67 Implement remaining IExplorerToolbar methods
68 Fix toolbar buttons to enable/disable correctly
69 After toolbar is customized, it may be necessary to patch the widths of separators
70 Add theme support
71 Check sizes and spacing of toolbars against Explorer
72 Implement resizing of the dock bar
73 Add missing icons for toolbar items
74 Draw History item in forward/back dropdown menus with icon
75 Fix toolbar customize dialog to not include separators as possible selections
76 Implement save/restore of toolbar state
77 Refactor drop down menu code to use a common function since code is so similar
78 */
79
80 extern HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder);
81
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 return S_OK;
938 }
939
940 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
941 IUnknown *punkToolbarSite, BOOL fReserved)
942 {
943 RECT neededBorderSpace;
944 RECT availableBorderSpace = *prcBorder;
945
946 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
947
948 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
949 // Let's make sure we fetch the actual size properly.
950 ::GetWindowRect(fMainReBar, &availableBorderSpace);
951 neededBorderSpace.left = 0;
952 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
953 if (!fLocked)
954 neededBorderSpace.top += 3;
955 neededBorderSpace.right = 0;
956 neededBorderSpace.bottom = 0;
957
958 CComPtr<IDockingWindowSite> dockingWindowSite;
959
960 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
961 if (FAILED_UNEXPECTEDLY(hResult))
962 return hResult;
963
964 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
965 if (FAILED_UNEXPECTEDLY(hResult))
966 return hResult;
967
968 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
969 if (FAILED_UNEXPECTEDLY(hResult))
970 return hResult;
971
972 return S_OK;
973 }
974
975 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
976 {
977 if (pClassID == NULL)
978 return E_POINTER;
979 *pClassID = CLSID_InternetToolbar;
980 return S_OK;
981 }
982
983 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
984 {
985 return E_NOTIMPL;
986 }
987
988 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
989 {
990 return E_NOTIMPL;
991 }
992
993 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
994 {
995 return E_NOTIMPL;
996 }
997
998 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
999 {
1000 return E_NOTIMPL;
1001 }
1002
1003 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
1004 {
1005 CComPtr<IShellMenu> menuBar;
1006 CComPtr<IUnknown> logoBar;
1007 CComPtr<IUnknown> toolsBar;
1008 CComPtr<IUnknown> navigationBar;
1009 HRESULT hResult;
1010
1011 /* Create and attach the menubar to the rebar */
1012 hResult = CreateMenuBar(&menuBar);
1013 if (FAILED_UNEXPECTEDLY(hResult))
1014 return hResult;
1015 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1016
1017 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
1018 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
1019
1020 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1021 // and it will put them in their own row, sized to take up the whole row.
1022 #if 0
1023 /* Create and attach the brand/logo to the rebar */
1024 hResult = CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown, &logoBar));
1025 if (FAILED_UNEXPECTEDLY(hResult))
1026 return hResult;
1027 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
1028 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
1029 #endif
1030
1031 /* Create and attach the standard toolbar to the rebar */
1032 hResult = CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown, &toolsBar));
1033 if (FAILED_UNEXPECTEDLY(hResult))
1034 return hResult;
1035 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1036 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
1037 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow);
1038 if (FAILED_UNEXPECTEDLY(hResult))
1039 return hResult;
1040
1041 /* Create and attach the address/navigation toolbar to the rebar */
1042 hResult = CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown, &navigationBar));
1043 if (FAILED_UNEXPECTEDLY(hResult))
1044 return hResult;
1045 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1046 fNavigationBar.Attach(navigationBar.Detach());
1047 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
1048
1049 return S_OK;
1050 }
1051
1052 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
1053 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
1054 {
1055 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1056 {
1057 while (cCmds != 0)
1058 {
1059 switch (prgCmds->cmdID)
1060 {
1061 case ITID_TEXTLABELS: // Text Labels state
1062 prgCmds->cmdf = OLECMDF_SUPPORTED;
1063 break;
1064 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
1065 prgCmds->cmdf = OLECMDF_SUPPORTED;
1066 if (fControlsBar)
1067 prgCmds->cmdf |= OLECMDF_LATCHED;
1068 break;
1069 case ITID_ADDRESSBANDSHOWN: // address bar visibility
1070 prgCmds->cmdf = OLECMDF_SUPPORTED;
1071 if (fNavigationBar)
1072 prgCmds->cmdf |= OLECMDF_LATCHED;
1073 break;
1074 case ITID_LINKSBANDSHOWN: // links bar visibility
1075 prgCmds->cmdf = 0;
1076 break;
1077 case ITID_MENUBANDSHOWN: // Menubar band visibility
1078 prgCmds->cmdf = OLECMDF_SUPPORTED;
1079 if (fMenuBar)
1080 prgCmds->cmdf |= OLECMDF_LATCHED;
1081 break;
1082 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
1083 prgCmds->cmdf = 0;
1084 break;
1085 case ITID_CUSTOMIZEENABLED: // customize enabled
1086 prgCmds->cmdf = OLECMDF_SUPPORTED;
1087 break;
1088 case ITID_TOOLBARLOCKED: // lock toolbars
1089 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1090 if (fLocked)
1091 prgCmds->cmdf |= OLECMDF_LATCHED;
1092 break;
1093 default:
1094 prgCmds->cmdf = 0;
1095 break;
1096 }
1097 prgCmds++;
1098 cCmds--;
1099 }
1100 return S_OK;
1101 }
1102 return E_FAIL;
1103 }
1104
1105 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
1106 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1107 {
1108 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1109 {
1110 switch (nCmdID)
1111 {
1112 case 1:
1113 // what do I do here?
1114 return S_OK;
1115 case ITID_TEXTLABELS:
1116 // toggle text labels
1117 return S_OK;
1118 case ITID_TOOLBARBANDSHOWN:
1119 // toggle toolbar band visibility
1120 return S_OK;
1121 case ITID_ADDRESSBANDSHOWN:
1122 // toggle address band visibility
1123 return S_OK;
1124 case ITID_LINKSBANDSHOWN:
1125 // toggle links band visibility
1126 return S_OK;
1127 case ITID_CUSTOMIZEENABLED:
1128 // run customize
1129 return S_OK;
1130 case ITID_TOOLBARLOCKED:
1131 return LockUnlockToolbars(!fLocked);
1132 }
1133 }
1134 return E_FAIL;
1135 }
1136
1137 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
1138 {
1139 return E_NOTIMPL;
1140 }
1141
1142 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1143 {
1144 return E_NOTIMPL;
1145 }
1146
1147 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1148 LCID lcid, DISPID *rgDispId)
1149 {
1150 return E_NOTIMPL;
1151 }
1152
1153 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1154 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1155 {
1156 HRESULT hResult;
1157
1158 switch(dispIdMember)
1159 {
1160 case DISPID_BEFORENAVIGATE:
1161 hResult = S_OK;
1162 break;
1163 case DISPID_DOWNLOADCOMPLETE:
1164 hResult = S_OK;
1165 break;
1166 case DISPID_COMMANDSTATECHANGE:
1167 if (pDispParams->cArgs != 2)
1168 return E_INVALIDARG;
1169 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
1170 return E_INVALIDARG;
1171 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
1172 V_I4(&pDispParams->rgvarg[1]));
1173 case DISPID_DOWNLOADBEGIN:
1174 hResult = S_OK;
1175 break;
1176 case DISPID_NAVIGATECOMPLETE2:
1177 hResult = S_OK;
1178 break;
1179 case DISPID_DOCUMENTCOMPLETE:
1180 hResult = S_OK;
1181 break;
1182 }
1183 return S_OK;
1184 }
1185
1186 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1187 {
1188 HRESULT hResult;
1189
1190 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14);
1191
1192 fCommandTarget.Release();
1193 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1194 if (FAILED_UNEXPECTEDLY(hResult))
1195 return hResult;
1196 fCommandCategory = *category;
1197 return S_OK;
1198 }
1199
1200 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1201 {
1202 return E_NOTIMPL;
1203 }
1204
1205 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1206 {
1207 return E_NOTIMPL;
1208 }
1209
1210 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1211 HINSTANCE param10, LPCTSTR param14, long *param18)
1212 {
1213 long result;
1214
1215 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1216 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1217 *param18 = result;
1218 if (result == -1)
1219 return E_FAIL;
1220 return S_OK;
1221 }
1222
1223 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1224 {
1225 return E_NOTIMPL;
1226 }
1227
1228 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1229 {
1230 if (theState == NULL)
1231 return E_POINTER;
1232 // map the command id
1233 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1234 return S_OK;
1235 }
1236
1237 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1238 {
1239 // map the command id
1240 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1241 return S_OK;
1242 }
1243
1244 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1245 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1246 {
1247 return E_NOTIMPL;
1248 }
1249
1250 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1251 {
1252 if (paramC == NULL)
1253 return E_POINTER;
1254 *paramC = MAKELONG(24, 24);
1255 return S_OK;
1256 }
1257
1258 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1259 WPARAM wParam, LPARAM lParam, LRESULT *result)
1260 {
1261 return E_NOTIMPL;
1262 }
1263
1264 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1265 HIMAGELIST param14, HIMAGELIST param18)
1266 {
1267 return E_NOTIMPL;
1268 }
1269
1270 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1271 {
1272 return E_NOTIMPL;
1273 }
1274
1275 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1276 {
1277 return E_NOTIMPL;
1278 }
1279
1280 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1281 {
1282 CComPtr<IBrowserService> browserService;
1283 HWND ownerWindow;
1284 HWND dockContainer;
1285 HRESULT hResult;
1286
1287 if (pUnkSite == NULL)
1288 {
1289 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1290 ::DestroyWindow(fMainReBar);
1291 DestroyWindow();
1292 fSite.Release();
1293 }
1294 else
1295 {
1296 // get window handle of owner
1297 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow);
1298 if (FAILED_UNEXPECTEDLY(hResult))
1299 return hResult;
1300 if (ownerWindow == NULL)
1301 return E_FAIL;
1302
1303 // create dock container
1304 fSite = pUnkSite;
1305 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
1306 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
1307 if (dockContainer == NULL)
1308 return E_FAIL;
1309 SubclassWindow(dockContainer);
1310
1311 // create rebar in dock container
1312 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
1313 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
1314 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
1315 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
1316 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
1317 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1318 if (fMainReBar == NULL)
1319 return E_FAIL;
1320
1321 // take advice to watch events
1322 hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1323 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
1324 }
1325 return S_OK;
1326 }
1327
1328 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1329 {
1330 if (ppvSite == NULL)
1331 return E_POINTER;
1332 if (fSite.p != NULL)
1333 return fSite->QueryInterface(riid, ppvSite);
1334 *ppvSite = NULL;
1335 return S_OK;
1336 }
1337
1338 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1339 {
1340 HRESULT hResult;
1341
1342 if (IsEqualIID(guidService, IID_IBandSite))
1343 return this->QueryInterface(riid, ppvObject);
1344 if (IsEqualIID(guidService, SID_IBandProxy))
1345 {
1346 if (fBandProxy.p == NULL)
1347 {
1348 hResult = CreateAndInitBandProxy();
1349 if (FAILED_UNEXPECTEDLY(hResult))
1350 return hResult;
1351 }
1352 return fBandProxy->QueryInterface(riid, ppvObject);
1353 }
1354 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1355 }
1356
1357 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1358 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1359 {
1360 HRESULT hResult;
1361
1362 if (fMenuBar)
1363 {
1364 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult);
1365 if (hResult != S_FALSE)
1366 return hResult;
1367 }
1368
1369 if (fNavigationBar)
1370 {
1371 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult);
1372 if (hResult != S_FALSE)
1373 return hResult;
1374 }
1375
1376 if (fLogoBar)
1377 {
1378 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult);
1379 if (hResult != S_FALSE)
1380 return hResult;
1381 }
1382
1383 return S_FALSE;
1384 }
1385
1386 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1387 {
1388 UNIMPLEMENTED;
1389 return E_NOTIMPL;
1390 }
1391
1392 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1393 {
1394 UNIMPLEMENTED;
1395 return E_NOTIMPL;
1396 }
1397
1398 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1399 {
1400 UNIMPLEMENTED;
1401 return E_NOTIMPL;
1402 }
1403
1404 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1405 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1406 {
1407 if (ppstb == NULL)
1408 return E_POINTER;
1409 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
1410 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1411 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1412 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1413 *ppstb = NULL;
1414 return E_FAIL;
1415 }
1416
1417 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1418 {
1419 UNIMPLEMENTED;
1420 return E_NOTIMPL;
1421 }
1422
1423 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1424 {
1425 UNIMPLEMENTED;
1426 return E_NOTIMPL;
1427 }
1428
1429 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1430 {
1431 UNIMPLEMENTED;
1432 return E_NOTIMPL;
1433 }
1434
1435 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1436 {
1437 UNIMPLEMENTED;
1438 return E_NOTIMPL;
1439 }
1440
1441 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1442 {
1443 UNIMPLEMENTED;
1444 return E_NOTIMPL;
1445 }
1446
1447 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1448 {
1449 CComPtr<IWebBrowser> webBrowser;
1450 HRESULT hResult;
1451
1452 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1453 if (FAILED_UNEXPECTEDLY(hResult))
1454 return 0;
1455 hResult = webBrowser->GoBack();
1456 return 1;
1457 }
1458
1459 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1460 {
1461 CComPtr<IWebBrowser> webBrowser;
1462 HRESULT hResult;
1463
1464 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1465 if (FAILED_UNEXPECTEDLY(hResult))
1466 return 0;
1467 hResult = webBrowser->GoForward();
1468 return 1;
1469 }
1470
1471 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1472 {
1473 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1474 return 1;
1475 }
1476
1477 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1478 {
1479 return IUnknown_Exec(fSite, CLSID_CommonButtons, 0x123, 1, NULL, NULL);
1480 }
1481
1482 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1483 {
1484 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL);
1485 return 1;
1486 }
1487
1488 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1489 {
1490 HRESULT hResult;
1491
1492 if (fCommandTarget.p != NULL)
1493 {
1494 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1495 }
1496 return 1;
1497 }
1498
1499 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1500 {
1501 CComPtr<IBrowserService> browserService;
1502 CComPtr<IOleCommandTarget> commandTarget;
1503 CComPtr<ITravelLog> travelLog;
1504 NMTOOLBARW *notifyInfo;
1505 RECT bounds;
1506 HMENU newMenu;
1507 TPMPARAMS params;
1508 int selectedItem;
1509 VARIANT parmIn;
1510 OLECMD commandInfo;
1511 HRESULT hResult;
1512 wchar_t templateString[200];
1513
1514 notifyInfo = (NMTOOLBARW *)pNMHDR;
1515 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1516 {
1517 // not from the toolbar, keep looking for a message handler
1518 bHandled = FALSE;
1519 return 0;
1520 }
1521 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1522 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1523 switch (notifyInfo->iItem)
1524 {
1525 case IDM_GOTO_BACK:
1526 newMenu = CreatePopupMenu();
1527 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1528 hResult = browserService->GetTravelLog(&travelLog);
1529 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1530 commandInfo.cmdID = 0x1d;
1531 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1532 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1533 travelLog->CountEntries(browserService) > 1)
1534 {
1535 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1536
1537 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1538 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1539 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1540
1541 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1542 }
1543 params.cbSize = sizeof(params);
1544 params.rcExclude = bounds;
1545 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1546 bounds.left, bounds.bottom, m_hWnd, &params);
1547 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1548 {
1549 V_VT(&parmIn) = VT_I4;
1550 V_I4(&parmIn) = 1;
1551 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1552 }
1553 else if (selectedItem != 0)
1554 hResult = travelLog->Travel(browserService, -selectedItem);
1555 DestroyMenu(newMenu);
1556 break;
1557 case IDM_GOTO_FORWARD:
1558 newMenu = CreatePopupMenu();
1559 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1560 hResult = browserService->GetTravelLog(&travelLog);
1561 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1562 commandInfo.cmdID = 0x1d;
1563 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL);
1564 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1565 travelLog->CountEntries(browserService) > 1)
1566 {
1567 AppendMenuW(newMenu, MF_SEPARATOR, -1, L"");
1568
1569 if (LoadStringW(_AtlBaseModule.GetResourceInstance(),
1570 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0)
1571 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H");
1572
1573 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString);
1574 }
1575 params.cbSize = sizeof(params);
1576 params.rcExclude = bounds;
1577 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1578 bounds.left, bounds.bottom, m_hWnd, &params);
1579 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1580 {
1581 V_VT(&parmIn) = VT_I4;
1582 V_I4(&parmIn) = 1;
1583 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1584 }
1585 else if (selectedItem != 0)
1586 hResult = travelLog->Travel(browserService, selectedItem);
1587 DestroyMenu(newMenu);
1588 break;
1589 case gViewsCommandID:
1590 VARIANT inValue;
1591 CComVariant outValue;
1592 HRESULT hResult;
1593
1594 V_VT(&inValue) = VT_INT_PTR;
1595 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1596
1597 if (fCommandTarget.p != NULL)
1598 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue);
1599 // pvaOut is VT_I4 with value 0x403
1600 break;
1601 }
1602 return TBDDRET_DEFAULT;
1603 }
1604
1605 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1606 {
1607 return 1;
1608 }
1609
1610 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1611 {
1612 return 1;
1613 }
1614
1615 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1616 {
1617 HMENU contextMenuBar;
1618 HMENU contextMenu;
1619 POINT clickLocation;
1620 int command;
1621 RBHITTESTINFO hitTestInfo;
1622 REBARBANDINFOW rebarBandInfo;
1623 int bandID;
1624 BOOL goButtonChecked;
1625
1626 clickLocation.x = LOWORD(lParam);
1627 clickLocation.y = HIWORD(lParam);
1628 hitTestInfo.pt = clickLocation;
1629 ScreenToClient(&hitTestInfo.pt);
1630 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1631 if (hitTestInfo.iBand == -1)
1632 return 0;
1633 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1634 rebarBandInfo.fMask = RBBIM_ID;
1635 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1636 bandID = rebarBandInfo.wID;
1637 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1638 contextMenu = GetSubMenu(contextMenuBar, 0);
1639 switch (bandID)
1640 {
1641 case ITBBID_MENUBAND: // menu band
1642 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1643 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1644 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1645 break;
1646 case ITBBID_BRANDBAND: // brand band
1647 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1648 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1649 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1650 break;
1651 case ITBBID_TOOLSBAND: // tools band
1652 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1653 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1654 break;
1655 case ITBBID_ADDRESSBAND: // navigation band
1656 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1657 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1658 break;
1659 default:
1660 break;
1661 }
1662
1663 // TODO: Implement show/hide toolbars
1664 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, FALSE);
1665 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, FALSE);
1666 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1667 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1668
1669 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, fControlsBar != NULL);
1670 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, fNavigationBar != NULL);
1671 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
1672 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
1673 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked);
1674 goButtonChecked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE);
1675 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, goButtonChecked);
1676
1677 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1678 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1679 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1680 switch (command)
1681 {
1682 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1683 break;
1684 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1685 break;
1686 case IDM_TOOLBARS_LINKSBAR: // links
1687 break;
1688 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1689 LockUnlockToolbars(!fLocked);
1690 break;
1691 case IDM_TOOLBARS_CUSTOMIZE: // customize
1692 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1693 break;
1694 case IDM_TOOLBARS_GOBUTTON:
1695 SendMessage(fNavigationWindow, WM_COMMAND, IDM_TOOLBARS_GOBUTTON, 0);
1696 break;
1697 }
1698
1699 DestroyMenu(contextMenuBar);
1700 return 1;
1701 }
1702
1703 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1704 {
1705 if (wParam != SIZE_MINIMIZED)
1706 {
1707 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1708 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1709 }
1710 return 1;
1711 }
1712
1713 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1714 {
1715 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1716 {
1717 bHandled = FALSE;
1718 return 0;
1719 }
1720 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1721 return 1;
1722 }
1723
1724 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1725 {
1726 CComPtr<IBrowserService> browserService;
1727 CComPtr<ITravelLog> travelLog;
1728 TOOLTIPTEXTW *pTTTW;
1729 UINT nID;
1730 HRESULT hResult;
1731 wchar_t tempString[300];
1732
1733 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1734 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1735 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1736 else
1737 nID = (UINT)pNMHDR->idFrom;
1738
1739 if (nID != 0)
1740 {
1741 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1742 {
1743 // TODO: Should this call QueryService?
1744 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1745 hResult = browserService->GetTravelLog(&travelLog);
1746 hResult = travelLog->GetToolTipText(browserService,
1747 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1748 0, tempString, 299);
1749 if (FAILED_UNEXPECTEDLY(hResult))
1750 {
1751 bHandled = FALSE;
1752 return 0;
1753 }
1754 }
1755 else
1756 tempString[0] = 0;
1757 wcsncpy (pTTTW->szText, tempString, sizeof(pTTTW->szText) / sizeof(wchar_t));
1758 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1759 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1760 return 0;
1761 }
1762 return 0;
1763 }
1764
1765 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1766 {
1767 LRESULT theResult;
1768 HRESULT hResult;
1769
1770 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1771
1772 bHandled = hResult == S_OK;
1773
1774 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1775 }
1776 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1777 {
1778 NMHDR *notifyHeader;
1779 LRESULT theResult;
1780 HRESULT hResult;
1781
1782 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1783
1784 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1785
1786 bHandled = hResult == S_OK;
1787
1788 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1789 }
1790
1791 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1792 {
1793 bHandled = FALSE;
1794 if (fLocked)
1795 return 0;
1796
1797 if (wParam & MK_CONTROL)
1798 return 0;
1799
1800 fSizing = TRUE;
1801
1802 DWORD msgp = GetMessagePos();
1803
1804 fStartPosition.x = GET_X_LPARAM(msgp);
1805 fStartPosition.y = GET_Y_LPARAM(msgp);
1806
1807 RECT rc;
1808 GetWindowRect(&rc);
1809
1810 fStartHeight = rc.bottom - rc.top;
1811
1812 SetCapture();
1813
1814 bHandled = TRUE;
1815 return 0;
1816 }
1817
1818 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1819 {
1820 bHandled = FALSE;
1821 if (!fSizing)
1822 return 0;
1823
1824 DWORD msgp = GetMessagePos();
1825
1826 POINT pt;
1827 pt.x = GET_X_LPARAM(msgp);
1828 pt.y = GET_Y_LPARAM(msgp);
1829
1830 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1831
1832 bHandled = TRUE;
1833 return 0;
1834 }
1835
1836 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1837 {
1838 bHandled = FALSE;
1839 if (!fSizing)
1840 return 0;
1841
1842 OnMouseMove(uMsg, wParam, lParam, bHandled);
1843
1844 fSizing = FALSE;
1845
1846 ReleaseCapture();
1847
1848 return 0;
1849 }
1850