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 the toolbar band of a cabinet window 23 */ 24 25 #include "precomp.h" 26 27 class CToolsBand : 28 public CWindowImpl<CToolsBand, CWindow, CControlWinTraits>, 29 public CComObjectRootEx<CComMultiThreadModelNoCS>, 30 public IDeskBand, 31 public IObjectWithSite, 32 public IInputObject, 33 public IPersistStream 34 { 35 private: 36 CComPtr<IDockingWindowSite> fDockSite; 37 HIMAGELIST m_himlNormal; 38 HIMAGELIST m_himlHot; 39 public: 40 CToolsBand(); 41 virtual ~CToolsBand(); 42 public: 43 // *** IDeskBand methods *** 44 virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi); 45 46 // *** IObjectWithSite methods *** 47 virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite); 48 virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite); 49 50 // *** IOleWindow methods *** 51 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd); 52 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); 53 54 // *** IDockingWindow methods *** 55 virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved); 56 virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved); 57 virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow); 58 59 // *** IInputObject methods *** 60 virtual HRESULT STDMETHODCALLTYPE HasFocusIO(); 61 virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg); 62 virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg); 63 64 // *** IPersist methods *** 65 virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID); 66 67 // *** IPersistStream methods *** 68 virtual HRESULT STDMETHODCALLTYPE IsDirty(); 69 virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm); 70 virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty); 71 virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize); 72 73 // message handlers 74 LRESULT OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled); 75 76 BEGIN_MSG_MAP(CToolsBand) 77 // MESSAGE_HANDLER(WM_NOTIFY, OnNotify) 78 // MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) 79 NOTIFY_HANDLER(0, TBN_GETBUTTONINFOW, OnGetButtonInfo) 80 END_MSG_MAP() 81 82 BEGIN_COM_MAP(CToolsBand) 83 COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand) 84 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) 85 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow) 86 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow) 87 COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject) 88 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) 89 COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream) 90 END_COM_MAP() 91 }; 92 93 CToolsBand::CToolsBand() 94 : fDockSite(NULL) 95 { 96 } 97 98 CToolsBand::~CToolsBand() 99 { 100 } 101 102 HRESULT STDMETHODCALLTYPE CToolsBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi) 103 { 104 RECT actualRect; 105 POINTL actualSize; 106 POINTL idealSize; 107 POINTL maxSize; 108 POINTL itemSize; 109 110 ::GetWindowRect(m_hWnd, &actualRect); 111 actualSize.x = actualRect.right - actualRect.left; 112 actualSize.y = actualRect.bottom - actualRect.top; 113 114 /* Obtain the ideal size, to be used as min and max */ 115 SendMessageW(m_hWnd, TB_AUTOSIZE, 0, 0); 116 SendMessageW(m_hWnd, TB_GETMAXSIZE, 0, reinterpret_cast<LPARAM>(&maxSize)); 117 118 idealSize = maxSize; 119 SendMessageW(m_hWnd, TB_GETIDEALSIZE, FALSE, reinterpret_cast<LPARAM>(&idealSize)); 120 121 /* Obtain the button size, to be used as the integral size */ 122 DWORD size = SendMessageW(m_hWnd, TB_GETBUTTONSIZE, 0, 0); 123 itemSize.x = GET_X_LPARAM(size); 124 itemSize.y = GET_Y_LPARAM(size); 125 126 if (pdbi->dwMask & DBIM_MINSIZE) 127 { 128 pdbi->ptMinSize = idealSize; 129 } 130 if (pdbi->dwMask & DBIM_MAXSIZE) 131 { 132 pdbi->ptMaxSize = maxSize; 133 } 134 if (pdbi->dwMask & DBIM_INTEGRAL) 135 { 136 pdbi->ptIntegral = itemSize; 137 } 138 if (pdbi->dwMask & DBIM_ACTUAL) 139 { 140 pdbi->ptActual = actualSize; 141 } 142 if (pdbi->dwMask & DBIM_TITLE) 143 wcscpy(pdbi->wszTitle, L""); 144 if (pdbi->dwMask & DBIM_MODEFLAGS) 145 pdbi->dwModeFlags = DBIMF_UNDELETEABLE; 146 if (pdbi->dwMask & DBIM_BKCOLOR) 147 pdbi->crBkgnd = 0; 148 return S_OK; 149 } 150 151 static const int backImageIndex = 0; 152 static const int forwardImageIndex = 1; 153 static const int favoritesImageIndex = 2; 154 // 3 155 // 4 156 static const int cutImageIndex = 5; 157 static const int copyImageIndex = 6; 158 static const int pasteImageIndex = 7; 159 static const int undoImageIndex = 8; 160 //static const int redoImageIndex = 9; 161 static const int deleteImageIndex = 10; 162 // 11 163 // 12 164 // 13 165 // 14 166 static const int propertiesImageIndex = 15; 167 // 16 168 static const int searchImageIndex = 17; 169 // 18 170 // 19 171 // 20 172 // 21 173 static const int viewsImageIndex = 22; 174 // 23 175 // 24 176 // 25 177 // 26 178 // 27 179 static const int upImageIndex = 28; 180 static const int mapDriveImageIndex = 29; 181 static const int disconnectImageIndex = 30; 182 // 31 183 //static const int viewsAltImageIndex = 32; // same image as viewsImageIndex 184 // 33 185 // 34 186 // 35 187 // 36 188 // 37 189 //static const int viewsAlt2ImageIndex = 38; // same image as viewsAltImageIndex & viewsImageIndex 190 // 39 191 // 40 192 // 41 193 // 42 194 static const int foldersImageIndex = 43; 195 static const int moveToImageIndex = 44; 196 static const int copyToImageIndex = 45; 197 static const int folderOptionsImageIndex = 46; 198 199 enum StandardToolbarButtons { 200 BtnIdx_Back = 0, 201 BtnIdx_Forward, 202 BtnIdx_Up, 203 BtnIdx_Search, 204 BtnIdx_Folders, 205 BtnIdx_MoveTo, 206 BtnIdx_CopyTo, 207 BtnIdx_Delete, 208 BtnIdx_Undo, 209 BtnIdx_Views, 210 BtnIdx_Stop, 211 BtnIdx_Refresh, 212 BtnIdx_Home, 213 BtnIdx_MapDrive, 214 BtnIdx_Disconnect, 215 BtnIdx_Favorites, 216 BtnIdx_History, 217 BtnIdx_FullScreen, 218 BtnIdx_Properties, 219 BtnIdx_Cut, 220 BtnIdx_Copy, 221 BtnIdx_Paste, 222 BtnIdx_FolderOptions, 223 }; 224 225 const int numShownButtons = 13; 226 const int numHiddenButtons = 13; 227 TBBUTTON tbButtonsAdd[numShownButtons + numHiddenButtons] = 228 { 229 { backImageIndex, IDM_GOTO_BACK, TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Back }, 230 { forwardImageIndex, IDM_GOTO_FORWARD, TBSTATE_ENABLED, BTNS_DROPDOWN, { 0 }, 0, BtnIdx_Forward }, 231 { upImageIndex, IDM_GOTO_UPONELEVEL, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Up }, 232 { 6, -1, TBSTATE_ENABLED, BTNS_SEP }, 233 { searchImageIndex, gSearchCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Search }, 234 { foldersImageIndex, gFoldersCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Folders }, 235 { 6, -1, TBSTATE_ENABLED, BTNS_SEP }, 236 { moveToImageIndex, gMoveToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_MoveTo }, 237 { copyToImageIndex, gCopyToCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_CopyTo }, 238 { deleteImageIndex, gDeleteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Delete }, 239 { undoImageIndex, gUndoCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Undo }, 240 { 6, -1, TBSTATE_ENABLED, BTNS_SEP }, 241 { viewsImageIndex, gViewsCommandID, TBSTATE_ENABLED, BTNS_WHOLEDROPDOWN, { 0 }, 0, BtnIdx_Views }, 242 243 { 0, gStopCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Stop }, 244 { 0, IDM_VIEW_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Refresh }, 245 { 0, gHomeCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Home }, 246 { mapDriveImageIndex, IDM_TOOLS_MAPNETWORKDRIVE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_MapDrive }, 247 { disconnectImageIndex, IDM_TOOLS_DISCONNECTNETWORKDRIVE, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Disconnect }, 248 { favoritesImageIndex, gFavoritesCommandID, TBSTATE_ENABLED, BTNS_BUTTON | BTNS_SHOWTEXT, { 0 }, 0, BtnIdx_Favorites }, 249 { 0, gHistoryCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_History }, 250 { 0, gFullScreenCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_FullScreen }, 251 { propertiesImageIndex, gPropertiesCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Properties }, 252 { cutImageIndex, gCutCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Cut }, 253 { copyImageIndex, gCopyCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Copy }, 254 { pasteImageIndex, gPasteCommandID, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_Paste }, 255 { folderOptionsImageIndex, IDM_TOOLS_FOLDEROPTIONS, TBSTATE_ENABLED, BTNS_BUTTON, { 0 }, 0, BtnIdx_FolderOptions }, 256 }; 257 258 HRESULT STDMETHODCALLTYPE CToolsBand::SetSite(IUnknown* pUnkSite){ 259 HWND parentWindow; 260 HWND toolbar; 261 HRESULT hResult; 262 263 if(fDockSite) fDockSite.Release(); 264 265 if (pUnkSite == NULL) 266 return S_OK; 267 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fDockSite)); 268 if (FAILED_UNEXPECTEDLY(hResult)) 269 return hResult; 270 parentWindow = NULL; 271 hResult = IUnknown_GetWindow(pUnkSite, &parentWindow); 272 if (FAILED(hResult) || !::IsWindow(parentWindow)) 273 return E_FAIL; 274 275 toolbar = CreateWindowEx( 276 TBSTYLE_EX_DOUBLEBUFFER, 277 TOOLBARCLASSNAMEW, NULL, 278 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | 279 TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT | 280 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP, 281 0, 0, 500, 20, parentWindow, NULL, _AtlBaseModule.GetModuleInstance(), 0); 282 if (toolbar == NULL) 283 return E_FAIL; 284 SubclassWindow(toolbar); 285 SendMessage(TB_ADDSTRINGW, (WPARAM) GetModuleHandle(L"browseui.dll"), IDS_STANDARD_TOOLBAR); 286 287 SendMessage(WM_USER + 100, GetSystemMetrics(SM_CXEDGE) / 2, 0); 288 SendMessage(TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); 289 SendMessage(TB_SETMAXTEXTROWS, 1, 0); 290 SendMessage(TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS); 291 292 m_himlNormal = ImageList_LoadImageW(_AtlBaseModule.GetResourceInstance(), 293 MAKEINTRESOURCEW(IDB_SHELL_EXPLORER_LG), 294 0, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_DEFAULTSIZE | LR_CREATEDIBSECTION); 295 296 m_himlHot = ImageList_LoadImageW(_AtlBaseModule.GetResourceInstance(), 297 MAKEINTRESOURCEW(IDB_SHELL_EXPLORER_LG_HOT), 298 0, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_DEFAULTSIZE | LR_CREATEDIBSECTION); 299 300 SendMessage(TB_SETIMAGELIST, 0, (LPARAM) m_himlNormal); 301 SendMessage(TB_SETHOTIMAGELIST, 0, (LPARAM) m_himlHot); 302 SendMessage(TB_ADDBUTTONSW, numShownButtons, (LPARAM)&tbButtonsAdd); 303 304 return hResult; 305 } 306 307 HRESULT STDMETHODCALLTYPE CToolsBand::GetSite(REFIID riid, void **ppvSite) 308 { 309 if (fDockSite == NULL) 310 return E_FAIL; 311 return fDockSite->QueryInterface(riid, ppvSite); 312 } 313 314 HRESULT STDMETHODCALLTYPE CToolsBand::GetWindow(HWND *lphwnd) 315 { 316 if (lphwnd == NULL) 317 return E_POINTER; 318 *lphwnd = m_hWnd; 319 return S_OK; 320 } 321 322 HRESULT STDMETHODCALLTYPE CToolsBand::ContextSensitiveHelp(BOOL fEnterMode) 323 { 324 return E_NOTIMPL; 325 } 326 327 HRESULT STDMETHODCALLTYPE CToolsBand::CloseDW(DWORD dwReserved) 328 { 329 ShowDW(FALSE); 330 331 if (IsWindow()) 332 DestroyWindow(); 333 334 m_hWnd = NULL; 335 336 if (fDockSite) 337 fDockSite.Release(); 338 339 if (m_himlNormal) 340 ImageList_Destroy(m_himlNormal); 341 342 if (m_himlHot) 343 ImageList_Destroy(m_himlHot); 344 345 return S_OK; 346 } 347 348 HRESULT STDMETHODCALLTYPE CToolsBand::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved) 349 { 350 return E_NOTIMPL; 351 } 352 353 HRESULT STDMETHODCALLTYPE CToolsBand::ShowDW(BOOL fShow) 354 { 355 if (m_hWnd) 356 { 357 if (fShow) 358 ShowWindow(SW_SHOW); 359 else 360 ShowWindow(SW_HIDE); 361 } 362 return S_OK; 363 } 364 365 HRESULT STDMETHODCALLTYPE CToolsBand::HasFocusIO() 366 { 367 return S_FALSE; 368 } 369 370 HRESULT STDMETHODCALLTYPE CToolsBand::TranslateAcceleratorIO(LPMSG lpMsg) 371 { 372 return S_FALSE; 373 } 374 375 HRESULT STDMETHODCALLTYPE CToolsBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg) 376 { 377 return E_NOTIMPL; 378 } 379 380 HRESULT STDMETHODCALLTYPE CToolsBand::GetClassID(CLSID *pClassID) 381 { 382 return E_NOTIMPL; 383 } 384 385 HRESULT STDMETHODCALLTYPE CToolsBand::IsDirty() 386 { 387 return E_NOTIMPL; 388 } 389 390 HRESULT STDMETHODCALLTYPE CToolsBand::Load(IStream *pStm) 391 { 392 return E_NOTIMPL; 393 } 394 395 HRESULT STDMETHODCALLTYPE CToolsBand::Save(IStream *pStm, BOOL fClearDirty) 396 { 397 return E_NOTIMPL; 398 } 399 400 HRESULT STDMETHODCALLTYPE CToolsBand::GetSizeMax(ULARGE_INTEGER *pcbSize) 401 { 402 return E_NOTIMPL; 403 } 404 405 LRESULT CToolsBand::OnGetButtonInfo(UINT idControl, NMHDR *pNMHDR, BOOL &bHandled) 406 { 407 TBNOTIFYW *pTBntf = reinterpret_cast<TBNOTIFYW *>(pNMHDR); 408 409 if (pTBntf->iItem >= 0 && pTBntf->iItem < (numShownButtons + numHiddenButtons)) 410 { 411 pTBntf->tbButton = tbButtonsAdd[pTBntf->iItem]; 412 return TRUE; 413 } 414 else 415 return FALSE; 416 return 0; 417 } 418 419 HRESULT CToolsBand_CreateInstance(REFIID riid, void **ppv) 420 { 421 return ShellObjectCreator<CToolsBand>(riid, ppv); 422 } 423 424