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