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