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