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