365e74e598fa49384e1181759532a2f65f7be3a5
[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.AddRef();
551 fToolbarWindow = NULL;
552 fAdviseCookie = 0;
553 }
554
555 CInternetToolbar::~CInternetToolbar()
556 {
557 fMenuCallback.Release();
558 }
559
560 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags)
561 {
562 CComPtr<CDockSite> newSite;
563
564 newSite = new CComObject<CDockSite>;
565 newSite->Initialize(newItem, this, fMainReBar, bandID, flags);
566 }
567
568 HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight)
569 {
570 CComPtr<IDockingWindowSite> dockingWindowSite;
571 RECT availableBorderSpace;
572
573 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
574 if (FAILED_UNEXPECTEDLY(hResult))
575 return hResult;
576 hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace);
577 if (FAILED_UNEXPECTEDLY(hResult))
578 return hResult;
579
580 if (availableBorderSpace.top > maxHeight)
581 {
582 availableBorderSpace.top = maxHeight;
583 }
584
585 return ResizeBorderDW(&availableBorderSpace, fSite, FALSE);
586 }
587
588 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **menuBar)
589 {
590 CComPtr<IOleCommandTarget> siteCommandTarget;
591 CComPtr<IOleWindow> oleWindow;
592 CComPtr<IOleCommandTarget> commandTarget;
593 CComPtr<IShellMenuCallback> callback;
594 VARIANT menuOut;
595 HWND ownerWindow;
596 HRESULT hResult;
597
598 #if USE_CUSTOM_MENUBAND
599 HMODULE hrs = LoadLibraryW(L"rshell.dll");
600
601 if (!hrs)
602 {
603 DbgPrint("Failed: %d\n", GetLastError());
604 return E_FAIL;
605 }
606
607 PMENUBAND_CONSTRUCTOR func = (PMENUBAND_CONSTRUCTOR) GetProcAddress(hrs, "CMenuBand_Constructor");
608 if (func)
609 {
610 hResult = func(IID_PPV_ARG(IShellMenu, menuBar));
611 }
612 else
613 {
614 DbgPrint("Failed: %d\n", GetLastError());
615 hResult = E_FAIL;
616 }
617
618 if (FAILED_UNEXPECTEDLY(hResult))
619 {
620 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
621 IID_PPV_ARG(IShellMenu, menuBar));
622 }
623 #else
624 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
625 IID_PPV_ARG(IShellMenu, menuBar));
626 #endif
627 if (FAILED_UNEXPECTEDLY(hResult))
628 return hResult;
629 hResult = fMenuCallback.QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback));
630 if (FAILED_UNEXPECTEDLY(hResult))
631 return hResult;
632 hResult = (*menuBar)->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL);
633 if (FAILED_UNEXPECTEDLY(hResult))
634 return hResult;
635 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
636 if (FAILED_UNEXPECTEDLY(hResult))
637 return hResult;
638 hResult = oleWindow->GetWindow(&ownerWindow);
639 if (FAILED_UNEXPECTEDLY(hResult))
640 return hResult;
641 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &siteCommandTarget));
642 if (FAILED_UNEXPECTEDLY(hResult))
643 return hResult;
644 hResult = siteCommandTarget->Exec(&CGID_Explorer, 0x35, 0, NULL, &menuOut);
645 if (FAILED_UNEXPECTEDLY(hResult))
646 return hResult;
647 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL)
648 return E_FAIL;
649 hResult = (*menuBar)->SetMenu((HMENU)V_INTREF(&menuOut), ownerWindow, SMSET_DONTOWN);
650 if (FAILED_UNEXPECTEDLY(hResult))
651 return hResult;
652 hResult = IUnknown_Exec(*menuBar, CGID_MenuBand, 3, 1, NULL, NULL);
653 if (FAILED_UNEXPECTEDLY(hResult))
654 return hResult;
655 return S_OK;
656 }
657
658 HRESULT CInternetToolbar::CreateBrandBand(IUnknown **logoBar)
659 {
660 #if 1
661 return ::CreateBrandBand(IID_PPV_ARG(IUnknown, logoBar));
662 #else
663 return CoCreateInstance(CLSID_BrandBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, logoBar));
664 #endif
665 }
666
667 HRESULT CInternetToolbar::CreateToolsBar(IUnknown **toolsBar)
668 {
669 return ::CreateToolsBar(IID_PPV_ARG(IUnknown, toolsBar));
670 }
671
672 HRESULT CInternetToolbar::CreateAddressBand(IUnknown **toolsBar)
673 {
674 #if 1
675 return ::CreateAddressBand(IID_PPV_ARG(IUnknown, toolsBar));
676 #else
677 return CoCreateInstance(CLSID_SH_AddressBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, toolsBar));
678 #endif
679 }
680
681 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
682 {
683 REBARBANDINFOW rebarBandInfo;
684 int bandCount;
685 CDockSite *dockSite;
686 HRESULT hResult;
687
688 if (locked != fLocked)
689 {
690 fLocked = locked;
691 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
692 rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
693 bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
694 for (INT x = 0; x < bandCount; x++)
695 {
696 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
697 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
698 if (dockSite != NULL)
699 {
700 rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
701 if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || fLocked)
702 rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
703 if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !fLocked)
704 rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
705 SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
706 }
707 }
708 hResult = ReserveBorderSpace();
709
710 // TODO: refresh view menu?
711 }
712 return S_OK;
713 }
714
715 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID)
716 {
717 HRESULT hResult;
718
719 hResult = S_OK;
720 switch (commandID)
721 {
722 case -1:
723 // loop through buttons
724 //for buttons in CLSID_CommonButtons
725 // if up, QueryStatus for up state and update it
726 //
727 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget
728 break;
729 case 1:
730 // forward
731 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0);
732 break;
733 case 2:
734 // back
735 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0);
736 break;
737 }
738 return hResult;
739 }
740
741 HRESULT CInternetToolbar::CreateAndInitBandProxy()
742 {
743 CComPtr<IServiceProvider> serviceProvider;
744 HRESULT hResult;
745
746 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
747 if (FAILED_UNEXPECTEDLY(hResult))
748 return hResult;
749 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy));
750 if (FAILED_UNEXPECTEDLY(hResult))
751 {
752 hResult = CreateBandProxy(IID_PPV_ARG(IBandProxy, &fBandProxy));
753 if (FAILED_UNEXPECTEDLY(hResult))
754 return hResult;
755 hResult = fBandProxy->SetSite(fSite);
756 if (FAILED_UNEXPECTEDLY(hResult))
757 return hResult;
758 }
759 return S_OK;
760 }
761
762 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
763 {
764 return E_NOTIMPL;
765 }
766
767 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO()
768 {
769 HRESULT hr = S_FALSE;
770
771 if (fMenuBar)
772 hr = IUnknown_HasFocusIO(fMenuBar);
773 if (hr != S_FALSE)
774 return hr;
775
776 if (fControlsBar)
777 hr = IUnknown_HasFocusIO(fControlsBar);
778 if (hr != S_FALSE)
779 return hr;
780
781 if (fNavigationBar)
782 hr = IUnknown_HasFocusIO(fNavigationBar);
783 if (hr != S_FALSE)
784 return hr;
785
786 return S_FALSE;
787 }
788
789 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg)
790 {
791 HRESULT hr = S_FALSE;
792
793 if (fMenuBar)
794 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg);
795 if (hr == S_OK)
796 return hr;
797
798 if (fControlsBar)
799 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg);
800 if (hr == S_OK)
801 return hr;
802
803 if (fNavigationBar)
804 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg);
805 if (hr == S_OK)
806 return hr;
807
808 return S_FALSE;
809 }
810
811 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd)
812 {
813 if (lphwnd == NULL)
814 return E_POINTER;
815 *lphwnd = m_hWnd;
816 return S_OK;
817 }
818
819 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode)
820 {
821 return E_NOTIMPL;
822 }
823
824 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
825 {
826 HRESULT hResult;
827
828 // show the bar here
829 if (fShow)
830 {
831 hResult = ReserveBorderSpace();
832 if (FAILED_UNEXPECTEDLY(hResult))
833 return hResult;
834 }
835
836 if (fMenuBar)
837 {
838 hResult = IUnknown_ShowDW(fMenuBar, fShow);
839 if (FAILED_UNEXPECTEDLY(hResult))
840 return hResult;
841 }
842
843 if (fControlsBar)
844 {
845 hResult = IUnknown_ShowDW(fControlsBar, fShow);
846 if (FAILED_UNEXPECTEDLY(hResult))
847 return hResult;
848 }
849 if (fNavigationBar)
850 {
851 hResult = IUnknown_ShowDW(fNavigationBar, fShow);
852 if (FAILED_UNEXPECTEDLY(hResult))
853 return hResult;
854 }
855 if (fLogoBar)
856 {
857 hResult = IUnknown_ShowDW(fLogoBar, fShow);
858 if (FAILED_UNEXPECTEDLY(hResult))
859 return hResult;
860 }
861 return S_OK;
862 }
863
864 template<class T>
865 void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
866 {
867 if (cptr.p != NULL)
868 {
869 int nrc = cptr->Release();
870 if (nrc > 0)
871 {
872 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc);
873 if (forceRelease)
874 {
875 while (nrc > 0)
876 {
877 nrc = cptr->Release();
878 }
879 }
880 }
881 cptr.Detach();
882 }
883 }
884
885 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved)
886 {
887 HRESULT hResult;
888
889 if (fMenuBar)
890 {
891 hResult = IUnknown_CloseDW(fMenuBar, dwReserved);
892 if (FAILED_UNEXPECTEDLY(hResult))
893 return hResult;
894 ReleaseCComPtrExpectZero(fMenuBar);
895 }
896 if (fControlsBar)
897 {
898 hResult = IUnknown_CloseDW(fControlsBar, dwReserved);
899 if (FAILED_UNEXPECTEDLY(hResult))
900 return hResult;
901 ReleaseCComPtrExpectZero(fControlsBar);
902 }
903 if (fNavigationBar)
904 {
905 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved);
906 if (FAILED_UNEXPECTEDLY(hResult))
907 return hResult;
908 ReleaseCComPtrExpectZero(fNavigationBar);
909 }
910 if (fLogoBar)
911 {
912 hResult = IUnknown_CloseDW(fLogoBar, dwReserved);
913 if (FAILED_UNEXPECTEDLY(hResult))
914 return hResult;
915 ReleaseCComPtrExpectZero(fLogoBar);
916 }
917 return S_OK;
918 }
919
920 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
921 IUnknown *punkToolbarSite, BOOL fReserved)
922 {
923 RECT neededBorderSpace;
924 RECT availableBorderSpace = *prcBorder;
925
926 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace));
927
928 // RBSTR_CHANGERECT does not seem to set the proper size in the rect.
929 // Let's make sure we fetch the actual size properly.
930 GetWindowRect(fMainReBar, &availableBorderSpace);
931 neededBorderSpace.left = 0;
932 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
933 if (!fLocked)
934 neededBorderSpace.top += 3;
935 neededBorderSpace.right = 0;
936 neededBorderSpace.bottom = 0;
937
938 CComPtr<IDockingWindowSite> dockingWindowSite;
939
940 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite));
941 if (FAILED_UNEXPECTEDLY(hResult))
942 return hResult;
943
944 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
945 if (FAILED_UNEXPECTEDLY(hResult))
946 return hResult;
947
948 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace);
949 if (FAILED_UNEXPECTEDLY(hResult))
950 return hResult;
951
952 return S_OK;
953 }
954
955 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
956 {
957 if (pClassID == NULL)
958 return E_POINTER;
959 *pClassID = CLSID_InternetToolbar;
960 return S_OK;
961 }
962
963 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
964 {
965 return E_NOTIMPL;
966 }
967
968 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
969 {
970 return E_NOTIMPL;
971 }
972
973 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
974 {
975 return E_NOTIMPL;
976 }
977
978 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
979 {
980 return E_NOTIMPL;
981 }
982
983 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew()
984 {
985 CComPtr<IShellMenu> menuBar;
986 CComPtr<IUnknown> logoBar;
987 CComPtr<IUnknown> toolsBar;
988 CComPtr<IUnknown> navigationBar;
989 HRESULT hResult;
990
991 /* Create and attach the menubar to the rebar */
992 hResult = CreateMenuBar(&menuBar);
993 if (FAILED_UNEXPECTEDLY(hResult))
994 return hResult;
995 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
996
997 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow);
998 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count
999
1000 // FIXME: The ros Rebar does not properly support fixed-size items such as the brandband,
1001 // and it will put them in their own row, sized to take up the whole row.
1002 #if 0
1003 /* Create and attach the brand/logo to the rebar */
1004 hResult = CreateBrandBand(&logoBar);
1005 if (FAILED_UNEXPECTEDLY(hResult))
1006 return hResult;
1007 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE);
1008 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count
1009 #endif
1010
1011 /* Create and attach the standard toolbar to the rebar */
1012 hResult = CreateToolsBar(&toolsBar);
1013 if (FAILED_UNEXPECTEDLY(hResult))
1014 return hResult;
1015 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1016 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count
1017 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow);
1018 if (FAILED_UNEXPECTEDLY(hResult))
1019 return hResult;
1020
1021 /* Create and attach the address/navigation toolbar to the rebar */
1022 hResult = CreateAddressBand(&navigationBar);
1023 if (FAILED_UNEXPECTEDLY(hResult))
1024 return hResult;
1025 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS);
1026 fNavigationBar.Attach(navigationBar.Detach());
1027 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow);
1028
1029 return S_OK;
1030 }
1031
1032 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
1033 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
1034 {
1035 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1036 {
1037 while (cCmds != 0)
1038 {
1039 switch (prgCmds->cmdID)
1040 {
1041 case ITID_TEXTLABELS: // Text Labels state
1042 prgCmds->cmdf = OLECMDF_SUPPORTED;
1043 break;
1044 case ITID_TOOLBARBANDSHOWN: // toolbar visibility
1045 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1046 break;
1047 case ITID_ADDRESSBANDSHOWN: // address bar visibility
1048 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1049 break;
1050 case ITID_LINKSBANDSHOWN: // links bar visibility
1051 prgCmds->cmdf = 0;
1052 break;
1053 case ITID_MENUBANDSHOWN: // Menubar band visibility
1054 prgCmds->cmdf = 0;
1055 break;
1056 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled
1057 prgCmds->cmdf = 0;
1058 break;
1059 case ITID_CUSTOMIZEENABLED: // customize enabled
1060 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1061 break;
1062 case ITID_TOOLBARLOCKED: // lock toolbars
1063 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
1064 if (fLocked)
1065 prgCmds->cmdf |= OLECMDF_LATCHED;
1066 break;
1067 default:
1068 prgCmds->cmdf = 0;
1069 break;
1070 }
1071 prgCmds++;
1072 cCmds--;
1073 }
1074 return S_OK;
1075 }
1076 return E_FAIL;
1077 }
1078
1079 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
1080 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1081 {
1082 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands))
1083 {
1084 switch (nCmdID)
1085 {
1086 case 1:
1087 // what do I do here?
1088 return S_OK;
1089 case ITID_TEXTLABELS:
1090 // toggle text labels
1091 return S_OK;
1092 case ITID_TOOLBARBANDSHOWN:
1093 // toggle toolbar band visibility
1094 return S_OK;
1095 case ITID_ADDRESSBANDSHOWN:
1096 // toggle address band visibility
1097 return S_OK;
1098 case ITID_LINKSBANDSHOWN:
1099 // toggle links band visibility
1100 return S_OK;
1101 case ITID_CUSTOMIZEENABLED:
1102 // run customize
1103 return S_OK;
1104 case ITID_TOOLBARLOCKED:
1105 return LockUnlockToolbars(!fLocked);
1106 }
1107 }
1108 return E_FAIL;
1109 }
1110
1111 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo)
1112 {
1113 return E_NOTIMPL;
1114 }
1115
1116 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1117 {
1118 return E_NOTIMPL;
1119 }
1120
1121 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1122 LCID lcid, DISPID *rgDispId)
1123 {
1124 return E_NOTIMPL;
1125 }
1126
1127 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1128 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1129 {
1130 HRESULT hResult;
1131
1132 switch(dispIdMember)
1133 {
1134 case DISPID_BEFORENAVIGATE:
1135 hResult = S_OK;
1136 break;
1137 case DISPID_DOWNLOADCOMPLETE:
1138 hResult = S_OK;
1139 break;
1140 case DISPID_COMMANDSTATECHANGE:
1141 if (pDispParams->cArgs != 2)
1142 return E_INVALIDARG;
1143 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4)
1144 return E_INVALIDARG;
1145 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE,
1146 V_I4(&pDispParams->rgvarg[1]));
1147 case DISPID_DOWNLOADBEGIN:
1148 hResult = S_OK;
1149 break;
1150 case DISPID_NAVIGATECOMPLETE2:
1151 hResult = S_OK;
1152 break;
1153 case DISPID_DOCUMENTCOMPLETE:
1154 hResult = S_OK;
1155 break;
1156 }
1157 return S_OK;
1158 }
1159
1160 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14)
1161 {
1162 HRESULT hResult;
1163
1164 fCommandTarget.Release();
1165 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget));
1166 if (FAILED_UNEXPECTEDLY(hResult))
1167 return hResult;
1168 fCommandCategory = *category;
1169 return S_OK;
1170 }
1171
1172 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1()
1173 {
1174 return E_NOTIMPL;
1175 }
1176
1177 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons)
1178 {
1179 return E_NOTIMPL;
1180 }
1181
1182 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup,
1183 HINSTANCE param10, LPCTSTR param14, long *param18)
1184 {
1185 long result;
1186
1187 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW,
1188 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14));
1189 *param18 = result;
1190 if (result == -1)
1191 return E_FAIL;
1192 return S_OK;
1193 }
1194
1195 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14)
1196 {
1197 return E_NOTIMPL;
1198 }
1199
1200 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState)
1201 {
1202 if (theState == NULL)
1203 return E_POINTER;
1204 // map the command id
1205 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0);
1206 return S_OK;
1207 }
1208
1209 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState)
1210 {
1211 // map the command id
1212 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0));
1213 return S_OK;
1214 }
1215
1216 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount,
1217 TBADDBITMAP *lParam, long *newIndex, COLORREF param20)
1218 {
1219 return E_NOTIMPL;
1220 }
1221
1222 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC)
1223 {
1224 if (paramC == NULL)
1225 return E_POINTER;
1226 *paramC = MAKELONG(24, 24);
1227 return S_OK;
1228 }
1229
1230 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg,
1231 WPARAM wParam, LPARAM lParam, LRESULT *result)
1232 {
1233 return E_NOTIMPL;
1234 }
1235
1236 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10,
1237 HIMAGELIST param14, HIMAGELIST param18)
1238 {
1239 return E_NOTIMPL;
1240 }
1241
1242 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14)
1243 {
1244 return E_NOTIMPL;
1245 }
1246
1247 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1248 {
1249 return E_NOTIMPL;
1250 }
1251
1252 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
1253 {
1254 CComPtr<IBrowserService> browserService;
1255 CComPtr<IServiceProvider> serviceProvider;
1256 CComPtr<IOleWindow> oleWindow;
1257 HWND ownerWindow;
1258 HWND dockContainer;
1259 HRESULT hResult;
1260
1261 if (pUnkSite == NULL)
1262 {
1263 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
1264 ::DestroyWindow(fMainReBar);
1265 DestroyWindow();
1266 fSite.Release();
1267 }
1268 else
1269 {
1270 // get window handle of owner
1271 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &oleWindow));
1272 if (FAILED_UNEXPECTEDLY(hResult))
1273 return hResult;
1274 hResult = oleWindow->GetWindow(&ownerWindow);
1275 if (FAILED_UNEXPECTEDLY(hResult))
1276 return hResult;
1277 if (ownerWindow == NULL)
1278 return E_FAIL;
1279
1280 // create dock container
1281 fSite = pUnkSite;
1282 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
1283 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0);
1284 if (dockContainer == NULL)
1285 return E_FAIL;
1286 SubclassWindow(dockContainer);
1287
1288 // create rebar in dock container
1289 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
1290 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE |
1291 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP;
1292 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW;
1293 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style,
1294 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1295 if (fMainReBar == NULL)
1296 return E_FAIL;
1297
1298 // take advice to watch events
1299 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1300 hResult = serviceProvider->QueryService(
1301 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1302 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
1303 }
1304 return S_OK;
1305 }
1306
1307 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite)
1308 {
1309 if (ppvSite == NULL)
1310 return E_POINTER;
1311 if (fSite.p != NULL)
1312 return fSite->QueryInterface(riid, ppvSite);
1313 *ppvSite = NULL;
1314 return S_OK;
1315 }
1316
1317 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1318 {
1319 CComPtr<IServiceProvider> serviceProvider;
1320 HRESULT hResult;
1321
1322 if (IsEqualIID(guidService, IID_IBandSite))
1323 return this->QueryInterface(riid, ppvObject);
1324 if (IsEqualIID(guidService, SID_IBandProxy))
1325 {
1326 if (fBandProxy.p == NULL)
1327 {
1328 hResult = CreateAndInitBandProxy();
1329 if (FAILED_UNEXPECTEDLY(hResult))
1330 return hResult;
1331 }
1332 return fBandProxy->QueryInterface(riid, ppvObject);
1333 }
1334 return IUnknown_QueryService(fSite, guidService, riid, ppvObject);
1335 }
1336
1337 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent(
1338 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1339 {
1340 HRESULT hResult;
1341
1342 if (fMenuBar)
1343 {
1344 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult);
1345 if (hResult != S_FALSE)
1346 return hResult;
1347 }
1348
1349 if (fNavigationBar)
1350 {
1351 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult);
1352 if (hResult != S_FALSE)
1353 return hResult;
1354 }
1355
1356 if (fLogoBar)
1357 {
1358 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult);
1359 if (hResult != S_FALSE)
1360 return hResult;
1361 }
1362
1363 return S_FALSE;
1364 }
1365
1366 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd)
1367 {
1368 UNIMPLEMENTED;
1369 return E_NOTIMPL;
1370 }
1371
1372 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk)
1373 {
1374 UNIMPLEMENTED;
1375 return E_NOTIMPL;
1376 }
1377
1378 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID)
1379 {
1380 UNIMPLEMENTED;
1381 return E_NOTIMPL;
1382 }
1383
1384 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID,
1385 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName)
1386 {
1387 if (ppstb == NULL)
1388 return E_POINTER;
1389 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL)
1390 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1391 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL)
1392 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb));
1393 *ppstb = NULL;
1394 return E_FAIL;
1395 }
1396
1397 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState)
1398 {
1399 UNIMPLEMENTED;
1400 return E_NOTIMPL;
1401 }
1402
1403 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID)
1404 {
1405 UNIMPLEMENTED;
1406 return E_NOTIMPL;
1407 }
1408
1409 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv)
1410 {
1411 UNIMPLEMENTED;
1412 return E_NOTIMPL;
1413 }
1414
1415 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo)
1416 {
1417 UNIMPLEMENTED;
1418 return E_NOTIMPL;
1419 }
1420
1421 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo)
1422 {
1423 UNIMPLEMENTED;
1424 return E_NOTIMPL;
1425 }
1426
1427 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1428 {
1429 CComPtr<IServiceProvider> serviceProvider;
1430 CComPtr<IWebBrowser> webBrowser;
1431 HRESULT hResult;
1432
1433 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1434 if (FAILED_UNEXPECTEDLY(hResult))
1435 return 0;
1436 hResult = serviceProvider->QueryService(SID_SShellBrowser,
1437 IID_PPV_ARG(IWebBrowser, &webBrowser));
1438 if (FAILED_UNEXPECTEDLY(hResult))
1439 return 0;
1440 hResult = webBrowser->GoBack();
1441 return 1;
1442 }
1443
1444 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1445 {
1446 CComPtr<IServiceProvider> serviceProvider;
1447 CComPtr<IWebBrowser> webBrowser;
1448 HRESULT hResult;
1449
1450 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1451 if (FAILED_UNEXPECTEDLY(hResult))
1452 return 0;
1453 hResult = serviceProvider->QueryService(
1454 SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser));
1455 if (FAILED_UNEXPECTEDLY(hResult))
1456 return 0;
1457 hResult = webBrowser->GoForward();
1458 return 1;
1459 }
1460
1461 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1462 {
1463 CComPtr<IOleCommandTarget> oleCommandTarget;
1464 HRESULT hResult;
1465
1466 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1467 if (FAILED_UNEXPECTEDLY(hResult))
1468 return hResult;
1469 hResult = oleCommandTarget->Exec(&CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL);
1470 return 1;
1471 }
1472
1473 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1474 {
1475 CComPtr<IObjectWithSite> objectWithSite;
1476 CComPtr<IContextMenu> contextMenu;
1477 CMINVOKECOMMANDINFO commandInfo;
1478 const char *searchGUID = "{169A0691-8DF9-11d1-A1C4-00C04FD75D13}";
1479 HRESULT hResult;
1480
1481 // TODO: Query shell if this command is enabled first
1482
1483 memset(&commandInfo, 0, sizeof(commandInfo));
1484 commandInfo.cbSize = sizeof(commandInfo);
1485 commandInfo.hwnd = m_hWnd;
1486 commandInfo.lpParameters = searchGUID;
1487 commandInfo.nShow = SW_SHOWNORMAL;
1488
1489 hResult = CoCreateInstance(CLSID_ShellSearchExt, NULL, CLSCTX_INPROC_SERVER,
1490 IID_PPV_ARG(IContextMenu, &contextMenu));
1491 if (FAILED_UNEXPECTEDLY(hResult))
1492 return 0;
1493 hResult = contextMenu->QueryInterface(IID_PPV_ARG(IObjectWithSite, &objectWithSite));
1494 if (FAILED_UNEXPECTEDLY(hResult))
1495 return 0;
1496 hResult = objectWithSite->SetSite(fSite);
1497 if (FAILED_UNEXPECTEDLY(hResult))
1498 return 0;
1499 hResult = contextMenu->InvokeCommand(&commandInfo);
1500 hResult = objectWithSite->SetSite(NULL);
1501 return 0;
1502 }
1503
1504 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1505 {
1506 CComPtr<IOleCommandTarget> oleCommandTarget;
1507 HRESULT hResult;
1508
1509 hResult = fSite->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
1510 if (FAILED_UNEXPECTEDLY(hResult))
1511 return hResult;
1512 hResult = oleCommandTarget->Exec(&CGID_Explorer, 0x23, 0, NULL, NULL);
1513 return 1;
1514 }
1515
1516 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
1517 {
1518 HRESULT hResult;
1519
1520 if (fCommandTarget.p != NULL)
1521 {
1522 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL);
1523 }
1524 return 1;
1525 }
1526
1527 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1528 {
1529 CComPtr<IServiceProvider> serviceProvider;
1530 CComPtr<IBrowserService> browserService;
1531 CComPtr<IOleCommandTarget> commandTarget;
1532 CComPtr<ITravelLog> travelLog;
1533 NMTOOLBARW *notifyInfo;
1534 RECT bounds;
1535 HMENU newMenu;
1536 TPMPARAMS params;
1537 int selectedItem;
1538 VARIANT parmIn;
1539 OLECMD commandInfo;
1540 HRESULT hResult;
1541
1542 notifyInfo = (NMTOOLBARW *)pNMHDR;
1543 if (notifyInfo->hdr.hwndFrom != fToolbarWindow)
1544 {
1545 // not from the toolbar, keep looking for a message handler
1546 bHandled = FALSE;
1547 return 0;
1548 }
1549 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds));
1550 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2);
1551 switch (notifyInfo->iItem)
1552 {
1553 case IDM_GOTO_BACK:
1554 newMenu = CreatePopupMenu();
1555 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1556 hResult = serviceProvider->QueryService(
1557 SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1558 hResult = browserService->GetTravelLog(&travelLog);
1559 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK);
1560 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1561 commandInfo.cmdID = 0x1d;
1562 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1563 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1564 travelLog->CountEntries(browserService) > 1)
1565 {
1566 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1567 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1568 }
1569 params.cbSize = sizeof (params);
1570 params.rcExclude = bounds;
1571 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1572 bounds.left, bounds.bottom, m_hWnd, &params);
1573 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1574 {
1575 V_VT(&parmIn) = VT_I4;
1576 V_I4(&parmIn) = 1;
1577 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1578 }
1579 else if (selectedItem != 0)
1580 hResult = travelLog->Travel(browserService, -selectedItem);
1581 DestroyMenu(newMenu);
1582 break;
1583 case IDM_GOTO_FORWARD:
1584 newMenu = CreatePopupMenu();
1585 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider));
1586 hResult = serviceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
1587 hResult = browserService->GetTravelLog(&travelLog);
1588 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE);
1589 hResult = browserService->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &commandTarget));
1590 commandInfo.cmdID = 0x1d;
1591 hResult = commandTarget->QueryStatus(&CGID_Explorer, 1, &commandInfo, NULL);
1592 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED &&
1593 travelLog->CountEntries(browserService) > 1)
1594 {
1595 AppendMenu(newMenu, MF_SEPARATOR, -1, L"");
1596 AppendMenu(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, L"&History\tCtrl+H");
1597 }
1598 params.cbSize = sizeof (params);
1599 params.rcExclude = bounds;
1600 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD,
1601 bounds.left, bounds.bottom, m_hWnd, &params);
1602 if (selectedItem == IDM_EXPLORERBAR_HISTORY)
1603 {
1604 V_VT(&parmIn) = VT_I4;
1605 V_I4(&parmIn) = 1;
1606 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL);
1607 }
1608 else if (selectedItem != 0)
1609 hResult = travelLog->Travel(browserService, -selectedItem);
1610 DestroyMenu(newMenu);
1611 break;
1612 case gViewsCommandID:
1613 VARIANT inValue;
1614 CComVariant outValue;
1615 HRESULT hResult;
1616
1617 V_VT(&inValue) = VT_INT_PTR;
1618 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds);
1619
1620 if (fCommandTarget.p != NULL)
1621 hResult = fCommandTarget->Exec(&fCommandCategory, 0x7031, 1, &inValue, &outValue);
1622 // pvaOut is VT_I4 with value 0x403
1623 break;
1624 }
1625 return TBDDRET_DEFAULT;
1626 }
1627
1628 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1629 {
1630 return 1;
1631 }
1632
1633 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1634 {
1635 return 1;
1636 }
1637
1638 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1639 {
1640 HMENU contextMenuBar;
1641 HMENU contextMenu;
1642 POINT clickLocation;
1643 int command;
1644 RBHITTESTINFO hitTestInfo;
1645 REBARBANDINFOW rebarBandInfo;
1646 int bandID;
1647
1648 clickLocation.x = LOWORD(lParam);
1649 clickLocation.y = HIWORD(lParam);
1650 hitTestInfo.pt = clickLocation;
1651 ScreenToClient(&hitTestInfo.pt);
1652 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo);
1653 if (hitTestInfo.iBand == -1)
1654 return 0;
1655 rebarBandInfo.cbSize = sizeof(rebarBandInfo);
1656 rebarBandInfo.fMask = RBBIM_ID;
1657 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
1658 bandID = rebarBandInfo.wID;
1659 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU));
1660 contextMenu = GetSubMenu(contextMenuBar, 0);
1661 switch (bandID)
1662 {
1663 case ITBBID_MENUBAND: // menu band
1664 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1665 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1666 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1667 break;
1668 case ITBBID_BRANDBAND: // brand band
1669 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1670 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1671 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1672 break;
1673 case ITBBID_TOOLSBAND: // tools band
1674 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1675 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND);
1676 break;
1677 case ITBBID_ADDRESSBAND: // navigation band
1678 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND);
1679 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND);
1680 break;
1681 default:
1682 break;
1683 }
1684
1685 MENUITEMINFO mii;
1686 mii.cbSize = sizeof(mii);
1687 mii.fMask = MIIM_STATE;
1688 mii.fState = fLocked ? MFS_CHECKED : MFS_UNCHECKED;
1689 command = SetMenuItemInfo(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, FALSE, &mii);
1690
1691 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
1692 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
1693 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL);
1694 switch (command)
1695 {
1696 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons
1697 break;
1698 case IDM_TOOLBARS_ADDRESSBAR: // address bar
1699 break;
1700 case IDM_TOOLBARS_LINKSBAR: // links
1701 break;
1702 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
1703 LockUnlockToolbars(!fLocked);
1704 break;
1705 case IDM_TOOLBARS_CUSTOMIZE: // customize
1706 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
1707 break;
1708 }
1709
1710 DestroyMenu(contextMenuBar);
1711 return 1;
1712 }
1713
1714 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1715 {
1716 if (wParam != SIZE_MINIMIZED)
1717 {
1718 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam),
1719 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
1720 }
1721 return 1;
1722 }
1723
1724 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1725 {
1726 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd)
1727 {
1728 bHandled = FALSE;
1729 return 0;
1730 }
1731 SetCursor(LoadCursor(NULL, IDC_SIZENS));
1732 return 1;
1733 }
1734
1735 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled)
1736 {
1737 CComPtr<IBrowserService> browserService;
1738 CComPtr<ITravelLog> travelLog;
1739 TOOLTIPTEXTW *pTTTW;
1740 UINT nID;
1741 wchar_t tempString[300];
1742 HRESULT hResult;
1743
1744 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR);
1745 if ((pTTTW->uFlags & TTF_IDISHWND) != 0)
1746 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom);
1747 else
1748 nID = (UINT)pNMHDR->idFrom;
1749
1750 if (nID != 0)
1751 {
1752 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD)
1753 {
1754 // TODO: Should this call QueryService?
1755 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService));
1756 hResult = browserService->GetTravelLog(&travelLog);
1757 hResult = travelLog->GetToolTipText(browserService,
1758 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE,
1759 0, tempString, 299);
1760 if (FAILED_UNEXPECTEDLY(hResult))
1761 {
1762 bHandled = FALSE;
1763 return 0;
1764 }
1765 }
1766 else
1767 tempString[0] = 0;
1768 wcsncpy (pTTTW->szText, tempString, sizeof (pTTTW->szText) / sizeof (wchar_t));
1769 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
1770 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1771 return 0;
1772 }
1773 return 0;
1774 }
1775
1776 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1777 {
1778 LRESULT theResult;
1779 HRESULT hResult;
1780
1781 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult);
1782
1783 bHandled = hResult == S_OK;
1784
1785 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1786 }
1787 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1788 {
1789 NMHDR *notifyHeader;
1790 LRESULT theResult;
1791 HRESULT hResult;
1792
1793 notifyHeader = reinterpret_cast<NMHDR *>(lParam);
1794
1795 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult);
1796
1797 bHandled = hResult == S_OK;
1798
1799 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult;
1800 }
1801
1802 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1803 {
1804 bHandled = FALSE;
1805 if (fLocked)
1806 return 0;
1807
1808 if (wParam & MK_CONTROL)
1809 return 0;
1810
1811 fSizing = TRUE;
1812
1813 DWORD msgp = GetMessagePos();
1814
1815 fStartPosition.x = GET_X_LPARAM(msgp);
1816 fStartPosition.y = GET_Y_LPARAM(msgp);
1817
1818 RECT rc;
1819 GetWindowRect(m_hWnd, &rc);
1820
1821 fStartHeight = rc.bottom - rc.top;
1822
1823 SetCapture();
1824
1825 bHandled = TRUE;
1826 return 0;
1827 }
1828
1829 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1830 {
1831 bHandled = FALSE;
1832 if (!fSizing)
1833 return 0;
1834
1835 DWORD msgp = GetMessagePos();
1836
1837 POINT pt;
1838 pt.x = GET_X_LPARAM(msgp);
1839 pt.y = GET_Y_LPARAM(msgp);
1840
1841 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y);
1842
1843 bHandled = TRUE;
1844 return 0;
1845 }
1846
1847 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1848 {
1849 bHandled = FALSE;
1850 if (!fSizing)
1851 return 0;
1852
1853 OnMouseMove(uMsg, wParam, lParam, bHandled);
1854
1855 fSizing = FALSE;
1856
1857 ReleaseCapture();
1858
1859 return 0;
1860 }
1861
1862 HRESULT CreateInternetToolbar(REFIID riid, void **ppv)
1863 {
1864 CInternetToolbar *theToolbar;
1865 HRESULT hResult;
1866
1867 if (ppv == NULL)
1868 return E_POINTER;
1869 *ppv = NULL;
1870 ATLTRY (theToolbar = new CComObject<CInternetToolbar>);
1871 if (theToolbar == NULL)
1872 return E_OUTOFMEMORY;
1873 hResult = theToolbar->QueryInterface (riid, reinterpret_cast<void **>(ppv));
1874 if (FAILED_UNEXPECTEDLY(hResult))
1875 {
1876 delete theToolbar;
1877 return hResult;
1878 }
1879 return S_OK;
1880 }