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