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 #if 1 29 30 interface IAugmentedShellFolder : public IShellFolder 31 { 32 STDMETHOD(AddNameSpace)(LPGUID, IShellFolder *, LPCITEMIDLIST, ULONG) PURE; 33 STDMETHOD(GetNameSpaceID)(LPCITEMIDLIST, LPGUID) PURE; 34 STDMETHOD(QueryNameSpace)(ULONG, LPGUID, IShellFolder **) PURE; 35 STDMETHOD(EnumNameSpace)(ULONG, PULONG) PURE; 36 }; 37 38 #endif 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(LPCITEMIDLIST path, IShellFolder **newFolder); 77 78 struct ITBARSTATE 79 { 80 static const UINT SIG = ('R' << 0) | ('O' << 8) | ('S' << 16) | (('i' ^ 't' ^ 'b') << 24); 81 UINT cbSize; 82 UINT Signature; // Note: Windows has something else here (12 bytes) 83 UINT StdToolbar : 1; 84 UINT Addressbar : 1; 85 UINT Linksbar : 1; 86 UINT Throbber : 1; // toastytech.com/files/throboff.html 87 UINT Menubar : 1; // ..\Explorer\Advanced\AlwaysShowMenus for NT6? 88 // Note: Windows 8/10 stores the Ribbon state in ..\Explorer\Ribbon 89 }; 90 91 HRESULT IUnknown_RelayWinEvent(IUnknown * punk, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) 92 { 93 CComPtr<IWinEventHandler> menuWinEventHandler; 94 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler)); 95 if (FAILED_UNEXPECTEDLY(hResult)) 96 return hResult; 97 hResult = menuWinEventHandler->IsWindowOwner(hWnd); 98 if (FAILED_UNEXPECTEDLY(hResult)) 99 return hResult; 100 if (hResult == S_OK) 101 return menuWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult); 102 return S_FALSE; 103 } 104 105 HRESULT IUnknown_ShowDW(IUnknown * punk, BOOL fShow) 106 { 107 CComPtr<IDockingWindow> dockingWindow; 108 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow)); 109 if (FAILED_UNEXPECTEDLY(hResult)) 110 return hResult; 111 hResult = dockingWindow->ShowDW(fShow); 112 if (FAILED_UNEXPECTEDLY(hResult)) 113 return hResult; 114 return S_OK; 115 } 116 117 HRESULT IUnknown_CloseDW(IUnknown * punk, DWORD dwReserved) 118 { 119 CComPtr<IDockingWindow> dockingWindow; 120 HRESULT hResult = punk->QueryInterface(IID_PPV_ARG(IDockingWindow, &dockingWindow)); 121 if (FAILED_UNEXPECTEDLY(hResult)) 122 return hResult; 123 hResult = dockingWindow->CloseDW(dwReserved); 124 if (FAILED_UNEXPECTEDLY(hResult)) 125 return hResult; 126 return S_OK; 127 } 128 129 class CInternetToolbar; 130 131 class CDockSite : 132 public CComObjectRootEx<CComMultiThreadModelNoCS>, 133 public IDockingWindowSite, 134 public IInputObjectSite, 135 public IOleCommandTarget, 136 public IServiceProvider 137 { 138 public: 139 enum { 140 ITF_NOGRIPPER = 1, 141 ITF_NOTITLE = 2, 142 ITF_NEWBANDALWAYS = 4, 143 ITF_GRIPPERALWAYS = 8, 144 ITF_FIXEDSIZE = 16 145 }; 146 private: 147 CComPtr<IUnknown> fContainedBand; // the band inside us 148 CInternetToolbar *fToolbar; // our browser 149 HWND fRebarWindow; 150 HWND fChildWindow; 151 int fBandID; 152 public: 153 int fFlags; 154 private: 155 bool fInitialized; 156 // fields of DESKBANDINFO must be preserved between calls to GetBandInfo 157 DESKBANDINFO fDeskBandInfo; 158 public: 159 CDockSite(); 160 ~CDockSite(); 161 HRESULT Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags); 162 HRESULT GetRBBandInfo(REBARBANDINFOW &bandInfo); 163 IUnknown* GetContainedBand() const { return fContainedBand.p; } // Not ref. counted 164 private: 165 166 // *** IOleWindow methods *** 167 STDMETHOD(GetWindow)(HWND *lphwnd) override; 168 STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override; 169 170 // *** IDockingWindow methods *** 171 STDMETHOD(GetBorderDW)(IUnknown* punkObj, LPRECT prcBorder) override; 172 STDMETHOD(RequestBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override; 173 STDMETHOD(SetBorderSpaceDW)(IUnknown* punkObj, LPCBORDERWIDTHS pbw) override; 174 175 // *** IInputObjectSite specific methods *** 176 STDMETHOD(OnFocusChangeIS)(IUnknown *punkObj, BOOL fSetFocus) override; 177 178 // *** IOleCommandTarget specific methods *** 179 STDMETHOD(QueryStatus)(const GUID *pguidCmdGroup, ULONG cCmds, 180 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) override; 181 STDMETHOD(Exec)(const GUID *pguidCmdGroup, DWORD nCmdID, 182 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override; 183 184 // *** IServiceProvider methods *** 185 STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override; 186 187 BEGIN_COM_MAP(CDockSite) 188 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 189 COM_INTERFACE_ENTRY_IID(IID_IDockingWindowSite, IDockingWindowSite) 190 COM_INTERFACE_ENTRY_IID(IID_IInputObjectSite, IInputObjectSite) 191 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) 192 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 193 END_COM_MAP() 194 }; 195 196 CDockSite::CDockSite() 197 { 198 fToolbar = NULL; 199 fRebarWindow = NULL; 200 fChildWindow = NULL; 201 fBandID = 0; 202 fFlags = 0; 203 fInitialized = false; 204 memset(&fDeskBandInfo, 0, sizeof(fDeskBandInfo)); 205 } 206 207 CDockSite::~CDockSite() 208 { 209 } 210 211 HRESULT CDockSite::Initialize(IUnknown *containedBand, CInternetToolbar *browser, HWND hwnd, int bandID, int flags) 212 { 213 TCHAR textBuffer[40]; 214 REBARBANDINFOW bandInfo; 215 HRESULT hResult; 216 217 fContainedBand = containedBand; 218 fToolbar = browser; 219 fRebarWindow = hwnd; 220 fBandID = bandID; 221 fFlags = flags; 222 hResult = IUnknown_SetSite(containedBand, static_cast<IOleWindow *>(this)); 223 if (FAILED_UNEXPECTEDLY(hResult)) 224 return hResult; 225 hResult = IUnknown_GetWindow(containedBand, &fChildWindow); 226 if (FAILED_UNEXPECTEDLY(hResult)) 227 return hResult; 228 229 memset(&bandInfo, 0, sizeof(bandInfo)); 230 bandInfo.cbSize = sizeof(bandInfo); 231 bandInfo.lpText = textBuffer; 232 bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR); 233 hResult = GetRBBandInfo(bandInfo); 234 235 SendMessage(fRebarWindow, RB_GETBANDCOUNT, 0, 0); 236 SendMessage(fRebarWindow, RB_INSERTBANDW, -1, (LPARAM)&bandInfo); 237 fInitialized = true; 238 return S_OK; 239 } 240 241 HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo) 242 { 243 CComPtr<IDeskBand> deskBand; 244 HRESULT hResult; 245 246 hResult = fContainedBand->QueryInterface(IID_PPV_ARG(IDeskBand, &deskBand)); 247 if (FAILED_UNEXPECTEDLY(hResult)) 248 return hResult; 249 250 fDeskBandInfo.dwMask = DBIM_BKCOLOR | DBIM_MODEFLAGS | DBIM_TITLE | DBIM_ACTUAL | 251 DBIM_INTEGRAL | DBIM_MAXSIZE | DBIM_MINSIZE; 252 hResult = deskBand->GetBandInfo(fBandID, 0, &fDeskBandInfo); 253 // result of call is ignored 254 255 bandInfo.fMask = RBBIM_LPARAM | RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_CHILDSIZE | RBBIM_CHILD | 256 RBBIM_TEXT | RBBIM_STYLE; 257 258 bandInfo.fStyle = RBBS_FIXEDBMP; 259 if (fDeskBandInfo.dwModeFlags & DBIMF_VARIABLEHEIGHT) 260 bandInfo.fStyle |= RBBS_VARIABLEHEIGHT; 261 if (fDeskBandInfo.dwModeFlags & DBIMF_USECHEVRON) 262 bandInfo.fStyle |= RBBS_USECHEVRON; 263 if (fDeskBandInfo.dwModeFlags & DBIMF_BREAK) 264 bandInfo.fStyle |= RBBS_BREAK; 265 if (fDeskBandInfo.dwModeFlags & DBIMF_TOPALIGN) 266 bandInfo.fStyle |= RBBS_TOPALIGN; 267 if ((fFlags & ITF_NOGRIPPER) || fToolbar->pSettings->fLocked) 268 bandInfo.fStyle |= RBBS_NOGRIPPER; 269 if (fFlags & ITF_NOTITLE) 270 bandInfo.fStyle |= RBBS_HIDETITLE; 271 if ((fFlags & ITF_GRIPPERALWAYS) && !fToolbar->pSettings->fLocked) 272 bandInfo.fStyle |= RBBS_GRIPPERALWAYS; 273 if (fFlags & ITF_FIXEDSIZE) 274 bandInfo.fStyle |= RBBS_FIXEDSIZE; 275 276 if (fDeskBandInfo.dwModeFlags & DBIMF_BKCOLOR) 277 { 278 bandInfo.fMask |= RBBIM_COLORS; 279 bandInfo.clrFore = CLR_DEFAULT; 280 bandInfo.clrBack = fDeskBandInfo.crBkgnd; 281 } 282 wcsncpy(bandInfo.lpText, fDeskBandInfo.wszTitle, bandInfo.cch); 283 bandInfo.hwndChild = fChildWindow; 284 bandInfo.cxMinChild = fDeskBandInfo.ptMinSize.x; 285 bandInfo.cyMinChild = fDeskBandInfo.ptMinSize.y; 286 bandInfo.wID = fBandID; 287 bandInfo.cyChild = fDeskBandInfo.ptActual.y; 288 bandInfo.cyMaxChild = fDeskBandInfo.ptMaxSize.y; 289 bandInfo.cyIntegral = fDeskBandInfo.ptIntegral.y; 290 bandInfo.cxIdeal = fDeskBandInfo.ptActual.x; 291 bandInfo.lParam = reinterpret_cast<LPARAM>(static_cast<CDockSite*>(this)); 292 return S_OK; 293 } 294 295 HRESULT STDMETHODCALLTYPE CDockSite::GetWindow(HWND *lphwnd) 296 { 297 if (lphwnd == NULL) 298 return E_POINTER; 299 *lphwnd = fRebarWindow; 300 return S_OK; 301 } 302 303 HRESULT STDMETHODCALLTYPE CDockSite::ContextSensitiveHelp(BOOL fEnterMode) 304 { 305 return E_NOTIMPL; 306 } 307 308 HRESULT STDMETHODCALLTYPE CDockSite::GetBorderDW(IUnknown* punkObj, LPRECT prcBorder) 309 { 310 return E_NOTIMPL; 311 } 312 313 HRESULT STDMETHODCALLTYPE CDockSite::RequestBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw) 314 { 315 return E_NOTIMPL; 316 } 317 318 HRESULT STDMETHODCALLTYPE CDockSite::SetBorderSpaceDW(IUnknown* punkObj, LPCBORDERWIDTHS pbw) 319 { 320 return E_NOTIMPL; 321 } 322 323 HRESULT STDMETHODCALLTYPE CDockSite::OnFocusChangeIS (IUnknown *punkObj, BOOL fSetFocus) 324 { 325 return E_NOTIMPL; 326 } 327 328 HRESULT STDMETHODCALLTYPE CDockSite::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, 329 OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) 330 { 331 return E_NOTIMPL; 332 } 333 334 HRESULT STDMETHODCALLTYPE CDockSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, 335 VARIANT *pvaIn, VARIANT *pvaOut) 336 { 337 TCHAR textBuffer[40]; 338 REBARBANDINFOW bandInfo; 339 int index; 340 HRESULT hResult; 341 342 if (IsEqualIID(*pguidCmdGroup, CGID_DeskBand)) 343 { 344 switch (nCmdID) 345 { 346 case DBID_BANDINFOCHANGED: 347 if (fInitialized == false) 348 return S_OK; 349 if (V_VT(pvaIn) != VT_I4) 350 return E_INVALIDARG; 351 if (V_I4(pvaIn) != fBandID) 352 return E_FAIL; 353 // deskband information changed 354 // call GetBandInfo and refresh information in rebar 355 memset(&bandInfo, 0, sizeof(bandInfo)); 356 bandInfo.cbSize = sizeof(bandInfo); 357 bandInfo.lpText = textBuffer; 358 bandInfo.cch = sizeof(textBuffer) / sizeof(TCHAR); 359 hResult = GetRBBandInfo(bandInfo); 360 if (FAILED_UNEXPECTEDLY(hResult)) 361 return hResult; 362 index = (int)SendMessage(fRebarWindow, RB_IDTOINDEX, fBandID, 0); 363 SendMessage(fRebarWindow, RB_SETBANDINFOW, index, (LPARAM)&bandInfo); 364 return S_OK; 365 } 366 } 367 return E_FAIL; 368 } 369 370 HRESULT STDMETHODCALLTYPE CDockSite::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) 371 { 372 if (IsEqualIID(guidService, SID_SMenuBandParent)) 373 return this->QueryInterface(riid, ppvObject); 374 375 return fToolbar->QueryService(guidService, riid, ppvObject); 376 } 377 378 CMenuCallback::CMenuCallback() 379 { 380 } 381 382 CMenuCallback::~CMenuCallback() 383 { 384 } 385 386 static HRESULT BindToDesktop(LPCITEMIDLIST pidl, IShellFolder ** ppsfResult) 387 { 388 HRESULT hr; 389 CComPtr<IShellFolder> psfDesktop; 390 391 *ppsfResult = NULL; 392 393 hr = SHGetDesktopFolder(&psfDesktop); 394 if (FAILED(hr)) 395 return hr; 396 397 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, ppsfResult)); 398 399 return hr; 400 } 401 402 static HRESULT GetFavoritesFolder(IShellFolder ** ppsfFavorites, LPITEMIDLIST * ppidl) 403 { 404 HRESULT hr; 405 LPITEMIDLIST pidlUserFavorites; 406 LPITEMIDLIST pidlCommonFavorites; 407 CComPtr<IShellFolder> psfUserFavorites; 408 CComPtr<IShellFolder> psfCommonFavorites; 409 CComPtr<IAugmentedShellFolder> pasf; 410 411 if (ppsfFavorites) 412 *ppsfFavorites = NULL; 413 414 if (ppidl) 415 *ppidl = NULL; 416 417 hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidlUserFavorites); 418 if (FAILED(hr)) 419 { 420 WARN("Failed to get the USER favorites folder. Trying to run with just the COMMON one.\n"); 421 422 hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_FAVORITES, &pidlCommonFavorites); 423 if (FAILED_UNEXPECTEDLY(hr)) 424 return hr; 425 426 TRACE("COMMON favorites obtained.\n"); 427 *ppidl = pidlCommonFavorites; 428 hr = BindToDesktop(pidlCommonFavorites, ppsfFavorites); 429 return hr; 430 } 431 432 hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_FAVORITES, &pidlCommonFavorites); 433 if (FAILED_UNEXPECTEDLY(hr)) 434 { 435 WARN("Failed to get the COMMON favorites folder. Will use only the USER contents.\n"); 436 *ppidl = pidlCommonFavorites; 437 hr = BindToDesktop(pidlUserFavorites, ppsfFavorites); 438 return hr; 439 } 440 441 TRACE("Both COMMON and USER favorites folders obtained, merging them...\n"); 442 443 hr = BindToDesktop(pidlUserFavorites, &psfUserFavorites); 444 if (FAILED_UNEXPECTEDLY(hr)) 445 return hr; 446 447 hr = BindToDesktop(pidlCommonFavorites, &psfCommonFavorites); 448 if (FAILED_UNEXPECTEDLY(hr)) 449 return hr; 450 451 hr = CMergedFolder_CreateInstance(IID_PPV_ARG(IAugmentedShellFolder, &pasf)); 452 if (FAILED_UNEXPECTEDLY(hr)) 453 { 454 *ppsfFavorites = psfUserFavorites.Detach(); 455 *ppidl = pidlUserFavorites; 456 ILFree(pidlCommonFavorites); 457 return hr; 458 } 459 460 hr = pasf->AddNameSpace(NULL, psfUserFavorites, pidlUserFavorites, 0xFF00); 461 if (FAILED_UNEXPECTEDLY(hr)) 462 return hr; 463 464 hr = pasf->AddNameSpace(NULL, psfCommonFavorites, pidlCommonFavorites, 0); 465 if (FAILED_UNEXPECTEDLY(hr)) 466 return hr; 467 468 hr = pasf->QueryInterface(IID_PPV_ARG(IShellFolder, ppsfFavorites)); 469 pasf.Release(); 470 471 // TODO: obtain the folder's PIDL 472 473 ILFree(pidlCommonFavorites); 474 ILFree(pidlUserFavorites); 475 476 return hr; 477 } 478 479 HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, void **ppvObject) 480 { 481 CComPtr<IShellMenu> parentMenu; 482 CComPtr<IShellMenu> newMenu; 483 CComPtr<IShellFolder> favoritesFolder; 484 LPITEMIDLIST favoritesPIDL; 485 HWND ownerWindow; 486 HMENU parentHMenu; 487 HMENU favoritesHMenu; 488 HKEY orderRegKey; 489 DWORD disposition; 490 HRESULT hResult; 491 static const TCHAR szFavoritesKey[] = 492 _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Favorites"); 493 494 if (!IsEqualIID(riid, IID_IShellMenu)) 495 return E_FAIL; 496 if (psmd->uId != FCIDM_MENU_FAVORITES) 497 return E_FAIL; 498 499 // create favorites menu 500 hResult = psmd->punk->QueryInterface(IID_PPV_ARG(IShellMenu, &parentMenu)); 501 if (FAILED_UNEXPECTEDLY(hResult)) 502 return hResult; 503 hResult = parentMenu->GetMenu(&parentHMenu, &ownerWindow, NULL); 504 if (FAILED_UNEXPECTEDLY(hResult)) 505 return hResult; 506 favoritesHMenu = GetSubMenu(parentHMenu, 3); 507 if (favoritesHMenu == NULL) 508 return E_FAIL; 509 510 if (fFavoritesMenu.p == NULL) 511 { 512 hResult = CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu, &newMenu)); 513 if (FAILED_UNEXPECTEDLY(hResult)) 514 return hResult; 515 hResult = newMenu->Initialize(this, FCIDM_MENU_FAVORITES, -1, SMINIT_VERTICAL | SMINIT_CACHED); 516 if (FAILED_UNEXPECTEDLY(hResult)) 517 return hResult; 518 519 RegCreateKeyEx(HKEY_CURRENT_USER, szFavoritesKey, 520 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &orderRegKey, &disposition); 521 522 hResult = GetFavoritesFolder(&favoritesFolder, &favoritesPIDL); 523 if (FAILED_UNEXPECTEDLY(hResult)) 524 return hResult; 525 526 hResult = newMenu->SetShellFolder(favoritesFolder, favoritesPIDL, orderRegKey, SMSET_BOTTOM | SMINIT_CACHED | SMINV_ID); 527 if (favoritesPIDL) 528 ILFree(favoritesPIDL); 529 530 if (FAILED(hResult)) 531 return hResult; 532 533 fFavoritesMenu = newMenu; 534 } 535 536 hResult = fFavoritesMenu->SetMenu(favoritesHMenu, ownerWindow, SMSET_TOP | SMSET_DONTOWN); 537 if (FAILED_UNEXPECTEDLY(hResult)) 538 return hResult; 539 540 return fFavoritesMenu->QueryInterface(riid, ppvObject); 541 } 542 543 HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WPARAM wParam, LPARAM lParam) 544 { 545 switch (uMsg) 546 { 547 case SMC_INITMENU: 548 break; 549 case SMC_CREATE: 550 break; 551 case SMC_EXITMENU: 552 break; 553 case SMC_GETINFO: 554 { 555 SMINFO *infoPtr = reinterpret_cast<SMINFO *>(lParam); 556 if ((infoPtr->dwMask & SMIM_FLAGS) != 0) 557 { 558 if (psmd->uId == FCIDM_MENU_FAVORITES) 559 { 560 infoPtr->dwFlags |= SMIF_DROPCASCADE; 561 } 562 else 563 { 564 infoPtr->dwFlags |= SMIF_TRACKPOPUP; 565 } 566 } 567 if ((infoPtr->dwMask & SMIM_ICON) != 0) 568 infoPtr->iIcon = -1; 569 return S_OK; 570 } 571 case SMC_GETSFINFO: 572 break; 573 case SMC_GETOBJECT: 574 return GetObject(psmd, *reinterpret_cast<IID *>(wParam), reinterpret_cast<void **>(lParam)); 575 case SMC_GETSFOBJECT: 576 break; 577 case SMC_EXEC: 578 PostMessageW(psmd->hwnd, WM_COMMAND, psmd->uId, 0); 579 break; 580 case SMC_SFEXEC: 581 SHInvokeDefaultCommand(psmd->hwnd, psmd->psf, psmd->pidlItem); 582 break; 583 case SMC_SFSELECTITEM: 584 break; 585 case 13: 586 // return tooltip 587 break; 588 case SMC_REFRESH: 589 break; 590 case SMC_DEMOTE: 591 break; 592 case SMC_PROMOTE: 593 break; 594 case 0x13: 595 break; 596 case SMC_DEFAULTICON: 597 break; 598 case SMC_NEWITEM: 599 break; 600 case SMC_CHEVRONEXPAND: 601 break; 602 case SMC_DISPLAYCHEVRONTIP: 603 break; 604 case SMC_SETSFOBJECT: 605 break; 606 case SMC_SHCHANGENOTIFY: 607 break; 608 case SMC_CHEVRONGETTIP: 609 break; 610 case SMC_SFDDRESTRICTED: 611 break; 612 case 0x35: 613 break; 614 case 49: 615 break; 616 case 0x10000000: 617 break; 618 } 619 return S_FALSE; 620 } 621 622 CInternetToolbar::CInternetToolbar() 623 { 624 fMainReBar = NULL; 625 fMenuBandWindow = NULL; 626 fNavigationWindow = NULL; 627 fMenuCallback = new CComObject<CMenuCallback>(); 628 fToolbarWindow = NULL; 629 fAdviseCookie = 0; 630 pSettings = NULL; 631 fIgnoreChanges = FALSE; 632 } 633 634 CInternetToolbar::~CInternetToolbar() 635 { 636 } 637 638 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags) 639 { 640 CComPtr<CDockSite> newSite; 641 642 newSite = new CComObject<CDockSite>; 643 newSite->Initialize(newItem, this, fMainReBar, bandID, flags); 644 } 645 646 HRESULT CInternetToolbar::EnumBands(UINT Index, int *pBandId, IUnknown **ppUnkBand) 647 { 648 REBARBANDINFOW rbbi; 649 rbbi.cbSize = sizeof(rbbi); 650 rbbi.fMask = RBBIM_ID | RBBIM_LPARAM; 651 rbbi.cch = 0; 652 if (!::SendMessageW(fMainReBar, RB_GETBANDINFOW, Index, (LPARAM)&rbbi)) 653 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS); 654 *pBandId = rbbi.wID; 655 if (!rbbi.lParam) 656 return E_UNEXPECTED; 657 *ppUnkBand = ((CDockSite*)(rbbi.lParam))->GetContainedBand(); // Not ref. counted 658 return *ppUnkBand ? S_OK : S_FALSE; 659 } 660 661 HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight) 662 { 663 CComPtr<IDockingWindowSite> dockingWindowSite; 664 RECT availableBorderSpace; 665 666 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite)); 667 if (FAILED_UNEXPECTEDLY(hResult)) 668 return hResult; 669 hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace); 670 if (FAILED_UNEXPECTEDLY(hResult)) 671 return hResult; 672 673 if (maxHeight && availableBorderSpace.bottom - availableBorderSpace.top > maxHeight) 674 { 675 availableBorderSpace.bottom = availableBorderSpace.top + maxHeight; 676 } 677 678 return ResizeBorderDW(&availableBorderSpace, fSite, FALSE); 679 } 680 681 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar) 682 { 683 CComPtr<IShellMenu> menubar; 684 CComPtr<IShellMenuCallback> callback; 685 VARIANT menuOut; 686 HWND ownerWindow; 687 HRESULT hResult; 688 689 if (!pMenuBar) 690 return E_POINTER; 691 692 *pMenuBar = NULL; 693 694 hResult = CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu, &menubar)); 695 if (FAILED_UNEXPECTEDLY(hResult)) 696 return hResult; 697 698 hResult = fMenuCallback->QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback)); 699 if (FAILED_UNEXPECTEDLY(hResult)) 700 return hResult; 701 702 hResult = menubar->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL); 703 if (FAILED_UNEXPECTEDLY(hResult)) 704 return hResult; 705 706 // Set Menu 707 { 708 hResult = IUnknown_Exec(fSite, CGID_Explorer, 0x35, 0, NULL, &menuOut); 709 if (FAILED_UNEXPECTEDLY(hResult)) 710 return hResult; 711 712 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL) 713 return E_FAIL; 714 715 hResult = IUnknown_GetWindow(fSite, &ownerWindow); 716 if (FAILED_UNEXPECTEDLY(hResult)) 717 return hResult; 718 719 HMENU hMenuBar = (HMENU) V_INTREF(&menuOut); 720 721 // FIXME: Figure out the proper way to do this. 722 HMENU hMenuFavs = GetSubMenu(hMenuBar, 3); 723 if (hMenuFavs) 724 { 725 DeleteMenu(hMenuFavs, IDM_FAVORITES_EMPTY, MF_BYCOMMAND); 726 } 727 728 hResult = menubar->SetMenu(hMenuBar, ownerWindow, SMSET_DONTOWN); 729 if (FAILED_UNEXPECTEDLY(hResult)) 730 return hResult; 731 } 732 733 hResult = IUnknown_Exec(menubar, CGID_MenuBand, 3, 1, NULL, NULL); 734 if (FAILED_UNEXPECTEDLY(hResult)) 735 return hResult; 736 737 *pMenuBar = menubar.Detach(); 738 739 return S_OK; 740 } 741 742 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked) 743 { 744 if (locked != !!pSettings->fLocked) 745 { 746 pSettings->fLocked = (BOOL)locked; 747 pSettings->Save(); 748 RefreshLockedToolbarState(); 749 } 750 return S_OK; 751 } 752 753 void CInternetToolbar::RefreshLockedToolbarState() 754 { 755 REBARBANDINFOW rebarBandInfo; 756 int bandCount; 757 CDockSite *dockSite; 758 759 rebarBandInfo.cbSize = sizeof(rebarBandInfo); 760 rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM; 761 bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0); 762 for (INT x = 0; x < bandCount; x++) 763 { 764 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo); 765 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam); 766 if (dockSite != NULL) 767 { 768 rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS); 769 if ((dockSite->fFlags & CDockSite::ITF_NOGRIPPER) || pSettings->fLocked) 770 rebarBandInfo.fStyle |= RBBS_NOGRIPPER; 771 if ((dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS) && !pSettings->fLocked) 772 rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS; 773 SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo); 774 } 775 } 776 ReserveBorderSpace(0); 777 } 778 779 HRESULT CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd) 780 { 781 long state = 0; 782 if (pcmd->cmdf & OLECMDF_ENABLED) 783 state |= TBSTATE_ENABLED; 784 if (pcmd->cmdf & OLECMDF_LATCHED) 785 state |= TBSTATE_CHECKED; 786 return SetState(pguidCmdGroup, commandID, state); 787 } 788 789 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID) 790 { 791 HRESULT hResult; 792 793 hResult = S_OK; 794 switch (commandID) 795 { 796 case -1: 797 // loop through buttons 798 //for buttons in CLSID_CommonButtons 799 // if up, QueryStatus for up state and update it 800 // 801 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget 802 803 OLECMD commandList[4]; 804 commandList[0].cmdID = 0x1c; 805 commandList[1].cmdID = 0x1d; 806 commandList[2].cmdID = 0x1e; 807 commandList[3].cmdID = 0x23; 808 IUnknown_QueryStatus(fSite, CGID_Explorer, 4, commandList, NULL); 809 SetState(&CLSID_CommonButtons, gSearchCommandID, &commandList[0]); 810 SetState(&CLSID_CommonButtons, gFoldersCommandID, &commandList[3]); 811 //SetState(&CLSID_CommonButtons, gFavoritesCommandID, &commandList[2]); 812 //SetState(&CLSID_CommonButtons, gHistoryCommandID, &commandList[1]); 813 814 break; 815 case 1: 816 // forward 817 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0); 818 break; 819 case 2: 820 // back 821 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0); 822 break; 823 case 3: 824 // up 825 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_UPONELEVEL, newValue ? TBSTATE_ENABLED : 0); 826 break; 827 } 828 return hResult; 829 } 830 831 HRESULT CInternetToolbar::CreateAndInitBandProxy() 832 { 833 CComPtr<IServiceProvider> serviceProvider; 834 HRESULT hResult; 835 836 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider)); 837 if (FAILED_UNEXPECTEDLY(hResult)) 838 return hResult; 839 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy)); 840 if (FAILED_UNEXPECTEDLY(hResult)) 841 { 842 hResult = CBandProxy_CreateInstance(IID_PPV_ARG(IBandProxy, &fBandProxy)); 843 if (FAILED_UNEXPECTEDLY(hResult)) 844 return hResult; 845 hResult = fBandProxy->SetSite(fSite); 846 if (FAILED_UNEXPECTEDLY(hResult)) 847 return hResult; 848 } 849 return S_OK; 850 } 851 852 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg) 853 { 854 return E_NOTIMPL; 855 } 856 857 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO() 858 { 859 HRESULT hr = S_FALSE; 860 861 if (fMenuBar) 862 hr = IUnknown_HasFocusIO(fMenuBar); 863 if (hr != S_FALSE) 864 return hr; 865 866 if (fControlsBar) 867 hr = IUnknown_HasFocusIO(fControlsBar); 868 if (hr != S_FALSE) 869 return hr; 870 871 if (fNavigationBar) 872 hr = IUnknown_HasFocusIO(fNavigationBar); 873 if (hr != S_FALSE) 874 return hr; 875 876 return S_FALSE; 877 } 878 879 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg) 880 { 881 HRESULT hr = S_FALSE; 882 883 if (fMenuBar) 884 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg); 885 if (hr == S_OK) 886 return hr; 887 888 if (fControlsBar) 889 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg); 890 if (hr == S_OK) 891 return hr; 892 893 if (fNavigationBar) 894 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg); 895 if (hr == S_OK) 896 return hr; 897 898 return S_FALSE; 899 } 900 901 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd) 902 { 903 if (lphwnd == NULL) 904 return E_POINTER; 905 *lphwnd = m_hWnd; 906 return S_OK; 907 } 908 909 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode) 910 { 911 return E_NOTIMPL; 912 } 913 914 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow) 915 { 916 HRESULT hResult; 917 918 // show the bar here 919 if (fShow) 920 { 921 hResult = ReserveBorderSpace(); 922 if (FAILED_UNEXPECTEDLY(hResult)) 923 return hResult; 924 } 925 926 // TODO: Why should showing the IDockingWindow change all bands? Related to CORE-17236 and CORE-19659. 927 int id; 928 IUnknown *pUnk; 929 for (UINT i = 0; SUCCEEDED(EnumBands(i, &id, &pUnk)); ++i) 930 { 931 if (!pUnk) 932 continue; 933 BOOL visible = fShow && IsBandVisible(id) != S_FALSE; 934 hResult = IUnknown_ShowDW(pUnk, visible); 935 FAILED_UNEXPECTEDLY(hResult); 936 } 937 return S_OK; 938 } 939 940 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved) 941 { 942 HRESULT hResult; 943 944 if (fMenuBar) 945 { 946 hResult = IUnknown_CloseDW(fMenuBar, dwReserved); 947 if (FAILED_UNEXPECTEDLY(hResult)) 948 return hResult; 949 ReleaseCComPtrExpectZero(fMenuBar); 950 } 951 if (fControlsBar) 952 { 953 hResult = IUnknown_CloseDW(fControlsBar, dwReserved); 954 if (FAILED_UNEXPECTEDLY(hResult)) 955 return hResult; 956 ReleaseCComPtrExpectZero(fControlsBar); 957 } 958 if (fNavigationBar) 959 { 960 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved); 961 if (FAILED_UNEXPECTEDLY(hResult)) 962 return hResult; 963 ReleaseCComPtrExpectZero(fNavigationBar); 964 } 965 if (fLogoBar) 966 { 967 hResult = IUnknown_CloseDW(fLogoBar, dwReserved); 968 if (FAILED_UNEXPECTEDLY(hResult)) 969 return hResult; 970 ReleaseCComPtrExpectZero(fLogoBar); 971 } 972 973 SetSite(NULL); 974 return S_OK; 975 } 976 977 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder, 978 IUnknown *punkToolbarSite, BOOL fReserved) 979 { 980 RECT neededBorderSpace; 981 RECT availableBorderSpace = *prcBorder; 982 983 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace)); 984 985 // RBSTR_CHANGERECT does not seem to set the proper size in the rect. 986 // Let's make sure we fetch the actual size properly. 987 ::GetWindowRect(fMainReBar, &availableBorderSpace); 988 neededBorderSpace.left = 0; 989 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top; 990 if (!pSettings->fLocked) 991 neededBorderSpace.top += 3; 992 neededBorderSpace.right = 0; 993 neededBorderSpace.bottom = 0; 994 995 CComPtr<IDockingWindowSite> dockingWindowSite; 996 997 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite)); 998 if (FAILED_UNEXPECTEDLY(hResult)) 999 return hResult; 1000 1001 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace); 1002 if (FAILED_UNEXPECTEDLY(hResult)) 1003 return hResult; 1004 1005 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace); 1006 if (FAILED_UNEXPECTEDLY(hResult)) 1007 return hResult; 1008 1009 return S_OK; 1010 } 1011 1012 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID) 1013 { 1014 if (pClassID == NULL) 1015 return E_POINTER; 1016 *pClassID = CLSID_InternetToolbar; 1017 return S_OK; 1018 } 1019 1020 HRESULT CInternetToolbar::SetDirty() 1021 { 1022 if (fIgnoreChanges) 1023 return S_OK; 1024 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_NOTIFYITBARDIRTY, 0, NULL, NULL); 1025 return S_OK; 1026 } 1027 1028 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty() 1029 { 1030 return E_NOTIMPL; 1031 } 1032 1033 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm) 1034 { 1035 fIgnoreChanges = TRUE; 1036 HRESULT hr = InitNew(); 1037 ITBARSTATE state; 1038 if (SUCCEEDED(hr)) 1039 { 1040 hr = S_FALSE; 1041 ULONG cb = sizeof(state); 1042 if (pStm->Read(&state, cb, &cb) == S_OK && state.Signature == state.SIG) 1043 { 1044 SetBandVisibility(ITBBID_MENUBAND, state.Menubar); 1045 SetBandVisibility(ITBBID_TOOLSBAND, state.StdToolbar); 1046 SetBandVisibility(ITBBID_ADDRESSBAND, state.Addressbar); 1047 //SetBandVisibility(ITBBID_?, state.Linksbar); 1048 //SetBandVisibility(ITBBID_?, state.Throbber); 1049 hr = S_OK; 1050 } 1051 } 1052 fIgnoreChanges = FALSE; 1053 return hr; 1054 } 1055 1056 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty) 1057 { 1058 ITBARSTATE state = { sizeof(state), state.SIG }; 1059 state.Menubar = IsBandVisible(ITBBID_MENUBAND) == S_OK; 1060 state.StdToolbar = IsBandVisible(ITBBID_TOOLSBAND) == S_OK; 1061 state.Addressbar = IsBandVisible(ITBBID_ADDRESSBAND) == S_OK; 1062 state.Linksbar = FALSE; 1063 return pStm->Write(&state, sizeof(state), NULL); 1064 } 1065 1066 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize) 1067 { 1068 return E_NOTIMPL; 1069 } 1070 1071 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew() 1072 { 1073 CComPtr<IShellMenu> menuBar; 1074 CComPtr<IUnknown> logoBar; 1075 CComPtr<IUnknown> toolsBar; 1076 CComPtr<IUnknown> navigationBar; 1077 HRESULT hResult; 1078 1079 /* Create and attach the menubar to the rebar */ 1080 hResult = CreateMenuBar(&menuBar); 1081 if (FAILED_UNEXPECTEDLY(hResult)) 1082 return hResult; 1083 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1084 1085 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow); 1086 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count 1087 1088 // FIXME: The ROS Rebar does not properly support fixed-size items such as the brandband, 1089 // and it will put them in their own row, sized to take up the whole row. 1090 #if 0 1091 /* Create and attach the brand/logo to the rebar */ 1092 hResult = CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown, &logoBar)); 1093 if (FAILED_UNEXPECTEDLY(hResult)) 1094 return hResult; 1095 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE); 1096 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count 1097 #endif 1098 1099 /* Create and attach the standard toolbar to the rebar */ 1100 hResult = CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown, &toolsBar)); 1101 if (FAILED_UNEXPECTEDLY(hResult)) 1102 return hResult; 1103 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1104 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count 1105 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow); 1106 if (FAILED_UNEXPECTEDLY(hResult)) 1107 return hResult; 1108 1109 /* Create and attach the address/navigation toolbar to the rebar */ 1110 hResult = CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown, &navigationBar)); 1111 if (FAILED_UNEXPECTEDLY(hResult)) 1112 return hResult; 1113 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1114 fNavigationBar.Attach(navigationBar.Detach()); 1115 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow); 1116 1117 return S_OK; 1118 } 1119 1120 HRESULT CInternetToolbar::IsBandVisible(int BandID) 1121 { 1122 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0); 1123 1124 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE}; 1125 SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo); 1126 1127 return (bandInfo.fStyle & RBBS_HIDDEN) ? S_FALSE : S_OK; 1128 } 1129 1130 HRESULT CInternetToolbar::SetBandVisibility(int BandID, int Show) 1131 { 1132 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0); 1133 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE | RBBIM_CHILD}; 1134 if (!SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo)) 1135 return E_FAIL; 1136 1137 if (Show < 0) 1138 bandInfo.fStyle ^= RBBS_HIDDEN; // Toggle 1139 else if (Show) 1140 bandInfo.fStyle &= ~RBBS_HIDDEN; 1141 else 1142 bandInfo.fStyle |= RBBS_HIDDEN; 1143 1144 bandInfo.fMask &= ~RBBIM_CHILD; 1145 ::ShowWindow(bandInfo.hwndChild, (bandInfo.fStyle & RBBS_HIDDEN) ? SW_HIDE : SW_SHOW); // CORE-17236 1146 SendMessage(fMainReBar, RB_SETBANDINFOW, index, (LPARAM)&bandInfo); 1147 1148 ReserveBorderSpace(0); 1149 SetDirty(); 1150 return S_OK; 1151 } 1152 1153 HRESULT CInternetToolbar::ToggleBandVisibility(int BandID) 1154 { 1155 return SetBandVisibility(BandID, -1); 1156 } 1157 1158 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup, 1159 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) 1160 { 1161 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands)) 1162 { 1163 while (cCmds != 0) 1164 { 1165 switch (prgCmds->cmdID) 1166 { 1167 case ITID_TEXTLABELS: // Text Labels state 1168 prgCmds->cmdf = OLECMDF_SUPPORTED; 1169 break; 1170 case ITID_TOOLBARBANDSHOWN: // toolbar visibility 1171 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1172 if (IsBandVisible(ITBBID_TOOLSBAND) == S_OK) 1173 prgCmds->cmdf |= OLECMDF_LATCHED; 1174 break; 1175 case ITID_ADDRESSBANDSHOWN: // address bar visibility 1176 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1177 if (IsBandVisible(ITBBID_ADDRESSBAND) == S_OK) 1178 prgCmds->cmdf |= OLECMDF_LATCHED; 1179 break; 1180 case ITID_LINKSBANDSHOWN: // links bar visibility 1181 prgCmds->cmdf = 0; 1182 break; 1183 case ITID_MENUBANDSHOWN: // Menubar band visibility 1184 prgCmds->cmdf = OLECMDF_SUPPORTED; 1185 if (fMenuBar) 1186 prgCmds->cmdf |= OLECMDF_LATCHED; 1187 break; 1188 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled 1189 prgCmds->cmdf = 0; 1190 break; 1191 case ITID_CUSTOMIZEENABLED: // customize enabled 1192 prgCmds->cmdf = OLECMDF_SUPPORTED; 1193 break; 1194 case ITID_TOOLBARLOCKED: // lock toolbars 1195 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1196 if (pSettings->fLocked) 1197 prgCmds->cmdf |= OLECMDF_LATCHED; 1198 break; 1199 default: 1200 prgCmds->cmdf = 0; 1201 break; 1202 } 1203 prgCmds++; 1204 cCmds--; 1205 } 1206 return S_OK; 1207 } 1208 return E_FAIL; 1209 } 1210 1211 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, 1212 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) 1213 { 1214 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands)) 1215 { 1216 switch (nCmdID) 1217 { 1218 case 1: 1219 // what do I do here? 1220 return S_OK; 1221 case ITID_TEXTLABELS: 1222 // toggle text labels 1223 return S_OK; 1224 case ITID_TOOLBARBANDSHOWN: 1225 return ToggleBandVisibility(ITBBID_TOOLSBAND); 1226 case ITID_ADDRESSBANDSHOWN: 1227 return ToggleBandVisibility(ITBBID_ADDRESSBAND); 1228 case ITID_LINKSBANDSHOWN: 1229 // toggle links band visibility 1230 return S_OK; 1231 case ITID_CUSTOMIZEENABLED: 1232 // run customize 1233 return S_OK; 1234 case ITID_TOOLBARLOCKED: 1235 return LockUnlockToolbars(!pSettings->fLocked); 1236 } 1237 } 1238 return E_FAIL; 1239 } 1240 1241 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo) 1242 { 1243 return E_NOTIMPL; 1244 } 1245 1246 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) 1247 { 1248 return E_NOTIMPL; 1249 } 1250 1251 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, 1252 LCID lcid, DISPID *rgDispId) 1253 { 1254 return E_NOTIMPL; 1255 } 1256 1257 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, 1258 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 1259 { 1260 HRESULT hResult; 1261 1262 switch(dispIdMember) 1263 { 1264 case DISPID_BEFORENAVIGATE: 1265 hResult = S_OK; 1266 break; 1267 case DISPID_DOWNLOADCOMPLETE: 1268 hResult = S_OK; 1269 break; 1270 case DISPID_COMMANDSTATECHANGE: 1271 if (pDispParams->cArgs != 2) 1272 return E_INVALIDARG; 1273 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4) 1274 return E_INVALIDARG; 1275 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE, 1276 V_I4(&pDispParams->rgvarg[1])); 1277 case DISPID_DOWNLOADBEGIN: 1278 hResult = S_OK; 1279 break; 1280 case DISPID_NAVIGATECOMPLETE2: 1281 hResult = S_OK; 1282 break; 1283 case DISPID_DOCUMENTCOMPLETE: 1284 hResult = S_OK; 1285 break; 1286 } 1287 return S_OK; 1288 } 1289 1290 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14) 1291 { 1292 HRESULT hResult; 1293 1294 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14); 1295 1296 fCommandTarget.Release(); 1297 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget)); 1298 if (FAILED_UNEXPECTEDLY(hResult)) 1299 return hResult; 1300 fCommandCategory = *category; 1301 return S_OK; 1302 } 1303 1304 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1() 1305 { 1306 return E_NOTIMPL; 1307 } 1308 1309 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons) 1310 { 1311 return E_NOTIMPL; 1312 } 1313 1314 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup, 1315 HINSTANCE param10, LPCTSTR param14, long *param18) 1316 { 1317 long result; 1318 1319 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW, 1320 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14)); 1321 *param18 = result; 1322 if (result == -1) 1323 return E_FAIL; 1324 return S_OK; 1325 } 1326 1327 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14) 1328 { 1329 return E_NOTIMPL; 1330 } 1331 1332 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState) 1333 { 1334 if (theState == NULL) 1335 return E_POINTER; 1336 // map the command id 1337 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0); 1338 return S_OK; 1339 } 1340 1341 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState) 1342 { 1343 // map the command id 1344 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0)); 1345 return S_OK; 1346 } 1347 1348 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount, 1349 TBADDBITMAP *lParam, long *newIndex, COLORREF param20) 1350 { 1351 return E_NOTIMPL; 1352 } 1353 1354 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC) 1355 { 1356 if (paramC == NULL) 1357 return E_POINTER; 1358 *paramC = MAKELONG(24, 24); 1359 return S_OK; 1360 } 1361 1362 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg, 1363 WPARAM wParam, LPARAM lParam, LRESULT *result) 1364 { 1365 if (fToolbarWindow) 1366 { 1367 LRESULT res = ::SendMessageW(fToolbarWindow, uMsg, wParam, lParam); 1368 if (result) 1369 *result = res; 1370 return S_OK; 1371 } 1372 return E_NOTIMPL; 1373 } 1374 1375 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10, 1376 HIMAGELIST param14, HIMAGELIST param18) 1377 { 1378 return E_NOTIMPL; 1379 } 1380 1381 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14) 1382 { 1383 return E_NOTIMPL; 1384 } 1385 1386 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 1387 { 1388 return E_NOTIMPL; 1389 } 1390 1391 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite) 1392 { 1393 CComPtr<IBrowserService> browserService; 1394 HWND ownerWindow; 1395 HWND dockContainer; 1396 HRESULT hResult; 1397 1398 if (pUnkSite == NULL) 1399 { 1400 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie); 1401 ::DestroyWindow(fMainReBar); 1402 DestroyWindow(); 1403 fSite.Release(); 1404 } 1405 else 1406 { 1407 // get window handle of owner 1408 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow); 1409 if (FAILED_UNEXPECTEDLY(hResult)) 1410 return hResult; 1411 if (ownerWindow == NULL) 1412 return E_FAIL; 1413 1414 // Get settings from owner window 1415 ::SendMessageW(ownerWindow, BWM_GETSETTINGSPTR, 0, (LPARAM)&pSettings); 1416 1417 // create dock container 1418 fSite = pUnkSite; 1419 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0, 1420 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0); 1421 if (dockContainer == NULL) 1422 return E_FAIL; 1423 SubclassWindow(dockContainer); 1424 1425 // create rebar in dock container 1426 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | 1427 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE | 1428 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP; 1429 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW; 1430 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style, 1431 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL); 1432 if (fMainReBar == NULL) 1433 return E_FAIL; 1434 1435 // take advice to watch events 1436 hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1437 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie); 1438 } 1439 return S_OK; 1440 } 1441 1442 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite) 1443 { 1444 if (ppvSite == NULL) 1445 return E_POINTER; 1446 if (fSite.p != NULL) 1447 return fSite->QueryInterface(riid, ppvSite); 1448 *ppvSite = NULL; 1449 return S_OK; 1450 } 1451 1452 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) 1453 { 1454 HRESULT hResult; 1455 1456 if (IsEqualIID(guidService, IID_IBandSite)) 1457 return this->QueryInterface(riid, ppvObject); 1458 if (IsEqualIID(guidService, SID_IBandProxy)) 1459 { 1460 if (fBandProxy.p == NULL) 1461 { 1462 hResult = CreateAndInitBandProxy(); 1463 if (FAILED_UNEXPECTEDLY(hResult)) 1464 return hResult; 1465 } 1466 return fBandProxy->QueryInterface(riid, ppvObject); 1467 } 1468 return IUnknown_QueryService(fSite, guidService, riid, ppvObject); 1469 } 1470 1471 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent( 1472 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) 1473 { 1474 HRESULT hResult; 1475 1476 if (fMenuBar) 1477 { 1478 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult); 1479 if (hResult != S_FALSE) 1480 return hResult; 1481 } 1482 1483 if (fNavigationBar) 1484 { 1485 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult); 1486 if (hResult != S_FALSE) 1487 return hResult; 1488 } 1489 1490 if (fLogoBar) 1491 { 1492 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult); 1493 if (hResult != S_FALSE) 1494 return hResult; 1495 } 1496 1497 return S_FALSE; 1498 } 1499 1500 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd) 1501 { 1502 UNIMPLEMENTED; 1503 return E_NOTIMPL; 1504 } 1505 1506 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk) 1507 { 1508 UNIMPLEMENTED; 1509 return E_NOTIMPL; 1510 } 1511 1512 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID) 1513 { 1514 if (uBand == ~0ul) 1515 return ::SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0); 1516 int id; 1517 IUnknown *pUnkUnused; 1518 HRESULT hr = EnumBands(uBand, &id, &pUnkUnused); 1519 if (SUCCEEDED(hr)) 1520 *pdwBandID = id; 1521 return hr; 1522 } 1523 1524 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID, 1525 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName) 1526 { 1527 if (ppstb == NULL) 1528 return E_POINTER; 1529 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL) 1530 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb)); 1531 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL) 1532 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb)); 1533 *ppstb = NULL; 1534 return E_FAIL; 1535 } 1536 1537 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState) 1538 { 1539 UNIMPLEMENTED; 1540 return E_NOTIMPL; 1541 } 1542 1543 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID) 1544 { 1545 UNIMPLEMENTED; 1546 return E_NOTIMPL; 1547 } 1548 1549 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv) 1550 { 1551 UNIMPLEMENTED; 1552 return E_NOTIMPL; 1553 } 1554 1555 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo) 1556 { 1557 UNIMPLEMENTED; 1558 return E_NOTIMPL; 1559 } 1560 1561 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo) 1562 { 1563 UNIMPLEMENTED; 1564 return E_NOTIMPL; 1565 } 1566 1567 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1568 { 1569 CComPtr<IWebBrowser> webBrowser; 1570 HRESULT hResult; 1571 1572 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser)); 1573 if (FAILED_UNEXPECTEDLY(hResult)) 1574 return 0; 1575 hResult = webBrowser->GoBack(); 1576 return 1; 1577 } 1578 1579 LRESULT CInternetToolbar::OnTravelForward(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1580 { 1581 CComPtr<IWebBrowser> webBrowser; 1582 HRESULT hResult; 1583 1584 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser)); 1585 if (FAILED_UNEXPECTEDLY(hResult)) 1586 return 0; 1587 hResult = webBrowser->GoForward(); 1588 return 1; 1589 } 1590 1591 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1592 { 1593 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL); 1594 return 1; 1595 } 1596 1597 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1598 { 1599 IUnknown_Exec(fSite, CGID_Explorer, 0x1c, 1, NULL, NULL); 1600 return 1; 1601 } 1602 1603 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1604 { 1605 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL); 1606 return 1; 1607 } 1608 1609 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1610 { 1611 HRESULT hResult; 1612 1613 if (fCommandTarget.p != NULL) 1614 { 1615 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL); 1616 if (FAILED(hResult)) 1617 { 1618 ::SendMessageW(::GetParent(m_hWnd), WM_COMMAND, wID, 0); 1619 } 1620 } 1621 return 1; 1622 } 1623 1624 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1625 { 1626 CComPtr<IBrowserService> browserService; 1627 CComPtr<IOleCommandTarget> commandTarget; 1628 CComPtr<ITravelLog> travelLog; 1629 NMTOOLBARW *notifyInfo; 1630 RECT bounds; 1631 HMENU newMenu; 1632 TPMPARAMS params; 1633 int selectedItem; 1634 VARIANT parmIn; 1635 OLECMD commandInfo; 1636 HRESULT hResult; 1637 wchar_t templateString[200]; 1638 1639 notifyInfo = (NMTOOLBARW *)pNMHDR; 1640 if (notifyInfo->hdr.hwndFrom != fToolbarWindow) 1641 { 1642 // not from the toolbar, keep looking for a message handler 1643 bHandled = FALSE; 1644 return 0; 1645 } 1646 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds)); 1647 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2); 1648 switch (notifyInfo->iItem) 1649 { 1650 case IDM_GOTO_BACK: 1651 newMenu = CreatePopupMenu(); 1652 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1653 hResult = browserService->GetTravelLog(&travelLog); 1654 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK); 1655 commandInfo.cmdID = 0x1d; 1656 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL); 1657 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED && 1658 travelLog->CountEntries(browserService) > 1) 1659 { 1660 AppendMenuW(newMenu, MF_SEPARATOR, -1, L""); 1661 1662 if (LoadStringW(_AtlBaseModule.GetResourceInstance(), 1663 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0) 1664 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H"); 1665 1666 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString); 1667 } 1668 params.cbSize = sizeof(params); 1669 params.rcExclude = bounds; 1670 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, 1671 bounds.left, bounds.bottom, m_hWnd, ¶ms); 1672 if (selectedItem == IDM_EXPLORERBAR_HISTORY) 1673 { 1674 V_VT(&parmIn) = VT_I4; 1675 V_I4(&parmIn) = 1; 1676 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL); 1677 } 1678 else if (selectedItem != 0) 1679 hResult = travelLog->Travel(browserService, -selectedItem); 1680 DestroyMenu(newMenu); 1681 break; 1682 case IDM_GOTO_FORWARD: 1683 newMenu = CreatePopupMenu(); 1684 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1685 hResult = browserService->GetTravelLog(&travelLog); 1686 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE); 1687 commandInfo.cmdID = 0x1d; 1688 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL); 1689 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED && 1690 travelLog->CountEntries(browserService) > 1) 1691 { 1692 AppendMenuW(newMenu, MF_SEPARATOR, -1, L""); 1693 1694 if (LoadStringW(_AtlBaseModule.GetResourceInstance(), 1695 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0) 1696 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H"); 1697 1698 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString); 1699 } 1700 params.cbSize = sizeof(params); 1701 params.rcExclude = bounds; 1702 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, 1703 bounds.left, bounds.bottom, m_hWnd, ¶ms); 1704 if (selectedItem == IDM_EXPLORERBAR_HISTORY) 1705 { 1706 V_VT(&parmIn) = VT_I4; 1707 V_I4(&parmIn) = 1; 1708 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL); 1709 } 1710 else if (selectedItem != 0) 1711 hResult = travelLog->Travel(browserService, selectedItem); 1712 DestroyMenu(newMenu); 1713 break; 1714 case gViewsCommandID: 1715 VARIANT inValue; 1716 CComVariant outValue; 1717 HRESULT hResult; 1718 1719 V_VT(&inValue) = VT_INT_PTR; 1720 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds); 1721 1722 if (fCommandTarget.p != NULL) 1723 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue); 1724 // pvaOut is VT_I4 with value 0x403 1725 break; 1726 } 1727 return TBDDRET_DEFAULT; 1728 } 1729 1730 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1731 { 1732 return 1; 1733 } 1734 1735 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1736 { 1737 return 1; 1738 } 1739 1740 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1741 { 1742 HMENU contextMenuBar; 1743 HMENU contextMenu; 1744 POINT clickLocation; 1745 int command; 1746 RBHITTESTINFO hitTestInfo; 1747 REBARBANDINFOW rebarBandInfo; 1748 int bandID; 1749 1750 clickLocation.x = LOWORD(lParam); 1751 clickLocation.y = HIWORD(lParam); 1752 hitTestInfo.pt = clickLocation; 1753 ScreenToClient(&hitTestInfo.pt); 1754 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo); 1755 if (hitTestInfo.iBand == -1) 1756 return 0; 1757 1758 rebarBandInfo.cbSize = sizeof(rebarBandInfo); 1759 rebarBandInfo.fMask = RBBIM_ID; 1760 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo); 1761 bandID = rebarBandInfo.wID; 1762 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU)); 1763 contextMenu = GetSubMenu(contextMenuBar, 0); 1764 switch (bandID) 1765 { 1766 case ITBBID_MENUBAND: // menu band 1767 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1768 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1769 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1770 break; 1771 case ITBBID_BRANDBAND: // brand band 1772 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1773 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1774 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1775 break; 1776 case ITBBID_TOOLSBAND: // tools band 1777 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1778 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1779 break; 1780 case ITBBID_ADDRESSBAND: // navigation band 1781 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1782 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1783 break; 1784 default: 1785 break; 1786 } 1787 1788 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE); 1789 1790 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, IsBandVisible(ITBBID_TOOLSBAND) == S_OK); 1791 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, IsBandVisible(ITBBID_ADDRESSBAND) == S_OK); 1792 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE); 1793 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE); 1794 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, pSettings->fLocked); 1795 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, pSettings->fShowGoButton); 1796 1797 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment 1798 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, 1799 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL); 1800 switch (command) 1801 { 1802 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons 1803 ToggleBandVisibility(ITBBID_TOOLSBAND); 1804 break; 1805 case IDM_TOOLBARS_ADDRESSBAR: // address bar 1806 ToggleBandVisibility(ITBBID_ADDRESSBAND); 1807 break; 1808 case IDM_TOOLBARS_LINKSBAR: // links 1809 break; 1810 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars 1811 LockUnlockToolbars(!pSettings->fLocked); 1812 break; 1813 case IDM_TOOLBARS_CUSTOMIZE: // customize 1814 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0); 1815 break; 1816 case IDM_TOOLBARS_GOBUTTON: 1817 SendMessage(fNavigationWindow, WM_COMMAND, IDM_TOOLBARS_GOBUTTON, 0); 1818 break; 1819 } 1820 1821 DestroyMenu(contextMenuBar); 1822 return 1; 1823 } 1824 1825 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1826 { 1827 if (wParam != SIZE_MINIMIZED) 1828 { 1829 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), 1830 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE); 1831 } 1832 return 1; 1833 } 1834 1835 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1836 { 1837 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd) 1838 { 1839 bHandled = FALSE; 1840 return 0; 1841 } 1842 SetCursor(LoadCursor(NULL, IDC_SIZENS)); 1843 return 1; 1844 } 1845 1846 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1847 { 1848 CComPtr<IBrowserService> browserService; 1849 CComPtr<ITravelLog> travelLog; 1850 TOOLTIPTEXTW *pTTTW; 1851 UINT nID; 1852 HRESULT hResult; 1853 wchar_t tempString[300]; 1854 1855 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR); 1856 if ((pTTTW->uFlags & TTF_IDISHWND) != 0) 1857 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom); 1858 else 1859 nID = (UINT)pNMHDR->idFrom; 1860 1861 if (nID != 0) 1862 { 1863 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD) 1864 { 1865 // TODO: Should this call QueryService? 1866 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService)); 1867 hResult = browserService->GetTravelLog(&travelLog); 1868 hResult = travelLog->GetToolTipText(browserService, 1869 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE, 1870 0, tempString, 299); 1871 if (FAILED_UNEXPECTEDLY(hResult)) 1872 { 1873 bHandled = FALSE; 1874 return 0; 1875 } 1876 } 1877 else 1878 tempString[0] = 0; 1879 wcsncpy (pTTTW->szText, tempString, sizeof(pTTTW->szText) / sizeof(wchar_t)); 1880 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0, 1881 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); 1882 return 0; 1883 } 1884 return 0; 1885 } 1886 1887 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1888 { 1889 LRESULT theResult; 1890 HRESULT hResult; 1891 1892 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult); 1893 1894 bHandled = hResult == S_OK; 1895 1896 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult; 1897 } 1898 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1899 { 1900 NMHDR *notifyHeader; 1901 LRESULT theResult; 1902 HRESULT hResult; 1903 1904 notifyHeader = reinterpret_cast<NMHDR *>(lParam); 1905 1906 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult); 1907 1908 bHandled = hResult == S_OK; 1909 1910 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult; 1911 } 1912 1913 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1914 { 1915 bHandled = FALSE; 1916 if (pSettings->fLocked) 1917 return 0; 1918 1919 if (wParam & MK_CONTROL) 1920 return 0; 1921 1922 fSizing = TRUE; 1923 1924 DWORD msgp = GetMessagePos(); 1925 1926 fStartPosition.x = GET_X_LPARAM(msgp); 1927 fStartPosition.y = GET_Y_LPARAM(msgp); 1928 1929 RECT rc; 1930 GetWindowRect(&rc); 1931 1932 fStartHeight = rc.bottom - rc.top; 1933 1934 SetCapture(); 1935 1936 bHandled = TRUE; 1937 return 0; 1938 } 1939 1940 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1941 { 1942 bHandled = FALSE; 1943 if (!fSizing) 1944 return 0; 1945 1946 DWORD msgp = GetMessagePos(); 1947 1948 POINT pt; 1949 pt.x = GET_X_LPARAM(msgp); 1950 pt.y = GET_Y_LPARAM(msgp); 1951 1952 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y); 1953 1954 bHandled = TRUE; 1955 return 0; 1956 } 1957 1958 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1959 { 1960 bHandled = FALSE; 1961 if (!fSizing) 1962 return 0; 1963 1964 OnMouseMove(uMsg, wParam, lParam, bHandled); 1965 1966 fSizing = FALSE; 1967 1968 ReleaseCapture(); 1969 1970 return 0; 1971 } 1972 1973 LRESULT CInternetToolbar::OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1974 { 1975 HRESULT hr; 1976 HWND hwndMenu; 1977 1978 hr = IUnknown_GetWindow(fMenuBar, &hwndMenu); 1979 if (FAILED_UNEXPECTEDLY(hr)) 1980 return 0; 1981 1982 CComPtr<IWinEventHandler> menuWinEventHandler; 1983 hr = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler)); 1984 if (FAILED_UNEXPECTEDLY(hr)) 1985 return 0; 1986 1987 LRESULT lres; 1988 hr = menuWinEventHandler->OnWinEvent(hwndMenu, uMsg, wParam, lParam, &lres); 1989 if (FAILED_UNEXPECTEDLY(hr)) 1990 return 0; 1991 1992 return lres; 1993 } 1994 1995 LRESULT CInternetToolbar::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 1996 { 1997 /* Refresh toolbar locked state */ 1998 RefreshLockedToolbarState(); 1999 2000 return 0; 2001 } 2002 2003 HRESULT CInternetToolbar::GetStream(UINT StreamFor, DWORD Stgm, IStream **ppS) 2004 { 2005 WCHAR path[MAX_PATH]; 2006 LPCWSTR subkey = NULL; 2007 switch (StreamFor) 2008 { 2009 case ITBARSTREAM_SHELLBROWSER: subkey = L"ShellBrowser"; break; 2010 case ITBARSTREAM_WEBBROWSER: subkey = L"WebBrowser"; break; 2011 case ITBARSTREAM_EXPLORER: subkey = L"Explorer"; break; 2012 default: return E_INVALIDARG; 2013 } 2014 wsprintfW(path, L"Software\\Microsoft\\Internet Explorer\\Toolbar\\%s", subkey); 2015 *ppS = SHOpenRegStream2W(HKEY_CURRENT_USER, path, L"RosITBarLayout", Stgm); // ROS prefix until we figure out the correct format 2016 return *ppS ? S_OK : E_FAIL; 2017 } 2018