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