[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 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
532 // Let's make sure we fetch the actual size properly.
533 GetWindowRect(fMainReBar, &availableBorderSpace);
534 neededBorderSpace.left = 0;
535 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
536 if (!fLocked)
537 neededBorderSpace.top += 3;
538 neededBorderSpace.right = 0;
539 neededBorderSpace.bottom = 0;
540 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
541 if (FAILED(hResult))
542 return hResult;
543 return S_OK;
544 }
545
546 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
547 {
548 CComPtr<IOleCommandTarget> siteCommandTarget;
549 CComPtr<IOleWindow> oleWindow;
550 CComPtr<IOleCommandTarget> commandTarget;
551 CComPtr<IShellMenuCallback> callback;
552 VARIANT menuOut;
553 HWND ownerWindow;
554 HRESULT hResult;
555
556 #if USE_CUSTOM_MENUBAND
557 HMODULE hrs = LoadLibraryW(L"rshell.dll");
558
559 if (!hrs)
560 {
561 DbgPrint("Failed: %d\n", GetLastError());
562 return E_FAIL;
563 }
564
565 PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
566 if (func)
567 {
568 hResult = func(IID_PPV_ARG(IShellMenu, menuBar));
569 }
570 else
571 {
572 DbgPrint("Failed: %d\n", GetLastError());
573 hResult = E_FAIL;
574 }
575
576 if (FAILED(hResult))
577 {
578 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
579 IID_PPV_ARG(IShellMenu, menuBar));
580 }
581 #else
582 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
583 IID_PPV_ARG(IShellMenu, menuBar));
584 #endif
585 if (FAILED(hResult))
586 return hResult;
587 hResult = fMenuCallback.QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
588 if (FAILED(hResult))
589 return hResult;
590 hResult = (*menuBar)->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
591 if (FAILED(hResult))
592 return hResult;
593 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
594 if (FAILED(hResult))
595 return hResult;
596 hResult = oleWindow->GetWindow(&ownerWindow);
597 if (FAILED(hResult))
598 return hResult;
599 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &siteCommandTarget));
600 if (FAILED(hResult))
601 return hResult;
602 hResult = siteCommandTarget->Exec(&CGID_Explorer, 0x35, 0, NULL, &menuOut);
603 if (FAILED(hResult))
604 return hResult;
605 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
606 return E_FAIL;
607 hResult = (*menuBar)->SetMenu((HMENU)V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
608 if (FAILED(hResult))
609 return hResult;
610 hResult = (*menuBar)->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
611 if (FAILED(hResult))
612 return hResult;
613 hResult = commandTarget->Exec(&CGID_MenuBand, 3, 1, NULL, NULL);
614 if (FAILED(hResult))
615 return hResult;
616 return S_OK;
617 }
618
619 HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
620 {
621 CComPtr<IUnknown> tempBand;
622 HRESULT hResult;
623
624 #if 1
625 hResult = ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
626 #else
627 hResult = CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
628 #endif
629 if (FAILED(hResult))
630 return hResult;
631 return S_OK;
632 }
633
634 HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
635 {
636 HRESULT hResult;
637
638 hResult = ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
639 if (FAILED(hResult))
640 return hResult;
641 return S_OK;
642 }
643
644 HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
645 {
646 CComPtr<IAddressBand> addressBand;
647 HRESULT hResult;
648
649 #if 1
650 hResult = ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
651 #else
652 hResult = CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
653 #endif
654 if (FAILED(hResult))
655 return hResult;
656 hResult = (*toolsBar)->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
657 return S_OK;
658 }
659
660 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
661 {
662 REBARBANDINFOW rebarBandInfo;
663 int bandCount;
664 CDockSite *dockSite;
665 HRESULT hResult;
666
667 if (locked != fLocked)
668 {
669 fLocked = locked;
670 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
671 rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
672 bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
673 for (INT x = 0; x < bandCount; x++)
674 {
675 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
676 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
677 if (dockSite != NULL)
678 {
679 rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
680 if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || fLocked)
681 rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
682 if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !fLocked)
683 rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
684 SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
685 }
686 }
687 hResult = ReserveBorderSpace();
688 }
689 return S_OK;
690 }
691
692 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
693 {
694 HRESULT hResult;
695
696 hResult = S_OK;
697 switch (commandID)
698 {
699 case -1:
700 // loop through buttons
701 //for buttons in CLSID_CommonButtons
702 // if up, QueryStatus for up state and update it
703 //
704 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
705 break;
706 case 1:
707 // forward
708 hResult = SetState(&CLSID_CommonButtons, gForwardCommandID, newValue ? TBSTATE_ENABLED : 0);
709 break;
710 case 2:
711 // back
712 hResult = SetState(&CLSID_CommonButtons, gBackCommandID, newValue ? TBSTATE_ENABLED : 0);
713 break;
714 }
715 return hResult;
716 }
717
718 HRESULT CInternetToolbar::CreateAndInitBandProxy()
719 {
720 CComPtr<IServiceProvider> serviceProvider;
721 HRESULT hResult;
722
723 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
724 if (FAILED(hResult))
725 return hResult;
726 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
727 if (FAILED(hResult))
728 {
729 hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
730 if (FAILED(hResult))
731 return hResult;
732 hResult = fBandProxy->SetSite(fSite);
733 if (FAILED(hResult))
734 return hResult;
735 }
736 return S_OK;
737 }
738
739 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
740 {
741 return E_NOTIMPL;
742 }
743
744 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
745 {
746 return E_NOTIMPL;
747 }
748
749 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
750 {
751 return E_NOTIMPL;
752 }
753
754 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
755 {
756 if (lphwnd == NULL)
757 return E_POINTER;
758 *lphwnd = m_hWnd;
759 return S_OK;
760 }
761
762 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
763 {
764 return E_NOTIMPL;
765 }
766
767 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
768 {
769 CComPtr<IDockingWindow> dockingWindow;
770 HRESULT hResult;
771
772 // show the bar here
773 hResult = ReserveBorderSpace();
774 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow));
775 hResult = dockingWindow->ShowDW(fShow);
776 return S_OK;
777 }
778
779 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
780 {
781 return E_NOTIMPL;
782 }
783
784 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
785 IUnknown *punkToolbarSite, BOOL fReserved)
786 {
787 return E_NOTIMPL;
788 }
789
790 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
791 {
792 if (pClassID == NULL)
793 return E_POINTER;
794 *pClassID = CLSID_InternetToolbar;
795 return S_OK;
796 }
797
798 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
799 {
800 return E_NOTIMPL;
801 }
802
803 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
804 {
805 return E_NOTIMPL;
806 }
807
808 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
809 {
810 return E_NOTIMPL;
811 }
812
813 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
814 {
815 return E_NOTIMPL;
816 }
817
818 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
819 {
820 CComPtr<IShellMenu> menuBar;
821 CComPtr<IUnknown> logoBar;
822 CComPtr<IUnknown> toolsBar;
823 CComPtr<IUnknown> navigationBar;
824 CComPtr<IOleWindow> menuOleWindow;
825 CComPtr<IOleWindow> toolbarOleWindow;
826 CComPtr<IOleWindow> navigationOleWindow;
827 HRESULT hResult;
828
829 /* Create and attach the menubar to the rebar */
830 hResult = CreateMenuBar(&menuBar);
831 if (FAILED(hResult))
832 return hResult;
833 AddDockItem(menuBar, ITBBID_MENUBAND,
834 CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
835
836 hResult = menuBar->QueryInterface(IID_PPV_ARG(IOleWindow, &menuOleWindow));
837 hResult = menuOleWindow->GetWindow(&fMenuBandWindow);
838 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
839
840 /* Create and attach the brand/logo to the rebar */
841 hResult = CreateBrandBand(&logoBar);
842 if (FAILED(hResult))
843 return hResult;
844 AddDockItem(logoBar, ITBBID_BRANDBAND,
845 CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
846 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
847
848 /* Create and attach the standard toolbar to the rebar */
849 hResult = CreateToolsBar(&toolsBar);
850 if (FAILED(hResult))
851 return hResult;
852 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
853 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
854 hResult = fControlsBar->QueryInterface(IID_PPV_ARG(IOleWindow, &toolbarOleWindow));
855 if (FAILED(hResult))
856 return hResult;
857 hResult = toolbarOleWindow->GetWindow(&fToolbarWindow);
858 if (FAILED(hResult))
859 return hResult;
860
861 /* Create and attach the address/navigation toolbar to the rebar */
862 hResult = CreateAddressBand(&navigationBar);
863 if (FAILED(hResult))
864 return hResult;
865 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
866 hResult = navigationBar->QueryInterface(IID_PPV_ARG(IOleWindow, &navigationOleWindow));
867 hResult = navigationOleWindow->GetWindow(&fNavigationWindow);
868 fNavigationBar.Attach(navigationBar.Detach());
869
870 return S_OK;
871 }
872
873 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
874 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
875 {
876 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
877 {
878 while (cCmds != 0)
879 {
880 switch (prgCmds->cmdID)
881 {
882 case ITID_TEXTLABELS: // Text Labels state
883 prgCmds->cmdf = OLECMDF_SUPPORTED;
884 break;
885 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
886 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
887 break;
888 case ITID_ADDRESSBANDSHOWN: // address bar visibility
889 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
890 break;
891 case ITID_LINKSBANDSHOWN: // links bar visibility
892 prgCmds->cmdf = 0;
893 break;
894 case ITID_MENUBANDSHOWN: // Menubar band visibility
895 prgCmds->cmdf = 0;
896 break;
897 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
898 prgCmds->cmdf = 0;
899 break;
900 case ITID_CUSTOMIZEENABLED: // customize enabled
901 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
902 break;
903 case ITID_TOOLBARLOCKED: // lock toolbars
904 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
905 if (fLocked)
906 prgCmds->cmdf |= OLECMDF_LATCHED;
907 break;
908 default:
909 prgCmds->cmdf = 0;
910 break;
911 }
912 prgCmds++;
913 cCmds--;
914 }
915 return S_OK;
916 }
917 return E_FAIL;
918 }
919
920 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
921 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
922 {
923 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
924 {
925 switch (nCmdID)
926 {
927 case 1:
928 // what do I do here?
929 return S_OK;
930 case ITID_TEXTLABELS:
931 // toggle text labels
932 return S_OK;
933 case ITID_TOOLBARBANDSHOWN:
934 // toggle toolbar band visibility
935 return S_OK;
936 case ITID_ADDRESSBANDSHOWN:
937 // toggle address band visibility
938 return S_OK;
939 case ITID_LINKSBANDSHOWN:
940 // toggle links band visibility
941 return S_OK;
942 case ITID_CUSTOMIZEENABLED:
943 // run customize
944 return S_OK;
945 case ITID_TOOLBARLOCKED:
946 return LockUnlockToolbars(!fLocked);
947 }
948 }
949 return E_FAIL;
950 }
951
952 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
953 {
954 return E_NOTIMPL;
955 }
956
957 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
958 {
959 return E_NOTIMPL;
960 }
961
962 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
963 LCID lcid, DISPID *rgDispId)
964 {
965 return E_NOTIMPL;
966 }
967
968 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
969 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
970 {
971 HRESULT hResult;
972
973 switch(dispIdMember)
974 {
975 case DISPID_BEFORENAVIGATE:
976 hResult = S_OK;
977 break;
978 case DISPID_DOWNLOADCOMPLETE:
979 hResult = S_OK;
980 break;
981 case DISPID_COMMANDSTATECHANGE:
982 if (pDispParams->cArgs != 2)
983 return E_INVALIDARG;
984 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
985 return E_INVALIDARG;
986 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
987 V_I4(&pDispParams->rgvarg[1]));
988 case DISPID_DOWNLOADBEGIN:
989 hResult = S_OK;
990 break;
991 case DISPID_NAVIGATECOMPLETE2:
992 hResult = S_OK;
993 break;
994 case DISPID_DOCUMENTCOMPLETE:
995 hResult = S_OK;
996 break;
997 }
998 return S_OK;
999 }
1000
1001 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1002 {
1003 HRESULT hResult;
1004
1005 fCommandTarget.Release();
1006 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1007 if (FAILED(hResult))
1008 return hResult;
1009 fCommandCategory = *category;
1010 return S_OK;
1011 }
1012
1013 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1014 {
1015 return E_NOTIMPL;
1016 }
1017
1018 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1019 {
1020 return E_NOTIMPL;
1021 }
1022
1023 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1024 HINSTANCE param10, LPCTSTR param14, long *param18)
1025 {
1026 long result;
1027
1028 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1029 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1030 *param18 = result;
1031 if (result == -1)
1032 return E_FAIL;
1033 return S_OK;
1034 }
1035
1036 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1037 {
1038 return E_NOTIMPL;
1039 }
1040
1041 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1042 {
1043 if (theState == NULL)
1044 return E_POINTER;
1045 // map the command id
1046 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1047 return S_OK;
1048 }
1049
1050 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1051 {
1052 // map the command id
1053 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1054 return S_OK;
1055 }
1056
1057 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1058 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1059 {
1060 return E_NOTIMPL;
1061 }
1062
1063 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1064 {
1065 if (paramC == NULL)
1066 return E_POINTER;
1067 *paramC = MAKELONG(24, 24);
1068 return S_OK;
1069 }
1070
1071 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1072 WPARAM wParam, LPARAM lParam, LRESULT *result)
1073 {
1074 return E_NOTIMPL;
1075 }
1076
1077 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1078 HIMAGELIST param14, HIMAGELIST param18)
1079 {
1080 return E_NOTIMPL;
1081 }
1082
1083 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1084 {
1085 return E_NOTIMPL;
1086 }
1087
1088 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1089 {
1090 return E_NOTIMPL;
1091 }
1092
1093 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1094 {
1095 CComPtr<IBrowserService> browserService;
1096 CComPtr<IServiceProvider> serviceProvider;
1097 CComPtr<IOleWindow> oleWindow;
1098 HWND ownerWindow;
1099 HWND dockContainer;
1100 HRESULT hResult;
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 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
1131 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
1132 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
1133 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
1134 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
1135 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1136 if (fMainReBar == NULL)
1137 return E_FAIL;
1138
1139 // take advice to watch events
1140 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1141 hResult = serviceProvider->QueryService(
1142 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1143 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
1144 }
1145 return S_OK;
1146 }
1147
1148 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1149 {
1150 if (ppvSite == NULL)
1151 return E_POINTER;
1152 if (fSite.p != NULL)
1153 return fSite->QueryInterface(riid, ppvSite);
1154 *ppvSite = NULL;
1155 return S_OK;
1156 }
1157
1158 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1159 {
1160 CComPtr<IServiceProvider> serviceProvider;
1161 HRESULT hResult;
1162
1163 if (IsEqualIID(guidService, IID_IBandSite))
1164 return this->QueryInterface(riid, ppvObject);
1165 if (IsEqualIID(guidService, SID_IBandProxy))
1166 {
1167 if (fBandProxy.p == NULL)
1168 {
1169 hResult = CreateAndInitBandProxy();
1170 if (FAILED(hResult))
1171 return hResult;
1172 }
1173 return fBandProxy->QueryInterface(riid, ppvObject);
1174 }
1175 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1176 }
1177
1178 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1179 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1180 {
1181 CComPtr<IWinEventHandler> menuWinEventHandler;
1182 HRESULT hResult;
1183
1184 if (fMenuBar)
1185 {
1186 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1187 if (menuWinEventHandler->IsWindowOwner(hWnd))
1188 {
1189 return menuWinEventHandler->OnWinEvent(fMenuBandWindow, uMsg, wParam, lParam, theResult);
1190 }
1191 }
1192
1193 return S_FALSE;
1194 }
1195
1196 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1197 {
1198 return E_NOTIMPL;
1199 }
1200
1201 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1202 {
1203 return E_NOTIMPL;
1204 }
1205
1206 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1207 {
1208 return E_NOTIMPL;
1209 }
1210
1211 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1212 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1213 {
1214 if (ppstb == NULL)
1215 return E_POINTER;
1216 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
1217 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1218 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1219 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1220 *ppstb = NULL;
1221 return E_FAIL;
1222 }
1223
1224 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1225 {
1226 return E_NOTIMPL;
1227 }
1228
1229 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1230 {
1231 return E_NOTIMPL;
1232 }
1233
1234 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1235 {
1236 return E_NOTIMPL;
1237 }
1238
1239 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1240 {
1241 return E_NOTIMPL;
1242 }
1243
1244 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1245 {
1246 return E_NOTIMPL;
1247 }
1248
1249 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1250 {
1251 CComPtr<IServiceProvider> serviceProvider;
1252 CComPtr<IWebBrowser> webBrowser;
1253 HRESULT hResult;
1254
1255 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1256 if (FAILED(hResult))
1257 return 0;
1258 hResult = serviceProvider->QueryService(SID_SShellBrowser,
1259 IID_PPV_ARG(IWebBrowser, &webBrowser));
1260 if (FAILED(hResult))
1261 return 0;
1262 hResult = webBrowser->GoBack();
1263 return 1;
1264 }
1265
1266 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1267 {
1268 CComPtr<IServiceProvider> serviceProvider;
1269 CComPtr<IWebBrowser> webBrowser;
1270 HRESULT hResult;
1271
1272 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1273 if (FAILED(hResult))
1274 return 0;
1275 hResult = serviceProvider->QueryService(
1276 SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1277 if (FAILED(hResult))
1278 return 0;
1279 hResult = webBrowser->GoForward();
1280 return 1;
1281 }
1282
1283 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1284 {
1285 CComPtr<IOleCommandTarget> oleCommandTarget;
1286 HRESULT hResult;
1287
1288 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1289 if (FAILED(hResult))
1290 return hResult;
1291 hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1292 return 1;
1293 }
1294
1295 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1296 {
1297 CComPtr<IObjectWithSite> objectWithSite;
1298 CComPtr<IContextMenu> contextMenu;
1299 CMINVOKECOMMANDINFO commandInfo;
1300 const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1301 HRESULT hResult;
1302
1303 // TODO: Query shell if this command is enabled first
1304
1305 memset(&commandInfo, 0, sizeof(commandInfo));
1306 commandInfo.cbSize = sizeof(commandInfo);
1307 commandInfo.hwnd = m_hWnd;
1308 commandInfo.lpParameters = searchGUID;
1309 commandInfo.nShow = SW_SHOWNORMAL;
1310
1311 hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1312 IID_PPV_ARG(IContextMenu, &contextMenu));
1313 if (FAILED(hResult))
1314 return 0;
1315 hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1316 if (FAILED(hResult))
1317 return 0;
1318 hResult = objectWithSite->SetSite(fSite);
1319 if (FAILED(hResult))
1320 return 0;
1321 hResult = contextMenu->InvokeCommand(&commandInfo);
1322 hResult = objectWithSite->SetSite(NULL);
1323 return 0;
1324 }
1325
1326 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1327 {
1328 CComPtr<IOleCommandTarget> oleCommandTarget;
1329 HRESULT hResult;
1330
1331 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1332 if (FAILED(hResult))
1333 return hResult;
1334 hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
1335 return 1;
1336 }
1337
1338 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1339 {
1340 HRESULT hResult;
1341
1342 if (fCommandTarget.p != NULL)
1343 {
1344 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1345 }
1346 return 1;
1347 }
1348
1349 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1350 {
1351 CComPtr<IServiceProvider> serviceProvider;
1352 CComPtr<IBrowserService> browserService;
1353 CComPtr<IOleCommandTarget> commandTarget;
1354 CComPtr<ITravelLog> travelLog;
1355 NMTOOLBARW *notifyInfo;
1356 RECT bounds;
1357 HMENU newMenu;
1358 TPMPARAMS params;
1359 int selectedItem;
1360 VARIANT parmIn;
1361 OLECMD commandInfo;
1362 HRESULT hResult;
1363
1364 notifyInfo = (NMTOOLBARW *)pNMHDR;
1365 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1366 {
1367 // not from the toolbar, keep looking for a message handler
1368 bHandled = FALSE;
1369 return 0;
1370 }
1371 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1372 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1373 switch (notifyInfo->iItem)
1374 {
1375 case gBackCommandID:
1376 newMenu = CreatePopupMenu();
1377 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1378 hResult = serviceProvider->QueryService(
1379 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1380 hResult = browserService->GetTravelLog(&travelLog);
1381 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1382 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1383 commandInfo.cmdID = 0x1d;
1384 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1385 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1386 travelLog->CountEntries(browserService) > 1)
1387 {
1388 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1389 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1390 }
1391 params.cbSize = sizeof (params);
1392 params.rcExclude = bounds;
1393 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1394 bounds.left, bounds.bottom, m_hWnd, &params);
1395 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1396 {
1397 V_VT(&parmIn) = VT_I4;
1398 V_I4(&parmIn) = 1;
1399 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1400 }
1401 else if (selectedItem != 0)
1402 hResult = travelLog->Travel(browserService, -selectedItem);
1403 DestroyMenu(newMenu);
1404 break;
1405 case gForwardCommandID:
1406 newMenu = CreatePopupMenu();
1407 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1408 hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1409 hResult = browserService->GetTravelLog(&travelLog);
1410 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1411 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1412 commandInfo.cmdID = 0x1d;
1413 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1414 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1415 travelLog->CountEntries(browserService) > 1)
1416 {
1417 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1418 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1419 }
1420 params.cbSize = sizeof (params);
1421 params.rcExclude = bounds;
1422 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1423 bounds.left, bounds.bottom, m_hWnd, &params);
1424 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1425 {
1426 V_VT(&parmIn) = VT_I4;
1427 V_I4(&parmIn) = 1;
1428 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1429 }
1430 else if (selectedItem != 0)
1431 hResult = travelLog->Travel(browserService, -selectedItem);
1432 DestroyMenu(newMenu);
1433 break;
1434 case gViewsCommandID:
1435 VARIANT inValue;
1436 CComVariant outValue;
1437 HRESULT hResult;
1438
1439 V_VT(&inValue) = VT_INT_PTR;
1440 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1441
1442 if (fCommandTarget.p != NULL)
1443 hResult = fCommandTarget->Exec(&fCommandCategory, 0x7031, 1, &inValue, &outValue);
1444 // pvaOut is VT_I4 with value 0x403
1445 break;
1446 }
1447 return TBDDRET_DEFAULT;
1448 }
1449
1450 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1451 {
1452 return 1;
1453 }
1454
1455 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1456 {
1457 return 1;
1458 }
1459
1460 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1461 {
1462 HMENU contextMenuBar;
1463 HMENU contextMenu;
1464 POINT clickLocation;
1465 int command;
1466 RBHITTESTINFO hitTestInfo;
1467 REBARBANDINFOW rebarBandInfo;
1468 int bandID;
1469
1470 clickLocation.x = LOWORD(lParam);
1471 clickLocation.y = HIWORD(lParam);
1472 hitTestInfo.pt = clickLocation;
1473 ScreenToClient(&hitTestInfo.pt);
1474 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1475 if (hitTestInfo.iBand == -1)
1476 return 0;
1477 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1478 rebarBandInfo.fMask = RBBIM_ID;
1479 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1480 bandID = rebarBandInfo.wID;
1481 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1482 contextMenu = GetSubMenu(contextMenuBar, 0);
1483 switch (bandID)
1484 {
1485 case ITBBID_MENUBAND: // menu band
1486 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1487 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1488 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1489 break;
1490 case ITBBID_BRANDBAND: // brand band
1491 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1492 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1493 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1494 break;
1495 case ITBBID_TOOLSBAND: // tools band
1496 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1497 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1498 break;
1499 case ITBBID_ADDRESSBAND: // navigation band
1500 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1501 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1502 break;
1503 default:
1504 break;
1505 }
1506 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1507 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1508 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1509 switch (command)
1510 {
1511 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1512 break;
1513 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1514 break;
1515 case IDM_TOOLBARS_LINKSBAR: // links
1516 break;
1517 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1518 LockUnlockToolbars(!fLocked);
1519 break;
1520 case IDM_TOOLBARS_CUSTOMIZE: // customize
1521 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1522 break;
1523 }
1524 return 1;
1525 }
1526
1527 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1528 {
1529 if (wParam != SIZE_MINIMIZED)
1530 {
1531 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1532 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1533 }
1534 return 1;
1535 }
1536
1537 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1538 {
1539 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1540 {
1541 bHandled = FALSE;
1542 return 0;
1543 }
1544 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1545 return 1;
1546 }
1547
1548 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1549 {
1550 CComPtr<IBrowserService> browserService;
1551 CComPtr<ITravelLog> travelLog;
1552 TOOLTIPTEXTW *pTTTW;
1553 UINT nID;
1554 wchar_t tempString[300];
1555 HRESULT hResult;
1556
1557 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1558 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1559 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1560 else
1561 nID = (UINT)pNMHDR->idFrom;
1562
1563 if (nID != 0)
1564 {
1565 if (nID == (UINT)gBackCommandID || nID == (UINT)gForwardCommandID)
1566 {
1567 // TODO: Should this call QueryService?
1568 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1569 hResult = browserService->GetTravelLog(&travelLog);
1570 hResult = travelLog->GetToolTipText(browserService,
1571 (nID == (UINT)gBackCommandID) ? TLOG_BACK : TLOG_FORE,
1572 0, tempString, 299);
1573 if (FAILED(hResult))
1574 {
1575 bHandled = FALSE;
1576 return 0;
1577 }
1578 }
1579 else
1580 tempString[0] = 0;
1581 wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
1582 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1583 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1584 return 0;
1585 }
1586 return 0;
1587 }
1588
1589 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1590 {
1591 LRESULT theResult;
1592 HRESULT hResult;
1593 HWND target = (HWND) lParam;
1594
1595 if (fMenuBar)
1596 {
1597 CComPtr<IWinEventHandler> menuWinEventHandler;
1598 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1599 if (SUCCEEDED(hResult))
1600 {
1601 if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
1602 {
1603 hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
1604 return FAILED(hResult) ? 0 : theResult;
1605 }
1606 }
1607 }
1608
1609 if (fNavigationBar)
1610 {
1611 CComPtr<IWinEventHandler> menuWinEventHandler;
1612 hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1613 if (SUCCEEDED(hResult))
1614 {
1615 if (menuWinEventHandler->IsWindowOwner(target) == S_OK)
1616 {
1617 hResult = menuWinEventHandler->OnWinEvent(target, uMsg, wParam, lParam, &theResult);
1618 return FAILED(hResult) ? 0 : theResult;
1619 }
1620 }
1621 }
1622
1623 return 0;
1624 }
1625 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1626 {
1627 NMHDR *notifyHeader;
1628 LRESULT theResult;
1629 HRESULT hResult;
1630
1631 notifyHeader = (NMHDR *) lParam;
1632
1633 if (fMenuBar)
1634 {
1635 CComPtr<IWinEventHandler> menuWinEventHandler;
1636 hResult = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1637 if (SUCCEEDED(hResult))
1638 {
1639 if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
1640 {
1641 hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1642 return FAILED(hResult) ? 0 : theResult;
1643 }
1644 }
1645 }
1646
1647 if (fNavigationBar)
1648 {
1649 CComPtr<IWinEventHandler> menuWinEventHandler;
1650 hResult = fNavigationBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler));
1651 if (SUCCEEDED(hResult))
1652 {
1653 if (menuWinEventHandler->IsWindowOwner(notifyHeader->hwndFrom) == S_OK)
1654 {
1655 hResult = menuWinEventHandler->OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1656 return FAILED(hResult) ? 0 : theResult;
1657 }
1658 }
1659 }
1660
1661 return 0;
1662 }
1663
1664 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1665 {
1666 CComObject<CInternetToolbar> *theToolbar;
1667 HRESULT hResult;
1668
1669 if (ppv == NULL)
1670 return E_POINTER;
1671 *ppv = NULL;
1672 ATLTRY (theToolbar = new CComObject<CInternetToolbar>);
1673 if (theToolbar == NULL)
1674 return E_OUTOFMEMORY;
1675 hResult = theToolbar->QueryInterface (riid, reinterpret_cast<void **>(ppv));
1676 if (FAILED(hResult))
1677 {
1678 delete theToolbar;
1679 return hResult;
1680 }
1681 return S_OK;
1682 }