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