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