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