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