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