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