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