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