[REACTOS]
[reactos.git] / reactos / 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 // navigation controls and menubar just send a message to parent window
29 /*
30 TODO:
31 ****Implement BandProxy methods
32 ****Add QueryStatus handler for built-in bands
33 ****Enable/Disable up, search, and folders commands appropriately
34 **Why are explorer toolbar separators a nonstandard width?
35 **Remove "(Empty)" item from Favorites menu. Probably something missing in CMenuCallback::CallbackSM
36 **Chevron menu on menuband doesn't work
37 **Fix CInternetToolbar::QueryBand to be generic
38
39 ****Fix context menu to strip divider when menu shown for menu band
40 ****Fix context menu to have items checked appropriately
41 ****Implement -1 command id update
42 ****When bands are rearranged, resize the internet toolbar and fix height of brand band
43 ****Right clicking on the browse back and forward toolbar buttons displays the same as pulldown menus
44 Implement show/hide of bands
45 Why is the background color of my toolbars different from explorer?
46 Internet Toolbar command handler should get the target for the command and call Exec on the target.
47 For commands built in to the Internet Toolbar, its Exec handles the command
48 When window width is changed, brand band flashes badly
49 Add all bands with correct ids (system bands now add with correct ids)
50 Implement IBandSite
51 Implement remaining IExplorerToolbar methods
52 Fix toolbar buttons to enable/disable correctly
53 After toolbar is customized, it may be necessary to patch the widths of separators
54 Add theme support
55 Check sizes and spacing of toolbars against Explorer
56 Implement resizing of the dock bar
57 Add missing icons for toolbar items
58 Draw History item in forward/back dropdown menus with icon
59 Fix toolbar customize dialog to not include separators as possible selections
60 Implement save/restore of toolbar state
61 Refactor drop down menu code to use a common function since code is so similar
62 */
63
64 extern HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder);
65 extern HRESULT CreateToolsBar(REFIID riid, void **ppv);
66 extern HRESULT CreateBrandBand(REFIID riid, void **ppv);
67 extern HRESULT CreateBandProxy(REFIID riid, void **ppv);
68 extern HRESULT CreateAddressBand(REFIID riid, void **ppv);
69
70 class CInternetToolbar;
71
72 class CDockSite :
73 public CComObjectRootEx<CComMultiThreadModelNoCS>,
74 public IDockingWindowSite,
75 public IInputObjectSite,
76 public IOleCommandTarget,
77 public IServiceProvider
78 {
79 public:
80 enum {
81 ITF_NOGRIPPER = 1,
82 ITF_NOTITLE = 2,
83 ITF_NEWBANDALWAYS = 4,
84 ITF_GRIPPERALWAYS = 8,
85 ITF_FIXEDSIZE = 16
86 };
87 private:
88 CComPtr<IUnknown> fContainedBand; // the band inside us
89 CInternetToolbar *fToolbar; // our browser
90 HWND fRebarWindow;
91 HWND fChildWindow;
92 int fBandID;
93 public:
94 int fFlags;
95 private:
96 bool fInitialized;
97 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo
98 DESKBANDINFO fDeskBandInfo;
99 public:
100 CDockSite();
101 ~CDockSite();
102 HRESULT Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags);
103 HRESULT GetRBBandInfo(REBARBANDINFOW &bandInfo);
104 private:
105
106 // *** IOleWindow methods ***
107 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
108 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
109
110 // *** IDockingWindow methods ***
111 virtual HRESULT STDMETHODCALLTYPE GetBorderDW(IUnknown* punkObj, LPRECT prcBorder);
112 virtual HRESULT STDMETHODCALLTYPE RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
113 virtual HRESULT STDMETHODCALLTYPE SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw);
114
115 // *** IInputObjectSite specific methods ***
116 virtual HRESULT STDMETHODCALLTYPE OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus);
117
118 // *** IOleCommandTarget specific methods ***
119 virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
120 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText);
121 virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
122 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
123
124 // *** IServiceProvider methods ***
125 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
126
127 BEGIN_COM_MAP(CDockSite)
128 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
129 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite)
130 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite)
131 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
132 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
133 END_COM_MAP()
134 };
135
136 CDockSite::CDockSite()
137 {
138 fToolbar = NULL;
139 fRebarWindow = NULL;
140 fChildWindow = NULL;
141 fBandID = 0;
142 fFlags = 0;
143 fInitialized = false;
144 memset(&fDeskBandInfo, 0, sizeof(fDeskBandInfo));
145 }
146
147 CDockSite::~CDockSite()
148 {
149 }
150
151 HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags)
152 {
153 CComPtr<IObjectWithSite> site;
154 CComPtr<IOleWindow> oleWindow;
155 CComPtr<IDeskBand> deskBand;
156 TCHAR textBuffer[40];
157 REBARBANDINFOW bandInfo;
158 HRESULT hResult;
159
160 hResult = containedBand->QueryInterface(IID_IObjectWithSite, reinterpret_cast<void **>(&site));
161 if (FAILED(hResult))
162 return hResult;
163 hResult = containedBand->QueryInterface(IID_IOleWindow, reinterpret_cast<void **>(&oleWindow));
164 if (FAILED(hResult))
165 return hResult;
166 hResult = containedBand->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(&deskBand));
167 if (FAILED(hResult))
168 return hResult;
169 fContainedBand = containedBand;
170 fToolbar = browser;
171 fRebarWindow = hwnd;
172 fBandID = bandID;
173 fFlags = flags;
174 hResult = site->SetSite(static_cast<IOleWindow *>(this));
175 if (FAILED(hResult))
176 return hResult;
177 hResult = oleWindow->GetWindow(&fChildWindow);
178 if (FAILED(hResult))
179 return hResult;
180
181 memset(&bandInfo, 0, sizeof(bandInfo));
182 bandInfo.cbSize = sizeof(bandInfo);
183 bandInfo.lpText = textBuffer;
184 bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR);
185 hResult = GetRBBandInfo(bandInfo);
186
187 SendMessage(fRebarWindow, RB_GETBANDCOUNT, 0, 0);
188 SendMessage(fRebarWindow, RB_INSERTBANDW, -1, (LPARAM)&bandInfo);
189 fInitialized = true;
190 return S_OK;
191 }
192
193 HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
194 {
195 CComPtr<IDeskBand> deskBand;
196 HRESULT hResult;
197
198 hResult = fContainedBand->QueryInterface(IID_IDeskBand, reinterpret_cast<void **>(&deskBand));
199 if (FAILED(hResult))
200 return hResult;
201
202 fDeskBandInfo.dwMask = DBIM_BKCOLOR | DBIM_MODEFLAGS | DBIM_TITLE | DBIM_ACTUAL |
203 DBIM_INTEGRAL | DBIM_MAXSIZE | DBIM_MINSIZE;
204 hResult = deskBand->GetBandInfo(fBandID, 0, &fDeskBandInfo);
205 // result of call is ignored
206
207 bandInfo.fMask = RBBIM_LPARAM | RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_CHILDSIZE | RBBIM_CHILD |
208 RBBIM_TEXT | RBBIM_STYLE;
209
210 bandInfo.fStyle = RBBS_FIXEDBMP;
211 if (fDeskBandInfo.dwModeFlags & DBIMF_VARIABLEHEIGHT)
212 bandInfo.fStyle |= RBBS_VARIABLEHEIGHT;
213 if (fDeskBandInfo.dwModeFlags & DBIMF_USECHEVRON)
214 bandInfo.fStyle |= RBBS_USECHEVRON;
215 if (fDeskBandInfo.dwModeFlags & DBIMF_BREAK)
216 bandInfo.fStyle |= RBBS_BREAK;
217 if (fDeskBandInfo.dwModeFlags & DBIMF_TOPALIGN)
218 bandInfo.fStyle |= RBBS_TOPALIGN;
219 if (fFlags & ITF_NOGRIPPER || fToolbar->fLocked)
220 bandInfo.fStyle |= RBBS_NOGRIPPER;
221 if (fFlags & ITF_NOTITLE)
222 bandInfo.fStyle |= RBBS_HIDETITLE;
223 if (fFlags & ITF_GRIPPERALWAYS && !fToolbar->fLocked)
224 bandInfo.fStyle |= RBBS_GRIPPERALWAYS;
225 if (fFlags & ITF_FIXEDSIZE)
226 bandInfo.fStyle |= RBBS_FIXEDSIZE;
227
228 if (fDeskBandInfo.dwModeFlags & DBIMF_BKCOLOR)
229 {
230 bandInfo.fMask |= RBBIM_COLORS;
231 bandInfo.clrFore = CLR_DEFAULT;
232 bandInfo.clrBack = fDeskBandInfo.crBkgnd;
233 }
234 wcsncpy(bandInfo.lpText, fDeskBandInfo.wszTitle, bandInfo.cch);
235 bandInfo.hwndChild = fChildWindow;
236 bandInfo.cxMinChild = fDeskBandInfo.ptMinSize.x;
237 bandInfo.cyMinChild = fDeskBandInfo.ptMinSize.y;
238 bandInfo.wID = fBandID;
239 bandInfo.cyChild = fDeskBandInfo.ptActual.y;
240 bandInfo.cyMaxChild = fDeskBandInfo.ptMaxSize.y;
241 bandInfo.cyIntegral = fDeskBandInfo.ptIntegral.y;
242 bandInfo.cxIdeal = fDeskBandInfo.ptActual.x;
243 bandInfo.lParam = reinterpret_cast<LPARAM>(this);
244 return S_OK;
245 }
246
247 HRESULT STDMETHODCALLTYPE CDockSite::GetWindow(HWND *lphwnd)
248 {
249 if (lphwnd == NULL)
250 return E_POINTER;
251 *lphwnd = fRebarWindow;
252 return S_OK;
253 }
254
255 HRESULT STDMETHODCALLTYPE CDockSite::ContextSensitiveHelp(BOOL fEnterMode)
256 {
257 return E_NOTIMPL;
258 }
259
260 HRESULT STDMETHODCALLTYPE CDockSite::GetBorderDW(IUnknown* punkObj, LPRECT prcBorder)
261 {
262 return E_NOTIMPL;
263 }
264
265 HRESULT STDMETHODCALLTYPE CDockSite::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
266 {
267 return E_NOTIMPL;
268 }
269
270 HRESULT STDMETHODCALLTYPE CDockSite::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw)
271 {
272 return E_NOTIMPL;
273 }
274
275 HRESULT STDMETHODCALLTYPE CDockSite::OnFocusChangeIS (IUnknown *punkObj, BOOL fSetFocus)
276 {
277 return E_NOTIMPL;
278 }
279
280 HRESULT STDMETHODCALLTYPE CDockSite::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
281 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
282 {
283 return E_NOTIMPL;
284 }
285
286 HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt,
287 VARIANT *pvaIn, VARIANT *pvaOut)
288 {
289 TCHAR textBuffer[40];
290 REBARBANDINFOW bandInfo;
291 int index;
292 HRESULT hResult;
293
294 if (IsEqualIID(*pguidCmdGroup, CGID_DeskBand))
295 {
296 switch (nCmdID)
297 {
298 case DBID_BANDINFOCHANGED:
299 if (fInitialized == false)
300 return S_OK;
301 if (V_VT(pvaIn) != VT_I4)
302 return E_INVALIDARG;
303 if (V_I4(pvaIn) != fBandID)
304 return E_FAIL;
305 // deskband information changed
306 // call GetBandInfo and refresh information in rebar
307 memset(&bandInfo, 0, sizeof(bandInfo));
308 bandInfo.cbSize = sizeof(bandInfo);
309 bandInfo.lpText = textBuffer;
310 bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR);
311 hResult = GetRBBandInfo(bandInfo);
312 if (FAILED(hResult))
313 return hResult;
314 index = (int)SendMessage(fRebarWindow, RB_IDTOINDEX, fBandID, 0);
315 SendMessage(fRebarWindow, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
316 return S_OK;
317 }
318 }
319 return E_FAIL;
320 }
321
322 HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
323 {
324 CComPtr<IServiceProvider> serviceProvider;
325 HRESULT hResult;
326
327 if (IsEqualIID(guidService, SID_SMenuBandParent))
328 return this->QueryInterface(riid, ppvObject);
329 hResult = fToolbar->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&serviceProvider));
330 if (FAILED(hResult))
331 return hResult;
332 return serviceProvider->QueryService(guidService, riid, ppvObject);
333 }
334
335 CMenuCallback::CMenuCallback()
336 {
337 }
338
339 CMenuCallback::~CMenuCallback()
340 {
341 }
342
343 HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, void **ppvObject)
344 {
345 CComPtr<IShellMenu> parentMenu;
346 CComPtr<IShellMenu> newMenu;
347 CComPtr<IShellFolder> favoritesFolder;
348 LPITEMIDLIST favoritesPIDL;
349 HWND ownerWindow;
350 HMENU parentHMenu;
351 HMENU favoritesHMenu;
352 HKEY orderRegKey;
353 DWORD disposition;
354 HRESULT hResult;
355 static const TCHAR szFavoritesKey[] =
356 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites");
357
358 if (!IsEqualIID(riid, IID_IShellMenu))
359 return E_FAIL;
360 if (psmd->uId != FCIDM_MENU_FAVORITES)
361 return E_FAIL;
362
363 if (fFavoritesMenu.p == NULL)
364 {
365 // create favorites menu
366 hResult = psmd->punk->QueryInterface(IID_IShellMenu, reinterpret_cast<void **>(&parentMenu));
367 if (FAILED(hResult))
368 return hResult;
369 hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL);
370 if (FAILED(hResult))
371 return hResult;
372 favoritesHMenu = GetSubMenu(parentHMenu, 3);
373 if (favoritesHMenu == NULL)
374 return E_FAIL;
375 hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,
376 IID_IShellMenu, reinterpret_cast<void **>(&newMenu));
377 if (FAILED(hResult))
378 return hResult;
379 hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED);
380 if (FAILED(hResult))
381 return hResult;
382 hResult = newMenu->SetMenu(favoritesHMenu, ownerWindow, SMSET_TOP | SMSET_DONTOWN);
383 if (FAILED(hResult))
384 return hResult;
385 hResult = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &favoritesPIDL);
386 if (FAILED(hResult))
387 return hResult;
388 hResult = SHBindToFolder(favoritesPIDL, &favoritesFolder);
389 if (FAILED(hResult))
390 return hResult;
391 RegCreateKeyEx(HKEY_CURRENT_USER, szFavoritesKey,
392 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &orderRegKey, &disposition);
393 hResult = newMenu->SetShellFolder(favoritesFolder, favoritesPIDL, orderRegKey, SMSET_BOTTOM | 0x18);
394 ILFree(favoritesPIDL);
395 if (SUCCEEDED(hResult))
396 fFavoritesMenu.Attach(newMenu.Detach());
397 }
398 if (fFavoritesMenu.p == NULL)
399 return E_FAIL;
400 return fFavoritesMenu->QueryInterface(riid, ppvObject);
401 }
402
403 HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam)
404 {
405 switch (uMsg)
406 {
407 case SMC_INITMENU:
408 break;
409 case SMC_CREATE:
410 break;
411 case SMC_EXITMENU:
412 break;
413 case SMC_GETINFO:
414 {
415 SMINFO *infoPtr = reinterpret_cast<SMINFO *>(lParam);
416 if ((infoPtr->dwMask & SMIM_FLAGS) != 0)
417 {
418 if (psmd->uId == FCIDM_MENU_FAVORITES)
419 {
420 infoPtr->dwFlags |= SMIF_DROPCASCADE;
421 }
422 else
423 {
424 infoPtr->dwFlags |= SMIF_TRACKPOPUP;
425 }
426 }
427 if ((infoPtr->dwMask & SMIM_ICON) != 0)
428 infoPtr->iIcon = -1;
429 return S_OK;
430 }
431 case SMC_GETSFINFO:
432 break;
433 case SMC_GETOBJECT:
434 return GetObject(psmd, *reinterpret_cast<IID *>(wParam), reinterpret_cast<void **>(lParam));
435 case SMC_GETSFOBJECT:
436 break;
437 case SMC_SFEXEC:
438 break;
439 case SMC_SFSELECTITEM:
440 break;
441 case 13:
442 // return tooltip
443 break;
444 case SMC_REFRESH:
445 break;
446 case SMC_DEMOTE:
447 break;
448 case SMC_PROMOTE:
449 break;
450 case 0x13:
451 break;
452 case SMC_DEFAULTICON:
453 break;
454 case SMC_NEWITEM:
455 break;
456 case SMC_CHEVRONEXPAND:
457 break;
458 case SMC_DISPLAYCHEVRONTIP:
459 break;
460 case SMC_SETSFOBJECT:
461 break;
462 case SMC_SHCHANGENOTIFY:
463 break;
464 case SMC_CHEVRONGETTIP:
465 break;
466 case SMC_SFDDRESTRICTED:
467 break;
468 case 0x35:
469 break;
470 case 49:
471 break;
472 case 0x10000000:
473 break;
474 }
475 return S_FALSE;
476 }
477
478 CInternetToolbar::CInternetToolbar()
479 {
480 fMainReBar = NULL;
481 fLocked = false;
482 fMenuBandWindow = NULL;
483 fNavigationWindow = NULL;
484 fMenuCallback = new CComObject<CMenuCallback>();
485 fToolbarWindow = NULL;
486 fAdviseCookie = 0;
487 }
488
489 CInternetToolbar::~CInternetToolbar()
490 {
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 }