[BROWSEUI]
[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_PPV_ARG(IObjectWithSite, &site));
165 if (FAILED(hResult))
166 return hResult;
167 hResult = containedBand->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
168 if (FAILED(hResult))
169 return hResult;
170 hResult = containedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &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_PPV_ARG(IDeskBand, &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_PPV_ARG(IShellMenu, &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_PPV_ARG(IShellMenu, &newMenu));
386 }
387 #else
388 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
389 IID_PPV_ARG(IShellMenu, &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_PPV_ARG(IDockingWindowSite, &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_PPV_ARG(IShellMenu, menuBar));
577 }
578 #else
579 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
580 IID_PPV_ARG(IShellMenu, menuBar));
581 #endif
582 if (FAILED(hResult))
583 return hResult;
584 hResult = fMenuCallback.QueryInterface(IID_PPV_ARG(IShellMenuCallback, &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_PPV_ARG(IOleWindow, &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_PPV_ARG(IOleCommandTarget, &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_PPV_ARG(IOleCommandTarget, &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_PPV_ARG(IUnknown, 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_PPV_ARG(IUnknown, 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_PPV_ARG(IUnknown, 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_PPV_ARG(IAddressBand, &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_PPV_ARG(IServiceProvider, &serviceProvider));
723 if (FAILED(hResult))
724 return hResult;
725 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
726 if (FAILED(hResult))
727 {
728 hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &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_PPV_ARG(IDockingWindow, &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 /* Create and attach the menubar to the rebar */
829 hResult = CreateMenuBar(&menuBar);
830 if (FAILED(hResult))
831 return hResult;
832 AddDockItem(menuBar, ITBBID_MENUBAND,
833 CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
834
835 hResult = menuBar->QueryInterface(IID_PPV_ARG(IOleWindow, &menuOleWindow));
836 hResult = menuOleWindow->GetWindow(&fMenuBandWindow);
837 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
838
839 /* Create and attach the brand/logo to the rebar */
840 hResult = CreateBrandBand(&logoBar);
841 if (FAILED(hResult))
842 return hResult;
843 AddDockItem(logoBar, ITBBID_BRANDBAND,
844 CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
845 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
846
847 /* Create and attach the standard toolbar to the rebar */
848 hResult = CreateToolsBar(&toolsBar);
849 if (FAILED(hResult))
850 return hResult;
851 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS);
852 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
853 hResult = fControlsBar->QueryInterface(IID_PPV_ARG(IOleWindow, &toolbarOleWindow));
854 if (FAILED(hResult))
855 return hResult;
856 hResult = toolbarOleWindow->GetWindow(&fToolbarWindow);
857 if (FAILED(hResult))
858 return hResult;
859
860 /* Create and attach the address/navigation toolbar to the rebar */
861 hResult = CreateAddressBand(&navigationBar);
862 if (FAILED(hResult))
863 return hResult;
864 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS);
865 hResult = navigationBar->QueryInterface(IID_PPV_ARG(IOleWindow, &navigationOleWindow));
866 hResult = navigationOleWindow->GetWindow(&fNavigationWindow);
867 fNavigationBar.Attach(navigationBar.Detach());
868
869 return S_OK;
870 }
871
872 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
873 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
874 {
875 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
876 {
877 while (cCmds != 0)
878 {
879 switch (prgCmds->cmdID)
880 {
881 case ITID_TEXTLABELS: // Text Labels state
882 prgCmds->cmdf = OLECMDF_SUPPORTED;
883 break;
884 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
885 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
886 break;
887 case ITID_ADDRESSBANDSHOWN: // address bar visibility
888 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
889 break;
890 case ITID_LINKSBANDSHOWN: // links bar visibility
891 prgCmds->cmdf = 0;
892 break;
893 case ITID_MENUBANDSHOWN: // Menubar band visibility
894 prgCmds->cmdf = 0;
895 break;
896 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
897 prgCmds->cmdf = 0;
898 break;
899 case ITID_CUSTOMIZEENABLED: // customize enabled
900 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
901 break;
902 case ITID_TOOLBARLOCKED: // lock toolbars
903 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
904 if (fLocked)
905 prgCmds->cmdf |= OLECMDF_LATCHED;
906 break;
907 default:
908 prgCmds->cmdf = 0;
909 break;
910 }
911 prgCmds++;
912 cCmds--;
913 }
914 return S_OK;
915 }
916 return E_FAIL;
917 }
918
919 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
920 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
921 {
922 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
923 {
924 switch (nCmdID)
925 {
926 case 1:
927 // what do I do here?
928 return S_OK;
929 case ITID_TEXTLABELS:
930 // toggle text labels
931 return S_OK;
932 case ITID_TOOLBARBANDSHOWN:
933 // toggle toolbar band visibility
934 return S_OK;
935 case ITID_ADDRESSBANDSHOWN:
936 // toggle address band visibility
937 return S_OK;
938 case ITID_LINKSBANDSHOWN:
939 // toggle links band visibility
940 return S_OK;
941 case ITID_CUSTOMIZEENABLED:
942 // run customize
943 return S_OK;
944 case ITID_TOOLBARLOCKED:
945 return LockUnlockToolbars(!fLocked);
946 }
947 }
948 return E_FAIL;
949 }
950
951 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
952 {
953 return E_NOTIMPL;
954 }
955
956 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
957 {
958 return E_NOTIMPL;
959 }
960
961 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
962 LCID lcid, DISPID *rgDispId)
963 {
964 return E_NOTIMPL;
965 }
966
967 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
968 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
969 {
970 HRESULT hResult;
971
972 switch(dispIdMember)
973 {
974 case DISPID_BEFORENAVIGATE:
975 hResult = S_OK;
976 break;
977 case DISPID_DOWNLOADCOMPLETE:
978 hResult = S_OK;
979 break;
980 case DISPID_COMMANDSTATECHANGE:
981 if (pDispParams->cArgs != 2)
982 return E_INVALIDARG;
983 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
984 return E_INVALIDARG;
985 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
986 V_I4(&pDispParams->rgvarg[1]));
987 case DISPID_DOWNLOADBEGIN:
988 hResult = S_OK;
989 break;
990 case DISPID_NAVIGATECOMPLETE2:
991 hResult = S_OK;
992 break;
993 case DISPID_DOCUMENTCOMPLETE:
994 hResult = S_OK;
995 break;
996 }
997 return S_OK;
998 }
999
1000 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1001 {
1002 HRESULT hResult;
1003
1004 fCommandTarget.Release();
1005 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1006 if (FAILED(hResult))
1007 return hResult;
1008 fCommandCategory = *category;
1009 return S_OK;
1010 }
1011
1012 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1013 {
1014 return E_NOTIMPL;
1015 }
1016
1017 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1018 {
1019 return E_NOTIMPL;
1020 }
1021
1022 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1023 HINSTANCE param10, LPCTSTR param14, long *param18)
1024 {
1025 long result;
1026
1027 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1028 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1029 *param18 = result;
1030 if (result == -1)
1031 return E_FAIL;
1032 return S_OK;
1033 }
1034
1035 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1036 {
1037 return E_NOTIMPL;
1038 }
1039
1040 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1041 {
1042 if (theState == NULL)
1043 return E_POINTER;
1044 // map the command id
1045 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1046 return S_OK;
1047 }
1048
1049 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1050 {
1051 // map the command id
1052 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1053 return S_OK;
1054 }
1055
1056 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1057 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1058 {
1059 return E_NOTIMPL;
1060 }
1061
1062 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1063 {
1064 if (paramC == NULL)
1065 return E_POINTER;
1066 *paramC = MAKELONG(24, 24);
1067 return S_OK;
1068 }
1069
1070 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1071 WPARAM wParam, LPARAM lParam, LRESULT *result)
1072 {
1073 return E_NOTIMPL;
1074 }
1075
1076 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1077 HIMAGELIST param14, HIMAGELIST param18)
1078 {
1079 return E_NOTIMPL;
1080 }
1081
1082 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1083 {
1084 return E_NOTIMPL;
1085 }
1086
1087 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1088 {
1089 return E_NOTIMPL;
1090 }
1091
1092 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1093 {
1094 CComPtr<IBrowserService> browserService;
1095 CComPtr<IServiceProvider> serviceProvider;
1096 CComPtr<IOleWindow> oleWindow;
1097 HWND ownerWindow;
1098 HWND dockContainer;
1099 HRESULT hResult;
1100 DWORD style;
1101
1102 if (pUnkSite == NULL)
1103 {
1104 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1105 ::DestroyWindow(fMainReBar);
1106 DestroyWindow();
1107 fSite.Release();
1108 }
1109 else
1110 {
1111 // get window handle of owner
1112 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
1113 if (FAILED(hResult))
1114 return hResult;
1115 hResult = oleWindow->GetWindow(&ownerWindow);
1116 if (FAILED(hResult))
1117 return hResult;
1118 if (ownerWindow == NULL)
1119 return E_FAIL;
1120
1121 // create dock container
1122 fSite = pUnkSite;
1123 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
1124 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
1125 if (dockContainer == NULL)
1126 return E_FAIL;
1127 SubclassWindow(dockContainer);
1128
1129 // create rebar in dock container
1130 style = WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_VARHEIGHT |
1131 RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
1132 fMainReBar = CreateWindow(REBARCLASSNAMEW, NULL, style,
1133 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1134 if (fMainReBar == NULL)
1135 return E_FAIL;
1136
1137 // take advice to watch events
1138 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1139 hResult = serviceProvider->QueryService(
1140 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1141 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
1142 }
1143 return S_OK;
1144 }
1145
1146 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1147 {
1148 if (ppvSite == NULL)
1149 return E_POINTER;
1150 if (fSite.p != NULL)
1151 return fSite->QueryInterface(riid, ppvSite);
1152 *ppvSite = NULL;
1153 return S_OK;
1154 }
1155
1156 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1157 {
1158 CComPtr<IServiceProvider> serviceProvider;
1159 HRESULT hResult;
1160
1161 if (IsEqualIID(guidService, IID_IBandSite))
1162 return this->QueryInterface(riid, ppvObject);
1163 if (IsEqualIID(guidService, SID_IBandProxy))
1164 {
1165 if (fBandProxy.p == NULL)
1166 {
1167 hResult = CreateAndInitBandProxy();
1168 if (FAILED(hResult))
1169 return hResult;
1170 }
1171 return fBandProxy->QueryInterface(riid, ppvObject);
1172 }
1173 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1174 }
1175
1176 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1177 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1178 {
1179 CComPtr<IWinEventHandler> menuWinEventHandler;
1180 HRESULT hResult;
1181
1182 if (fMenuBar)
1183 {
1184 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1185 if (menuWinEventHandler->IsWindowOwner(hWnd))
1186 {
1187 return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
1188 }
1189 }
1190
1191 return S_FALSE;
1192 }
1193
1194 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1195 {
1196 return E_NOTIMPL;
1197 }
1198
1199 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1200 {
1201 return E_NOTIMPL;
1202 }
1203
1204 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1205 {
1206 return E_NOTIMPL;
1207 }
1208
1209 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1210 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1211 {
1212 if (ppstb == NULL)
1213 return E_POINTER;
1214 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
1215 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1216 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1217 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1218 *ppstb = NULL;
1219 return E_FAIL;
1220 }
1221
1222 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1223 {
1224 return E_NOTIMPL;
1225 }
1226
1227 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1228 {
1229 return E_NOTIMPL;
1230 }
1231
1232 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1233 {
1234 return E_NOTIMPL;
1235 }
1236
1237 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1238 {
1239 return E_NOTIMPL;
1240 }
1241
1242 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1243 {
1244 return E_NOTIMPL;
1245 }
1246
1247 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1248 {
1249 CComPtr<IServiceProvider> serviceProvider;
1250 CComPtr<IWebBrowser> webBrowser;
1251 HRESULT hResult;
1252
1253 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1254 if (FAILED(hResult))
1255 return 0;
1256 hResult = serviceProvider->QueryService(SID_SShellBrowser,
1257 IID_PPV_ARG(IWebBrowser, &webBrowser));
1258 if (FAILED(hResult))
1259 return 0;
1260 hResult = webBrowser->GoBack();
1261 return 1;
1262 }
1263
1264 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1265 {
1266 CComPtr<IServiceProvider> serviceProvider;
1267 CComPtr<IWebBrowser> webBrowser;
1268 HRESULT hResult;
1269
1270 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1271 if (FAILED(hResult))
1272 return 0;
1273 hResult = serviceProvider->QueryService(
1274 SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1275 if (FAILED(hResult))
1276 return 0;
1277 hResult = webBrowser->GoForward();
1278 return 1;
1279 }
1280
1281 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1282 {
1283 CComPtr<IOleCommandTarget> oleCommandTarget;
1284 HRESULT hResult;
1285
1286 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1287 if (FAILED(hResult))
1288 return hResult;
1289 hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1290 return 1;
1291 }
1292
1293 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1294 {
1295 CComPtr<IObjectWithSite> objectWithSite;
1296 CComPtr<IContextMenu> contextMenu;
1297 CMINVOKECOMMANDINFO commandInfo;
1298 const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1299 HRESULT hResult;
1300
1301 // TODO: Query shell if this command is enabled first
1302
1303 memset(&commandInfo, 0, sizeof(commandInfo));
1304 commandInfo.cbSize = sizeof(commandInfo);
1305 commandInfo.hwnd = m_hWnd;
1306 commandInfo.lpParameters = searchGUID;
1307 commandInfo.nShow = SW_SHOWNORMAL;
1308
1309 hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1310 IID_PPV_ARG(IContextMenu, &contextMenu));
1311 if (FAILED(hResult))
1312 return 0;
1313 hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1314 if (FAILED(hResult))
1315 return 0;
1316 hResult = objectWithSite->SetSite(fSite);
1317 if (FAILED(hResult))
1318 return 0;
1319 hResult = contextMenu->InvokeCommand(&commandInfo);
1320 hResult = objectWithSite->SetSite(NULL);
1321 return 0;
1322 }
1323
1324 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1325 {
1326 CComPtr<IOleCommandTarget> oleCommandTarget;
1327 HRESULT hResult;
1328
1329 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1330 if (FAILED(hResult))
1331 return hResult;
1332 hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
1333 return 1;
1334 }
1335
1336 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1337 {
1338 HRESULT hResult;
1339
1340 if (fCommandTarget.p != NULL)
1341 {
1342 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1343 }
1344 return 1;
1345 }
1346
1347 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1348 {
1349 CComPtr<IServiceProvider> serviceProvider;
1350 CComPtr<IBrowserService> browserService;
1351 CComPtr<IOleCommandTarget> commandTarget;
1352 CComPtr<ITravelLog> travelLog;
1353 NMTOOLBARW *notifyInfo;
1354 RECT bounds;
1355 HMENU newMenu;
1356 TPMPARAMS params;
1357 int selectedItem;
1358 VARIANT parmIn;
1359 OLECMD commandInfo;
1360 HRESULT hResult;
1361
1362 notifyInfo = (NMTOOLBARW *)pNMHDR;
1363 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1364 {
1365 // not from the toolbar, keep looking for a message handler
1366 bHandled = FALSE;
1367 return 0;
1368 }
1369 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1370 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1371 switch (notifyInfo->iItem)
1372 {
1373 case gBackCommandID:
1374 newMenu = CreatePopupMenu();
1375 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1376 hResult = serviceProvider->QueryService(
1377 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1378 hResult = browserService->GetTravelLog(&travelLog);
1379 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1380 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1381 commandInfo.cmdID = 0x1d;
1382 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1383 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1384 travelLog->CountEntries(browserService) > 1)
1385 {
1386 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1387 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1388 }
1389 params.cbSize = sizeof (params);
1390 params.rcExclude = bounds;
1391 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1392 bounds.left, bounds.bottom, m_hWnd, &params);
1393 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1394 {
1395 V_VT(&parmIn) = VT_I4;
1396 V_I4(&parmIn) = 1;
1397 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1398 }
1399 else if (selectedItem != 0)
1400 hResult = travelLog->Travel(browserService, -selectedItem);
1401 DestroyMenu(newMenu);
1402 break;
1403 case gForwardCommandID:
1404 newMenu = CreatePopupMenu();
1405 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1406 hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_IBrowserService,
1407 reinterpret_cast<void **>(&browserService));
1408 hResult = browserService->GetTravelLog(&travelLog);
1409 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1410 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1411 commandInfo.cmdID = 0x1d;
1412 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1413 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1414 travelLog->CountEntries(browserService) > 1)
1415 {
1416 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1417 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1418 }
1419 params.cbSize = sizeof (params);
1420 params.rcExclude = bounds;
1421 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1422 bounds.left, bounds.bottom, m_hWnd, &params);
1423 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1424 {
1425 V_VT(&parmIn) = VT_I4;
1426 V_I4(&parmIn) = 1;
1427 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1428 }
1429 else if (selectedItem != 0)
1430 hResult = travelLog->Travel(browserService, -selectedItem);
1431 DestroyMenu(newMenu);
1432 break;
1433 case gViewsCommandID:
1434 VARIANT inValue;
1435 CComVariant outValue;
1436 HRESULT hResult;
1437
1438 V_VT(&inValue) = VT_INT_PTR;
1439 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1440
1441 if (fCommandTarget.p != NULL)
1442 hResult = fCommandTarget->Exec(&fCommandCategory, 0x7031, 1, &inValue, &outValue);
1443 // pvaOut is VT_I4 with value 0x403
1444 break;
1445 }
1446 return TBDDRET_DEFAULT;
1447 }
1448
1449 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1450 {
1451 return 1;
1452 }
1453
1454 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1455 {
1456 return 1;
1457 }
1458
1459 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1460 {
1461 HMENU contextMenuBar;
1462 HMENU contextMenu;
1463 POINT clickLocation;
1464 int command;
1465 RBHITTESTINFO hitTestInfo;
1466 REBARBANDINFOW rebarBandInfo;
1467 int bandID;
1468
1469 clickLocation.x = LOWORD(lParam);
1470 clickLocation.y = HIWORD(lParam);
1471 hitTestInfo.pt = clickLocation;
1472 ScreenToClient(&hitTestInfo.pt);
1473 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1474 if (hitTestInfo.iBand == -1)
1475 return 0;
1476 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1477 rebarBandInfo.fMask = RBBIM_ID;
1478 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1479 bandID = rebarBandInfo.wID;
1480 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1481 contextMenu = GetSubMenu(contextMenuBar, 0);
1482 switch (bandID)
1483 {
1484 case ITBBID_MENUBAND: // menu band
1485 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1486 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1487 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1488 break;
1489 case ITBBID_BRANDBAND: // brand band
1490 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1491 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1492 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1493 break;
1494 case ITBBID_TOOLSBAND: // tools band
1495 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1496 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1497 break;
1498 case ITBBID_ADDRESSBAND: // navigation band
1499 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1500 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1501 break;
1502 default:
1503 break;
1504 }
1505 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1506 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1507 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1508 switch (command)
1509 {
1510 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1511 break;
1512 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1513 break;
1514 case IDM_TOOLBARS_LINKSBAR: // links
1515 break;
1516 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1517 LockUnlockToolbars(!fLocked);
1518 break;
1519 case IDM_TOOLBARS_CUSTOMIZE: // customize
1520 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1521 break;
1522 }
1523 return 1;
1524 }
1525
1526 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1527 {
1528 if (wParam != SIZE_MINIMIZED)
1529 {
1530 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1531 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1532 }
1533 return 1;
1534 }
1535
1536 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1537 {
1538 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1539 {
1540 bHandled = FALSE;
1541 return 0;
1542 }
1543 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1544 return 1;
1545 }
1546
1547 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1548 {
1549 CComPtr<IBrowserService> browserService;
1550 CComPtr<ITravelLog> travelLog;
1551 TOOLTIPTEXTW *pTTTW;
1552 UINT nID;
1553 wchar_t tempString[300];
1554 HRESULT hResult;
1555
1556 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1557 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1558 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1559 else
1560 nID = (UINT)pNMHDR->idFrom;
1561
1562 if (nID != 0)
1563 {
1564 if (nID == (UINT)gBackCommandID || nID == (UINT)gForwardCommandID)
1565 {
1566 // TODO: Should this call QueryService?
1567 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1568 hResult = browserService->GetTravelLog(&travelLog);
1569 hResult = travelLog->GetToolTipText(browserService,
1570 (nID == (UINT)gBackCommandID) ? TLOG_BACK : TLOG_FORE,
1571 0, tempString, 299);
1572 if (FAILED(hResult))
1573 {
1574 bHandled = FALSE;
1575 return 0;
1576 }
1577 }
1578 else
1579 tempString[0] = 0;
1580 wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
1581 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1582 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1583 return 0;
1584 }
1585 return 0;
1586 }
1587
1588 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1589 {
1590 LRESULT theResult;
1591 HRESULT hResult;
1592 HWND target = (HWND) lParam;
1593
1594 if (fMenuBar)
1595 {
1596 CComPtr<IWinEventHandler> menuWinEventHandler;
1597 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1598 if (SUCCEEDED(hResult))
1599 {
1600 if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
1601 {
1602 hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
1603 return FAILED(hResult) ? 0 : theResult;
1604 }
1605 }
1606 }
1607
1608 if (fNavigationBar)
1609 {
1610 CComPtr<IWinEventHandler> menuWinEventHandler;
1611 hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1612 if (SUCCEEDED(hResult))
1613 {
1614 if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
1615 {
1616 hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
1617 return FAILED(hResult) ? 0 : theResult;
1618 }
1619 }
1620 }
1621
1622 return 0;
1623 }
1624 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1625 {
1626 NMHDR *notifyHeader;
1627 LRESULT theResult;
1628 HRESULT hResult;
1629
1630 notifyHeader = (NMHDR *) lParam;
1631
1632 if (fMenuBar)
1633 {
1634 CComPtr<IWinEventHandler> menuWinEventHandler;
1635 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1636 if (SUCCEEDED(hResult))
1637 {
1638 if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
1639 {
1640 hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1641 return FAILED(hResult) ? 0 : theResult;
1642 }
1643 }
1644 }
1645
1646 if (fNavigationBar)
1647 {
1648 CComPtr<IWinEventHandler> menuWinEventHandler;
1649 hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1650 if (SUCCEEDED(hResult))
1651 {
1652 if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
1653 {
1654 hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1655 return FAILED(hResult) ? 0 : theResult;
1656 }
1657 }
1658 }
1659
1660 return 0;
1661 }
1662
1663 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1664 {
1665 CComObject<CInternetToolbar> *theToolbar;
1666 HRESULT hResult;
1667
1668 if (ppv == NULL)
1669 return E_POINTER;
1670 *ppv = NULL;
1671 ATLTRY (theToolbar = new CComObject<CInternetToolbar>);
1672 if (theToolbar == NULL)
1673 return E_OUTOFMEMORY;
1674 hResult = theToolbar->QueryInterface (riid, reinterpret_cast<void **>(ppv));
1675 if (FAILED(hResult))
1676 {
1677 delete theToolbar;
1678 return hResult;
1679 }
1680 return S_OK;
1681 }