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