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