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 fMainReBar = NULL; 611 fLocked = false; 612 fMenuBandWindow = NULL; 613 fNavigationWindow = NULL; 614 fMenuCallback = new CComObject<CMenuCallback>(); 615 fToolbarWindow = NULL; 616 fAdviseCookie = 0; 617 } 618 619 CInternetToolbar::~CInternetToolbar() 620 { 621 } 622 623 void CInternetToolbar::AddDockItem(IUnknown *newItem, int bandID, int flags) 624 { 625 CComPtr<CDockSite> newSite; 626 627 newSite = new CComObject<CDockSite>; 628 newSite->Initialize(newItem, this, fMainReBar, bandID, flags); 629 } 630 631 HRESULT CInternetToolbar::ReserveBorderSpace(LONG maxHeight) 632 { 633 CComPtr<IDockingWindowSite> dockingWindowSite; 634 RECT availableBorderSpace; 635 636 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite)); 637 if (FAILED_UNEXPECTEDLY(hResult)) 638 return hResult; 639 hResult = dockingWindowSite->GetBorderDW(static_cast<IDockingWindow *>(this), &availableBorderSpace); 640 if (FAILED_UNEXPECTEDLY(hResult)) 641 return hResult; 642 643 if (maxHeight && availableBorderSpace.bottom - availableBorderSpace.top > maxHeight) 644 { 645 availableBorderSpace.bottom = availableBorderSpace.top + maxHeight; 646 } 647 648 return ResizeBorderDW(&availableBorderSpace, fSite, FALSE); 649 } 650 651 HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar) 652 { 653 CComPtr<IShellMenu> menubar; 654 CComPtr<IShellMenuCallback> callback; 655 VARIANT menuOut; 656 HWND ownerWindow; 657 HRESULT hResult; 658 659 if (!pMenuBar) 660 return E_POINTER; 661 662 *pMenuBar = NULL; 663 664 hResult = CMenuBand_CreateInstance(IID_PPV_ARG(IShellMenu, &menubar)); 665 if (FAILED_UNEXPECTEDLY(hResult)) 666 return hResult; 667 668 hResult = fMenuCallback->QueryInterface(IID_PPV_ARG(IShellMenuCallback, &callback)); 669 if (FAILED_UNEXPECTEDLY(hResult)) 670 return hResult; 671 672 hResult = menubar->Initialize(callback, -1, ANCESTORDEFAULT, SMINIT_HORIZONTAL | SMINIT_TOPLEVEL); 673 if (FAILED_UNEXPECTEDLY(hResult)) 674 return hResult; 675 676 // Set Menu 677 { 678 hResult = IUnknown_Exec(fSite, CGID_Explorer, 0x35, 0, NULL, &menuOut); 679 if (FAILED_UNEXPECTEDLY(hResult)) 680 return hResult; 681 682 if (V_VT(&menuOut) != VT_INT_PTR || V_INTREF(&menuOut) == NULL) 683 return E_FAIL; 684 685 hResult = IUnknown_GetWindow(fSite, &ownerWindow); 686 if (FAILED_UNEXPECTEDLY(hResult)) 687 return hResult; 688 689 HMENU hMenuBar = (HMENU) V_INTREF(&menuOut); 690 691 // FIXME: Figure out the proper way to do this. 692 HMENU hMenuFavs = GetSubMenu(hMenuBar, 3); 693 if (hMenuFavs) 694 { 695 DeleteMenu(hMenuFavs, IDM_FAVORITES_EMPTY, MF_BYCOMMAND); 696 } 697 698 hResult = menubar->SetMenu(hMenuBar, ownerWindow, SMSET_DONTOWN); 699 if (FAILED_UNEXPECTEDLY(hResult)) 700 return hResult; 701 } 702 703 hResult = IUnknown_Exec(menubar, CGID_MenuBand, 3, 1, NULL, NULL); 704 if (FAILED_UNEXPECTEDLY(hResult)) 705 return hResult; 706 707 *pMenuBar = menubar.Detach(); 708 709 return S_OK; 710 } 711 712 HRESULT CInternetToolbar::LockUnlockToolbars(bool locked) 713 { 714 REBARBANDINFOW rebarBandInfo; 715 int bandCount; 716 CDockSite *dockSite; 717 HRESULT hResult; 718 719 if (locked != fLocked) 720 { 721 fLocked = locked; 722 rebarBandInfo.cbSize = sizeof(rebarBandInfo); 723 rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM; 724 bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0); 725 for (INT x = 0; x < bandCount; x++) 726 { 727 SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo); 728 dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam); 729 if (dockSite != NULL) 730 { 731 rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS); 732 if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || fLocked) 733 rebarBandInfo.fStyle |= RBBS_NOGRIPPER; 734 if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !fLocked) 735 rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS; 736 SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo); 737 } 738 } 739 hResult = ReserveBorderSpace(0); 740 741 // TODO: refresh view menu? 742 } 743 return S_OK; 744 } 745 746 HRESULT CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd) 747 { 748 long state = 0; 749 if (pcmd->cmdf & OLECMDF_ENABLED) 750 state |= TBSTATE_ENABLED; 751 if (pcmd->cmdf & OLECMDF_LATCHED) 752 state |= TBSTATE_CHECKED; 753 return SetState(pguidCmdGroup, commandID, state); 754 } 755 756 HRESULT CInternetToolbar::CommandStateChanged(bool newValue, int commandID) 757 { 758 HRESULT hResult; 759 760 hResult = S_OK; 761 switch (commandID) 762 { 763 case -1: 764 // loop through buttons 765 //for buttons in CLSID_CommonButtons 766 // if up, QueryStatus for up state and update it 767 // 768 //for buttons in fCommandCategory, update with QueryStatus of fCommandTarget 769 770 OLECMD commandList[4]; 771 commandList[0].cmdID = 0x1c; 772 commandList[1].cmdID = 0x1d; 773 commandList[2].cmdID = 0x1e; 774 commandList[3].cmdID = 0x23; 775 IUnknown_QueryStatus(fSite, CGID_Explorer, 4, commandList, NULL); 776 SetState(&CLSID_CommonButtons, gSearchCommandID, &commandList[0]); 777 SetState(&CLSID_CommonButtons, gFoldersCommandID, &commandList[3]); 778 //SetState(&CLSID_CommonButtons, gFavoritesCommandID, &commandList[2]); 779 //SetState(&CLSID_CommonButtons, gHistoryCommandID, &commandList[1]); 780 781 break; 782 case 1: 783 // forward 784 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_FORWARD, newValue ? TBSTATE_ENABLED : 0); 785 break; 786 case 2: 787 // back 788 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_BACK, newValue ? TBSTATE_ENABLED : 0); 789 break; 790 case 3: 791 // up 792 hResult = SetState(&CLSID_CommonButtons, IDM_GOTO_UPONELEVEL, newValue ? TBSTATE_ENABLED : 0); 793 break; 794 } 795 return hResult; 796 } 797 798 HRESULT CInternetToolbar::CreateAndInitBandProxy() 799 { 800 CComPtr<IServiceProvider> serviceProvider; 801 HRESULT hResult; 802 803 hResult = fSite->QueryInterface(IID_PPV_ARG(IServiceProvider, &serviceProvider)); 804 if (FAILED_UNEXPECTEDLY(hResult)) 805 return hResult; 806 hResult = serviceProvider->QueryService(SID_IBandProxy, IID_PPV_ARG(IBandProxy, &fBandProxy)); 807 if (FAILED_UNEXPECTEDLY(hResult)) 808 { 809 hResult = CBandProxy_CreateInstance(IID_PPV_ARG(IBandProxy, &fBandProxy)); 810 if (FAILED_UNEXPECTEDLY(hResult)) 811 return hResult; 812 hResult = fBandProxy->SetSite(fSite); 813 if (FAILED_UNEXPECTEDLY(hResult)) 814 return hResult; 815 } 816 return S_OK; 817 } 818 819 HRESULT STDMETHODCALLTYPE CInternetToolbar::UIActivateIO(BOOL fActivate, LPMSG lpMsg) 820 { 821 return E_NOTIMPL; 822 } 823 824 HRESULT STDMETHODCALLTYPE CInternetToolbar::HasFocusIO() 825 { 826 HRESULT hr = S_FALSE; 827 828 if (fMenuBar) 829 hr = IUnknown_HasFocusIO(fMenuBar); 830 if (hr != S_FALSE) 831 return hr; 832 833 if (fControlsBar) 834 hr = IUnknown_HasFocusIO(fControlsBar); 835 if (hr != S_FALSE) 836 return hr; 837 838 if (fNavigationBar) 839 hr = IUnknown_HasFocusIO(fNavigationBar); 840 if (hr != S_FALSE) 841 return hr; 842 843 return S_FALSE; 844 } 845 846 HRESULT STDMETHODCALLTYPE CInternetToolbar::TranslateAcceleratorIO(LPMSG lpMsg) 847 { 848 HRESULT hr = S_FALSE; 849 850 if (fMenuBar) 851 hr = IUnknown_TranslateAcceleratorIO(fMenuBar, lpMsg); 852 if (hr == S_OK) 853 return hr; 854 855 if (fControlsBar) 856 hr = IUnknown_TranslateAcceleratorIO(fControlsBar, lpMsg); 857 if (hr == S_OK) 858 return hr; 859 860 if (fNavigationBar) 861 hr = IUnknown_TranslateAcceleratorIO(fNavigationBar, lpMsg); 862 if (hr == S_OK) 863 return hr; 864 865 return S_FALSE; 866 } 867 868 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetWindow(HWND *lphwnd) 869 { 870 if (lphwnd == NULL) 871 return E_POINTER; 872 *lphwnd = m_hWnd; 873 return S_OK; 874 } 875 876 HRESULT STDMETHODCALLTYPE CInternetToolbar::ContextSensitiveHelp(BOOL fEnterMode) 877 { 878 return E_NOTIMPL; 879 } 880 881 HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow) 882 { 883 HRESULT hResult; 884 885 // show the bar here 886 if (fShow) 887 { 888 hResult = ReserveBorderSpace(); 889 if (FAILED_UNEXPECTEDLY(hResult)) 890 return hResult; 891 } 892 893 if (fMenuBar) 894 { 895 hResult = IUnknown_ShowDW(fMenuBar, fShow); 896 if (FAILED_UNEXPECTEDLY(hResult)) 897 return hResult; 898 } 899 900 if (fControlsBar) 901 { 902 hResult = IUnknown_ShowDW(fControlsBar, fShow); 903 if (FAILED_UNEXPECTEDLY(hResult)) 904 return hResult; 905 } 906 if (fNavigationBar) 907 { 908 hResult = IUnknown_ShowDW(fNavigationBar, fShow); 909 if (FAILED_UNEXPECTEDLY(hResult)) 910 return hResult; 911 } 912 if (fLogoBar) 913 { 914 hResult = IUnknown_ShowDW(fLogoBar, fShow); 915 if (FAILED_UNEXPECTEDLY(hResult)) 916 return hResult; 917 } 918 return S_OK; 919 } 920 921 HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved) 922 { 923 HRESULT hResult; 924 925 if (fMenuBar) 926 { 927 hResult = IUnknown_CloseDW(fMenuBar, dwReserved); 928 if (FAILED_UNEXPECTEDLY(hResult)) 929 return hResult; 930 ReleaseCComPtrExpectZero(fMenuBar); 931 } 932 if (fControlsBar) 933 { 934 hResult = IUnknown_CloseDW(fControlsBar, dwReserved); 935 if (FAILED_UNEXPECTEDLY(hResult)) 936 return hResult; 937 ReleaseCComPtrExpectZero(fControlsBar); 938 } 939 if (fNavigationBar) 940 { 941 hResult = IUnknown_CloseDW(fNavigationBar, dwReserved); 942 if (FAILED_UNEXPECTEDLY(hResult)) 943 return hResult; 944 ReleaseCComPtrExpectZero(fNavigationBar); 945 } 946 if (fLogoBar) 947 { 948 hResult = IUnknown_CloseDW(fLogoBar, dwReserved); 949 if (FAILED_UNEXPECTEDLY(hResult)) 950 return hResult; 951 ReleaseCComPtrExpectZero(fLogoBar); 952 } 953 954 SetSite(NULL); 955 return S_OK; 956 } 957 958 HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder, 959 IUnknown *punkToolbarSite, BOOL fReserved) 960 { 961 RECT neededBorderSpace; 962 RECT availableBorderSpace = *prcBorder; 963 964 SendMessage(fMainReBar, RB_SIZETORECT, RBSTR_CHANGERECT, reinterpret_cast<LPARAM>(&availableBorderSpace)); 965 966 // RBSTR_CHANGERECT does not seem to set the proper size in the rect. 967 // Let's make sure we fetch the actual size properly. 968 ::GetWindowRect(fMainReBar, &availableBorderSpace); 969 neededBorderSpace.left = 0; 970 neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top; 971 if (!fLocked) 972 neededBorderSpace.top += 3; 973 neededBorderSpace.right = 0; 974 neededBorderSpace.bottom = 0; 975 976 CComPtr<IDockingWindowSite> dockingWindowSite; 977 978 HRESULT hResult = fSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &dockingWindowSite)); 979 if (FAILED_UNEXPECTEDLY(hResult)) 980 return hResult; 981 982 hResult = dockingWindowSite->RequestBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace); 983 if (FAILED_UNEXPECTEDLY(hResult)) 984 return hResult; 985 986 hResult = dockingWindowSite->SetBorderSpaceDW(static_cast<IDockingWindow *>(this), &neededBorderSpace); 987 if (FAILED_UNEXPECTEDLY(hResult)) 988 return hResult; 989 990 return S_OK; 991 } 992 993 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID) 994 { 995 if (pClassID == NULL) 996 return E_POINTER; 997 *pClassID = CLSID_InternetToolbar; 998 return S_OK; 999 } 1000 1001 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty() 1002 { 1003 return E_NOTIMPL; 1004 } 1005 1006 HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm) 1007 { 1008 return E_NOTIMPL; 1009 } 1010 1011 HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty) 1012 { 1013 return E_NOTIMPL; 1014 } 1015 1016 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize) 1017 { 1018 return E_NOTIMPL; 1019 } 1020 1021 HRESULT STDMETHODCALLTYPE CInternetToolbar::InitNew() 1022 { 1023 CComPtr<IShellMenu> menuBar; 1024 CComPtr<IUnknown> logoBar; 1025 CComPtr<IUnknown> toolsBar; 1026 CComPtr<IUnknown> navigationBar; 1027 HRESULT hResult; 1028 1029 /* Create and attach the menubar to the rebar */ 1030 hResult = CreateMenuBar(&menuBar); 1031 if (FAILED_UNEXPECTEDLY(hResult)) 1032 return hResult; 1033 AddDockItem(menuBar, ITBBID_MENUBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1034 1035 hResult = IUnknown_GetWindow(menuBar, &fMenuBandWindow); 1036 fMenuBar.Attach(menuBar.Detach()); // transfer the ref count 1037 1038 // FIXME: The ROS Rebar does not properly support fixed-size items such as the brandband, 1039 // and it will put them in their own row, sized to take up the whole row. 1040 #if 0 1041 /* Create and attach the brand/logo to the rebar */ 1042 hResult = CBrandBand_CreateInstance(IID_PPV_ARG(IUnknown, &logoBar)); 1043 if (FAILED_UNEXPECTEDLY(hResult)) 1044 return hResult; 1045 AddDockItem(logoBar, ITBBID_BRANDBAND, CDockSite::ITF_NOGRIPPER | CDockSite::ITF_NOTITLE | CDockSite::ITF_FIXEDSIZE); 1046 fLogoBar.Attach(logoBar.Detach()); // transfer the ref count 1047 #endif 1048 1049 /* Create and attach the standard toolbar to the rebar */ 1050 hResult = CToolsBand_CreateInstance(IID_PPV_ARG(IUnknown, &toolsBar)); 1051 if (FAILED_UNEXPECTEDLY(hResult)) 1052 return hResult; 1053 AddDockItem(toolsBar, ITBBID_TOOLSBAND, CDockSite::ITF_NOTITLE | CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1054 fControlsBar.Attach(toolsBar.Detach()); // transfer the ref count 1055 hResult = IUnknown_GetWindow(fControlsBar, &fToolbarWindow); 1056 if (FAILED_UNEXPECTEDLY(hResult)) 1057 return hResult; 1058 1059 /* Create and attach the address/navigation toolbar to the rebar */ 1060 hResult = CAddressBand_CreateInstance(IID_PPV_ARG(IUnknown, &navigationBar)); 1061 if (FAILED_UNEXPECTEDLY(hResult)) 1062 return hResult; 1063 AddDockItem(navigationBar, ITBBID_ADDRESSBAND, CDockSite::ITF_NEWBANDALWAYS | CDockSite::ITF_GRIPPERALWAYS); 1064 fNavigationBar.Attach(navigationBar.Detach()); 1065 hResult = IUnknown_GetWindow(fNavigationBar, &fNavigationWindow); 1066 1067 return S_OK; 1068 } 1069 1070 HRESULT CInternetToolbar::IsBandVisible(int BandID) 1071 { 1072 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0); 1073 1074 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE}; 1075 SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo); 1076 1077 return (bandInfo.fStyle & RBBS_HIDDEN) ? S_FALSE : S_OK; 1078 } 1079 1080 HRESULT CInternetToolbar::ToggleBandVisibility(int BandID) 1081 { 1082 int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0); 1083 1084 REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE}; 1085 SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo); 1086 1087 if (bandInfo.fStyle & RBBS_HIDDEN) 1088 bandInfo.fStyle &= ~RBBS_HIDDEN; 1089 else 1090 bandInfo.fStyle |= RBBS_HIDDEN; 1091 1092 SendMessage(fMainReBar, RB_SETBANDINFOW, index, (LPARAM)&bandInfo); 1093 1094 ReserveBorderSpace(0); 1095 return S_OK; 1096 } 1097 1098 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup, 1099 ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) 1100 { 1101 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands)) 1102 { 1103 while (cCmds != 0) 1104 { 1105 switch (prgCmds->cmdID) 1106 { 1107 case ITID_TEXTLABELS: // Text Labels state 1108 prgCmds->cmdf = OLECMDF_SUPPORTED; 1109 break; 1110 case ITID_TOOLBARBANDSHOWN: // toolbar visibility 1111 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1112 if (IsBandVisible(ITBBID_TOOLSBAND) == S_OK) 1113 prgCmds->cmdf |= OLECMDF_LATCHED; 1114 break; 1115 case ITID_ADDRESSBANDSHOWN: // address bar visibility 1116 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1117 if (IsBandVisible(ITBBID_ADDRESSBAND) == S_OK) 1118 prgCmds->cmdf |= OLECMDF_LATCHED; 1119 break; 1120 case ITID_LINKSBANDSHOWN: // links bar visibility 1121 prgCmds->cmdf = 0; 1122 break; 1123 case ITID_MENUBANDSHOWN: // Menubar band visibility 1124 prgCmds->cmdf = OLECMDF_SUPPORTED; 1125 if (fMenuBar) 1126 prgCmds->cmdf |= OLECMDF_LATCHED; 1127 break; 1128 case ITID_AUTOHIDEENABLED: // Auto hide enabled/disabled 1129 prgCmds->cmdf = 0; 1130 break; 1131 case ITID_CUSTOMIZEENABLED: // customize enabled 1132 prgCmds->cmdf = OLECMDF_SUPPORTED; 1133 break; 1134 case ITID_TOOLBARLOCKED: // lock toolbars 1135 prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; 1136 if (fLocked) 1137 prgCmds->cmdf |= OLECMDF_LATCHED; 1138 break; 1139 default: 1140 prgCmds->cmdf = 0; 1141 break; 1142 } 1143 prgCmds++; 1144 cCmds--; 1145 } 1146 return S_OK; 1147 } 1148 return E_FAIL; 1149 } 1150 1151 HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, 1152 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) 1153 { 1154 if (IsEqualIID(*pguidCmdGroup, CGID_PrivCITCommands)) 1155 { 1156 switch (nCmdID) 1157 { 1158 case 1: 1159 // what do I do here? 1160 return S_OK; 1161 case ITID_TEXTLABELS: 1162 // toggle text labels 1163 return S_OK; 1164 case ITID_TOOLBARBANDSHOWN: 1165 return ToggleBandVisibility(ITBBID_TOOLSBAND); 1166 case ITID_ADDRESSBANDSHOWN: 1167 return ToggleBandVisibility(ITBBID_ADDRESSBAND); 1168 case ITID_LINKSBANDSHOWN: 1169 // toggle links band visibility 1170 return S_OK; 1171 case ITID_CUSTOMIZEENABLED: 1172 // run customize 1173 return S_OK; 1174 case ITID_TOOLBARLOCKED: 1175 return LockUnlockToolbars(!fLocked); 1176 } 1177 } 1178 return E_FAIL; 1179 } 1180 1181 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfoCount(UINT *pctinfo) 1182 { 1183 return E_NOTIMPL; 1184 } 1185 1186 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) 1187 { 1188 return E_NOTIMPL; 1189 } 1190 1191 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, 1192 LCID lcid, DISPID *rgDispId) 1193 { 1194 return E_NOTIMPL; 1195 } 1196 1197 HRESULT STDMETHODCALLTYPE CInternetToolbar::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, 1198 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 1199 { 1200 HRESULT hResult; 1201 1202 switch(dispIdMember) 1203 { 1204 case DISPID_BEFORENAVIGATE: 1205 hResult = S_OK; 1206 break; 1207 case DISPID_DOWNLOADCOMPLETE: 1208 hResult = S_OK; 1209 break; 1210 case DISPID_COMMANDSTATECHANGE: 1211 if (pDispParams->cArgs != 2) 1212 return E_INVALIDARG; 1213 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL || V_VT(&pDispParams->rgvarg[1]) != VT_I4) 1214 return E_INVALIDARG; 1215 return CommandStateChanged(V_BOOL(&pDispParams->rgvarg[0]) != VARIANT_FALSE, 1216 V_I4(&pDispParams->rgvarg[1])); 1217 case DISPID_DOWNLOADBEGIN: 1218 hResult = S_OK; 1219 break; 1220 case DISPID_NAVIGATECOMPLETE2: 1221 hResult = S_OK; 1222 break; 1223 case DISPID_DOCUMENTCOMPLETE: 1224 hResult = S_OK; 1225 break; 1226 } 1227 return S_OK; 1228 } 1229 1230 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetCommandTarget(IUnknown *theTarget, GUID *category, long param14) 1231 { 1232 HRESULT hResult; 1233 1234 TRACE("SetCommandTarget %p category %s param %d\n", theTarget, wine_dbgstr_guid(category), param14); 1235 1236 fCommandTarget.Release(); 1237 hResult = theTarget->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &fCommandTarget)); 1238 if (FAILED_UNEXPECTEDLY(hResult)) 1239 return hResult; 1240 fCommandCategory = *category; 1241 return S_OK; 1242 } 1243 1244 HRESULT STDMETHODCALLTYPE CInternetToolbar::Unknown1() 1245 { 1246 return E_NOTIMPL; 1247 } 1248 1249 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddButtons(const GUID *pguidCmdGroup, long buttonCount, TBBUTTON *buttons) 1250 { 1251 return E_NOTIMPL; 1252 } 1253 1254 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddString(const GUID *pguidCmdGroup, 1255 HINSTANCE param10, LPCTSTR param14, long *param18) 1256 { 1257 long result; 1258 1259 result = (long)::SendMessage(fToolbarWindow, TB_ADDSTRINGW, 1260 reinterpret_cast<WPARAM>(param10), reinterpret_cast<LPARAM>(param14)); 1261 *param18 = result; 1262 if (result == -1) 1263 return E_FAIL; 1264 return S_OK; 1265 } 1266 1267 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetButton(const GUID *pguidCmdGroup, long param10, long param14) 1268 { 1269 return E_NOTIMPL; 1270 } 1271 1272 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetState(const GUID *pguidCmdGroup, long commandID, long *theState) 1273 { 1274 if (theState == NULL) 1275 return E_POINTER; 1276 // map the command id 1277 *theState = (long)::SendMessage(fToolbarWindow, TB_GETSTATE, commandID, 0); 1278 return S_OK; 1279 } 1280 1281 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, long theState) 1282 { 1283 // map the command id 1284 ::SendMessage(fToolbarWindow, TB_SETSTATE, commandID, MAKELONG(theState, 0)); 1285 return S_OK; 1286 } 1287 1288 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBitmap(const GUID *pguidCmdGroup, long param10, long buttonCount, 1289 TBADDBITMAP *lParam, long *newIndex, COLORREF param20) 1290 { 1291 return E_NOTIMPL; 1292 } 1293 1294 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBitmapSize(long *paramC) 1295 { 1296 if (paramC == NULL) 1297 return E_POINTER; 1298 *paramC = MAKELONG(24, 24); 1299 return S_OK; 1300 } 1301 1302 HRESULT STDMETHODCALLTYPE CInternetToolbar::SendToolbarMsg(const GUID *pguidCmdGroup, UINT uMsg, 1303 WPARAM wParam, LPARAM lParam, LRESULT *result) 1304 { 1305 return E_NOTIMPL; 1306 } 1307 1308 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetImageList(const GUID *pguidCmdGroup, HIMAGELIST param10, 1309 HIMAGELIST param14, HIMAGELIST param18) 1310 { 1311 return E_NOTIMPL; 1312 } 1313 1314 HRESULT STDMETHODCALLTYPE CInternetToolbar::ModifyButton(const GUID *pguidCmdGroup, long param10, long param14) 1315 { 1316 return E_NOTIMPL; 1317 } 1318 1319 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnChange(LONG lEvent, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 1320 { 1321 return E_NOTIMPL; 1322 } 1323 1324 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite) 1325 { 1326 CComPtr<IBrowserService> browserService; 1327 HWND ownerWindow; 1328 HWND dockContainer; 1329 HRESULT hResult; 1330 1331 if (pUnkSite == NULL) 1332 { 1333 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie); 1334 ::DestroyWindow(fMainReBar); 1335 DestroyWindow(); 1336 fSite.Release(); 1337 } 1338 else 1339 { 1340 // get window handle of owner 1341 hResult = IUnknown_GetWindow(pUnkSite, &ownerWindow); 1342 if (FAILED_UNEXPECTEDLY(hResult)) 1343 return hResult; 1344 if (ownerWindow == NULL) 1345 return E_FAIL; 1346 1347 // create dock container 1348 fSite = pUnkSite; 1349 dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0, 1350 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, NULL, 0); 1351 if (dockContainer == NULL) 1352 return E_FAIL; 1353 SubclassWindow(dockContainer); 1354 1355 // create rebar in dock container 1356 DWORD style = WS_VISIBLE | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | 1357 RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_REGISTERDROP | RBS_AUTOSIZE | RBS_DBLCLKTOGGLE | 1358 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_TOP; 1359 DWORD exStyle = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_TOOLWINDOW; 1360 fMainReBar = CreateWindowEx(exStyle, REBARCLASSNAMEW, NULL, style, 1361 0, 0, 700, 60, dockContainer, NULL, _AtlBaseModule.GetModuleInstance(), NULL); 1362 if (fMainReBar == NULL) 1363 return E_FAIL; 1364 1365 // take advice to watch events 1366 hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1367 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie); 1368 } 1369 return S_OK; 1370 } 1371 1372 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSite(REFIID riid, void **ppvSite) 1373 { 1374 if (ppvSite == NULL) 1375 return E_POINTER; 1376 if (fSite.p != NULL) 1377 return fSite->QueryInterface(riid, ppvSite); 1378 *ppvSite = NULL; 1379 return S_OK; 1380 } 1381 1382 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) 1383 { 1384 HRESULT hResult; 1385 1386 if (IsEqualIID(guidService, IID_IBandSite)) 1387 return this->QueryInterface(riid, ppvObject); 1388 if (IsEqualIID(guidService, SID_IBandProxy)) 1389 { 1390 if (fBandProxy.p == NULL) 1391 { 1392 hResult = CreateAndInitBandProxy(); 1393 if (FAILED_UNEXPECTEDLY(hResult)) 1394 return hResult; 1395 } 1396 return fBandProxy->QueryInterface(riid, ppvObject); 1397 } 1398 return IUnknown_QueryService(fSite, guidService, riid, ppvObject); 1399 } 1400 1401 HRESULT STDMETHODCALLTYPE CInternetToolbar::OnWinEvent( 1402 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) 1403 { 1404 HRESULT hResult; 1405 1406 if (fMenuBar) 1407 { 1408 hResult = IUnknown_RelayWinEvent(fMenuBar, hWnd, uMsg, wParam, lParam, theResult); 1409 if (hResult != S_FALSE) 1410 return hResult; 1411 } 1412 1413 if (fNavigationBar) 1414 { 1415 hResult = IUnknown_RelayWinEvent(fNavigationBar, hWnd, uMsg, wParam, lParam, theResult); 1416 if (hResult != S_FALSE) 1417 return hResult; 1418 } 1419 1420 if (fLogoBar) 1421 { 1422 hResult = IUnknown_RelayWinEvent(fLogoBar, hWnd, uMsg, wParam, lParam, theResult); 1423 if (hResult != S_FALSE) 1424 return hResult; 1425 } 1426 1427 return S_FALSE; 1428 } 1429 1430 HRESULT STDMETHODCALLTYPE CInternetToolbar::IsWindowOwner(HWND hWnd) 1431 { 1432 UNIMPLEMENTED; 1433 return E_NOTIMPL; 1434 } 1435 1436 HRESULT STDMETHODCALLTYPE CInternetToolbar::AddBand(IUnknown *punk) 1437 { 1438 UNIMPLEMENTED; 1439 return E_NOTIMPL; 1440 } 1441 1442 HRESULT STDMETHODCALLTYPE CInternetToolbar::EnumBands(UINT uBand, DWORD *pdwBandID) 1443 { 1444 UNIMPLEMENTED; 1445 return E_NOTIMPL; 1446 } 1447 1448 HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryBand(DWORD dwBandID, 1449 IDeskBand **ppstb, DWORD *pdwState, LPWSTR pszName, int cchName) 1450 { 1451 if (ppstb == NULL) 1452 return E_POINTER; 1453 if (dwBandID == ITBBID_MENUBAND && fMenuBar.p != NULL) 1454 return fMenuBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb)); 1455 //if (dwBandID == ITBBID_BRANDBAND && fLogoBar.p != NULL) 1456 // return fLogoBar->QueryInterface(IID_PPV_ARG(IDeskBand, ppstb)); 1457 *ppstb = NULL; 1458 return E_FAIL; 1459 } 1460 1461 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState) 1462 { 1463 UNIMPLEMENTED; 1464 return E_NOTIMPL; 1465 } 1466 1467 HRESULT STDMETHODCALLTYPE CInternetToolbar::RemoveBand(DWORD dwBandID) 1468 { 1469 UNIMPLEMENTED; 1470 return E_NOTIMPL; 1471 } 1472 1473 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandObject(DWORD dwBandID, REFIID riid, void **ppv) 1474 { 1475 UNIMPLEMENTED; 1476 return E_NOTIMPL; 1477 } 1478 1479 HRESULT STDMETHODCALLTYPE CInternetToolbar::SetBandSiteInfo(const BANDSITEINFO *pbsinfo) 1480 { 1481 UNIMPLEMENTED; 1482 return E_NOTIMPL; 1483 } 1484 1485 HRESULT STDMETHODCALLTYPE CInternetToolbar::GetBandSiteInfo(BANDSITEINFO *pbsinfo) 1486 { 1487 UNIMPLEMENTED; 1488 return E_NOTIMPL; 1489 } 1490 1491 LRESULT CInternetToolbar::OnTravelBack(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1492 { 1493 CComPtr<IWebBrowser> webBrowser; 1494 HRESULT hResult; 1495 1496 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IWebBrowser, &webBrowser)); 1497 if (FAILED_UNEXPECTEDLY(hResult)) 1498 return 0; 1499 hResult = webBrowser->GoBack(); 1500 return 1; 1501 } 1502 1503 LRESULT CInternetToolbar::OnTravelForward(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->GoForward(); 1512 return 1; 1513 } 1514 1515 LRESULT CInternetToolbar::OnUpLevel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1516 { 1517 IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_GOTO_UPONELEVEL, 0, NULL, NULL); 1518 return 1; 1519 } 1520 1521 LRESULT CInternetToolbar::OnSearch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1522 { 1523 IUnknown_Exec(fSite, CGID_Explorer, 0x1c, 1, NULL, NULL); 1524 return 1; 1525 } 1526 1527 LRESULT CInternetToolbar::OnFolders(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1528 { 1529 IUnknown_Exec(fSite, CGID_Explorer, 0x23, 0, NULL, NULL); 1530 return 1; 1531 } 1532 1533 LRESULT CInternetToolbar::OnForwardToCommandTarget(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled) 1534 { 1535 HRESULT hResult; 1536 1537 if (fCommandTarget.p != NULL) 1538 { 1539 hResult = fCommandTarget->Exec(&fCommandCategory, wID, 0, NULL, NULL); 1540 if (FAILED(hResult)) 1541 { 1542 ::SendMessageW(::GetParent(m_hWnd), WM_COMMAND, wID, 0); 1543 } 1544 } 1545 return 1; 1546 } 1547 1548 LRESULT CInternetToolbar::OnMenuDropDown(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1549 { 1550 CComPtr<IBrowserService> browserService; 1551 CComPtr<IOleCommandTarget> commandTarget; 1552 CComPtr<ITravelLog> travelLog; 1553 NMTOOLBARW *notifyInfo; 1554 RECT bounds; 1555 HMENU newMenu; 1556 TPMPARAMS params; 1557 int selectedItem; 1558 VARIANT parmIn; 1559 OLECMD commandInfo; 1560 HRESULT hResult; 1561 wchar_t templateString[200]; 1562 1563 notifyInfo = (NMTOOLBARW *)pNMHDR; 1564 if (notifyInfo->hdr.hwndFrom != fToolbarWindow) 1565 { 1566 // not from the toolbar, keep looking for a message handler 1567 bHandled = FALSE; 1568 return 0; 1569 } 1570 SendMessage(fToolbarWindow, TB_GETRECT, notifyInfo->iItem, reinterpret_cast<LPARAM>(&bounds)); 1571 ::MapWindowPoints(fToolbarWindow, NULL, reinterpret_cast<POINT *>(&bounds), 2); 1572 switch (notifyInfo->iItem) 1573 { 1574 case IDM_GOTO_BACK: 1575 newMenu = CreatePopupMenu(); 1576 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1577 hResult = browserService->GetTravelLog(&travelLog); 1578 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_BACK); 1579 commandInfo.cmdID = 0x1d; 1580 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL); 1581 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED && 1582 travelLog->CountEntries(browserService) > 1) 1583 { 1584 AppendMenuW(newMenu, MF_SEPARATOR, -1, L""); 1585 1586 if (LoadStringW(_AtlBaseModule.GetResourceInstance(), 1587 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0) 1588 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H"); 1589 1590 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString); 1591 } 1592 params.cbSize = sizeof(params); 1593 params.rcExclude = bounds; 1594 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, 1595 bounds.left, bounds.bottom, m_hWnd, ¶ms); 1596 if (selectedItem == IDM_EXPLORERBAR_HISTORY) 1597 { 1598 V_VT(&parmIn) = VT_I4; 1599 V_I4(&parmIn) = 1; 1600 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL); 1601 } 1602 else if (selectedItem != 0) 1603 hResult = travelLog->Travel(browserService, -selectedItem); 1604 DestroyMenu(newMenu); 1605 break; 1606 case IDM_GOTO_FORWARD: 1607 newMenu = CreatePopupMenu(); 1608 hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 1609 hResult = browserService->GetTravelLog(&travelLog); 1610 hResult = travelLog->InsertMenuEntries(browserService, newMenu, 0, 1, 9, TLMENUF_FORE); 1611 commandInfo.cmdID = 0x1d; 1612 hResult = IUnknown_QueryStatus(browserService, CGID_Explorer, 1, &commandInfo, NULL); 1613 if ((commandInfo.cmdf & (OLECMDF_ENABLED | OLECMDF_LATCHED)) == OLECMDF_ENABLED && 1614 travelLog->CountEntries(browserService) > 1) 1615 { 1616 AppendMenuW(newMenu, MF_SEPARATOR, -1, L""); 1617 1618 if (LoadStringW(_AtlBaseModule.GetResourceInstance(), 1619 IDS_HISTORYTEXT, templateString, sizeof(templateString) / sizeof(wchar_t)) == 0) 1620 StringCbCopyW(templateString, sizeof(templateString), L"&History\tCtrl+H"); 1621 1622 AppendMenuW(newMenu, MF_STRING /* | MF_OWNERDRAW */, IDM_EXPLORERBAR_HISTORY, templateString); 1623 } 1624 params.cbSize = sizeof(params); 1625 params.rcExclude = bounds; 1626 selectedItem = TrackPopupMenuEx(newMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, 1627 bounds.left, bounds.bottom, m_hWnd, ¶ms); 1628 if (selectedItem == IDM_EXPLORERBAR_HISTORY) 1629 { 1630 V_VT(&parmIn) = VT_I4; 1631 V_I4(&parmIn) = 1; 1632 Exec(&CGID_Explorer, 0x1d, 2, &parmIn, NULL); 1633 } 1634 else if (selectedItem != 0) 1635 hResult = travelLog->Travel(browserService, selectedItem); 1636 DestroyMenu(newMenu); 1637 break; 1638 case gViewsCommandID: 1639 VARIANT inValue; 1640 CComVariant outValue; 1641 HRESULT hResult; 1642 1643 V_VT(&inValue) = VT_INT_PTR; 1644 V_INTREF(&inValue) = reinterpret_cast<INT *>(&bounds); 1645 1646 if (fCommandTarget.p != NULL) 1647 hResult = fCommandTarget->Exec(&fCommandCategory, FCIDM_SHVIEW_AUTOARRANGE, 1, &inValue, &outValue); 1648 // pvaOut is VT_I4 with value 0x403 1649 break; 1650 } 1651 return TBDDRET_DEFAULT; 1652 } 1653 1654 LRESULT CInternetToolbar::OnQueryInsert(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1655 { 1656 return 1; 1657 } 1658 1659 LRESULT CInternetToolbar::OnQueryDelete(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1660 { 1661 return 1; 1662 } 1663 1664 LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1665 { 1666 HMENU contextMenuBar; 1667 HMENU contextMenu; 1668 POINT clickLocation; 1669 int command; 1670 RBHITTESTINFO hitTestInfo; 1671 REBARBANDINFOW rebarBandInfo; 1672 int bandID; 1673 BOOL goButtonChecked; 1674 1675 clickLocation.x = LOWORD(lParam); 1676 clickLocation.y = HIWORD(lParam); 1677 hitTestInfo.pt = clickLocation; 1678 ScreenToClient(&hitTestInfo.pt); 1679 SendMessage(fMainReBar, RB_HITTEST, 0, (LPARAM)&hitTestInfo); 1680 if (hitTestInfo.iBand == -1) 1681 return 0; 1682 rebarBandInfo.cbSize = sizeof(rebarBandInfo); 1683 rebarBandInfo.fMask = RBBIM_ID; 1684 SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo); 1685 bandID = rebarBandInfo.wID; 1686 contextMenuBar = LoadMenu(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(IDM_CABINET_CONTEXTMENU)); 1687 contextMenu = GetSubMenu(contextMenuBar, 0); 1688 switch (bandID) 1689 { 1690 case ITBBID_MENUBAND: // menu band 1691 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1692 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1693 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1694 break; 1695 case ITBBID_BRANDBAND: // brand band 1696 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1697 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1698 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1699 break; 1700 case ITBBID_TOOLSBAND: // tools band 1701 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1702 DeleteMenu(contextMenu, IDM_TOOLBARS_GOBUTTON, MF_BYCOMMAND); 1703 break; 1704 case ITBBID_ADDRESSBAND: // navigation band 1705 DeleteMenu(contextMenu, IDM_TOOLBARS_CUSTOMIZE, MF_BYCOMMAND); 1706 DeleteMenu(contextMenu, IDM_TOOLBARS_TEXTLABELS, MF_BYCOMMAND); 1707 break; 1708 default: 1709 break; 1710 } 1711 1712 SHEnableMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE); 1713 1714 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_STANDARDBUTTONS, IsBandVisible(ITBBID_TOOLSBAND) == S_OK); 1715 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, IsBandVisible(ITBBID_ADDRESSBAND) == S_OK); 1716 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE); 1717 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE); 1718 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked); 1719 goButtonChecked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE); 1720 SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, goButtonChecked); 1721 1722 // TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment 1723 command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, 1724 clickLocation.x, clickLocation.y, 0, m_hWnd, NULL); 1725 switch (command) 1726 { 1727 case IDM_TOOLBARS_STANDARDBUTTONS: // standard buttons 1728 ToggleBandVisibility(ITBBID_TOOLSBAND); 1729 break; 1730 case IDM_TOOLBARS_ADDRESSBAR: // address bar 1731 ToggleBandVisibility(ITBBID_ADDRESSBAND); 1732 break; 1733 case IDM_TOOLBARS_LINKSBAR: // links 1734 break; 1735 case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars 1736 LockUnlockToolbars(!fLocked); 1737 break; 1738 case IDM_TOOLBARS_CUSTOMIZE: // customize 1739 SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0); 1740 break; 1741 case IDM_TOOLBARS_GOBUTTON: 1742 SendMessage(fNavigationWindow, WM_COMMAND, IDM_TOOLBARS_GOBUTTON, 0); 1743 break; 1744 } 1745 1746 DestroyMenu(contextMenuBar); 1747 return 1; 1748 } 1749 1750 LRESULT CInternetToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1751 { 1752 if (wParam != SIZE_MINIMIZED) 1753 { 1754 ::SetWindowPos(fMainReBar, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), 1755 SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE); 1756 } 1757 return 1; 1758 } 1759 1760 LRESULT CInternetToolbar::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1761 { 1762 if ((short)lParam != HTCLIENT || (HWND)wParam != m_hWnd) 1763 { 1764 bHandled = FALSE; 1765 return 0; 1766 } 1767 SetCursor(LoadCursor(NULL, IDC_SIZENS)); 1768 return 1; 1769 } 1770 1771 LRESULT CInternetToolbar::OnTipText(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 1772 { 1773 CComPtr<IBrowserService> browserService; 1774 CComPtr<ITravelLog> travelLog; 1775 TOOLTIPTEXTW *pTTTW; 1776 UINT nID; 1777 HRESULT hResult; 1778 wchar_t tempString[300]; 1779 1780 pTTTW = reinterpret_cast<TOOLTIPTEXTW *>(pNMHDR); 1781 if ((pTTTW->uFlags & TTF_IDISHWND) != 0) 1782 nID = ::GetDlgCtrlID((HWND)pNMHDR->idFrom); 1783 else 1784 nID = (UINT)pNMHDR->idFrom; 1785 1786 if (nID != 0) 1787 { 1788 if (nID == (UINT)IDM_GOTO_BACK || nID == (UINT)IDM_GOTO_FORWARD) 1789 { 1790 // TODO: Should this call QueryService? 1791 hResult = fSite->QueryInterface(IID_PPV_ARG(IBrowserService, &browserService)); 1792 hResult = browserService->GetTravelLog(&travelLog); 1793 hResult = travelLog->GetToolTipText(browserService, 1794 (nID == (UINT)IDM_GOTO_BACK) ? TLOG_BACK : TLOG_FORE, 1795 0, tempString, 299); 1796 if (FAILED_UNEXPECTEDLY(hResult)) 1797 { 1798 bHandled = FALSE; 1799 return 0; 1800 } 1801 } 1802 else 1803 tempString[0] = 0; 1804 wcsncpy (pTTTW->szText, tempString, sizeof(pTTTW->szText) / sizeof(wchar_t)); 1805 ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0, 1806 SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); 1807 return 0; 1808 } 1809 return 0; 1810 } 1811 1812 LRESULT CInternetToolbar::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1813 { 1814 LRESULT theResult; 1815 HRESULT hResult; 1816 1817 hResult = OnWinEvent((HWND) lParam, uMsg, wParam, lParam, &theResult); 1818 1819 bHandled = hResult == S_OK; 1820 1821 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult; 1822 } 1823 LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1824 { 1825 NMHDR *notifyHeader; 1826 LRESULT theResult; 1827 HRESULT hResult; 1828 1829 notifyHeader = reinterpret_cast<NMHDR *>(lParam); 1830 1831 hResult = OnWinEvent(notifyHeader->hwndFrom, uMsg, wParam, lParam, &theResult); 1832 1833 bHandled = hResult == S_OK; 1834 1835 return FAILED_UNEXPECTEDLY(hResult) ? 0 : theResult; 1836 } 1837 1838 LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1839 { 1840 bHandled = FALSE; 1841 if (fLocked) 1842 return 0; 1843 1844 if (wParam & MK_CONTROL) 1845 return 0; 1846 1847 fSizing = TRUE; 1848 1849 DWORD msgp = GetMessagePos(); 1850 1851 fStartPosition.x = GET_X_LPARAM(msgp); 1852 fStartPosition.y = GET_Y_LPARAM(msgp); 1853 1854 RECT rc; 1855 GetWindowRect(&rc); 1856 1857 fStartHeight = rc.bottom - rc.top; 1858 1859 SetCapture(); 1860 1861 bHandled = TRUE; 1862 return 0; 1863 } 1864 1865 LRESULT CInternetToolbar::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1866 { 1867 bHandled = FALSE; 1868 if (!fSizing) 1869 return 0; 1870 1871 DWORD msgp = GetMessagePos(); 1872 1873 POINT pt; 1874 pt.x = GET_X_LPARAM(msgp); 1875 pt.y = GET_Y_LPARAM(msgp); 1876 1877 ReserveBorderSpace(fStartHeight - fStartPosition.y + pt.y); 1878 1879 bHandled = TRUE; 1880 return 0; 1881 } 1882 1883 LRESULT CInternetToolbar::OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1884 { 1885 bHandled = FALSE; 1886 if (!fSizing) 1887 return 0; 1888 1889 OnMouseMove(uMsg, wParam, lParam, bHandled); 1890 1891 fSizing = FALSE; 1892 1893 ReleaseCapture(); 1894 1895 return 0; 1896 } 1897 1898 LRESULT CInternetToolbar::OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 1899 { 1900 HRESULT hr; 1901 HWND hwndMenu; 1902 1903 hr = IUnknown_GetWindow(fMenuBar, &hwndMenu); 1904 if (FAILED_UNEXPECTEDLY(hr)) 1905 return 0; 1906 1907 CComPtr<IWinEventHandler> menuWinEventHandler; 1908 hr = fMenuBar->QueryInterface(IID_PPV_ARG(IWinEventHandler, &menuWinEventHandler)); 1909 if (FAILED_UNEXPECTEDLY(hr)) 1910 return 0; 1911 1912 LRESULT lres; 1913 hr = menuWinEventHandler->OnWinEvent(hwndMenu, uMsg, wParam, lParam, &lres); 1914 if (FAILED_UNEXPECTEDLY(hr)) 1915 return 0; 1916 1917 return lres; 1918 } 1919