Reactos
at master 351 lines 9.8 kB view raw
1/* 2 * ReactOS Explorer 3 * 4 * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "precomp.h" 22 23/***************************************************************************** 24 ** CTaskBand **************************************************************** 25 *****************************************************************************/ 26 27const GUID CLSID_ITaskBand = { 0x68284FAA, 0x6A48, 0x11D0, { 0x8C, 0x78, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xB4 } }; 28 29class CTaskBand : 30 public CComCoClass<CTaskBand>, 31 public CComObjectRootEx<CComMultiThreadModelNoCS>, 32 public IObjectWithSite, 33 public IDeskBand, 34 public IDeskBar, 35 public IPersistStream, 36 public IWinEventHandler, 37 public IOleCommandTarget 38{ 39 CComPtr<ITrayWindow> m_Tray; 40 CComPtr<IUnknown> m_Site; 41 CComPtr<IUnknown> m_TasksWnd; 42 43 HWND m_hWnd; 44 45public: 46 CTaskBand() : 47 m_hWnd(NULL) 48 { 49 } 50 51 virtual ~CTaskBand() { } 52 53 /*****************************************************************************/ 54 55 STDMETHODIMP 56 GetWindow(OUT HWND *phwnd) override 57 { 58 if (!m_hWnd) 59 return E_FAIL; 60 if (!phwnd) 61 return E_INVALIDARG; 62 *phwnd = m_hWnd; 63 return S_OK; 64 } 65 66 STDMETHODIMP 67 ContextSensitiveHelp(IN BOOL fEnterMode) override 68 { 69 /* FIXME: Implement */ 70 return E_NOTIMPL; 71 } 72 73 STDMETHODIMP 74 ShowDW(IN BOOL bShow) override 75 { 76 /* We don't do anything... */ 77 return S_OK; 78 } 79 80 STDMETHODIMP 81 CloseDW(IN DWORD dwReserved) override 82 { 83 /* We don't do anything... */ 84 return S_OK; 85 } 86 87 STDMETHODIMP 88 ResizeBorderDW( 89 LPCRECT prcBorder, 90 IUnknown *punkToolbarSite, 91 BOOL fReserved) override 92 { 93 /* No need to implement this method */ 94 return E_NOTIMPL; 95 } 96 97 STDMETHODIMP 98 GetBandInfo( 99 IN DWORD dwBandID, 100 IN DWORD dwViewMode, 101 IN OUT DESKBANDINFO *pdbi) override 102 { 103 TRACE("CTaskBand::GetBandInfo(0x%x,0x%x,0x%p) hWnd=0x%p\n", dwBandID, dwViewMode, pdbi, m_hWnd); 104 105 if (m_hWnd != NULL) 106 { 107 HWND hwndToolbar = ::GetWindow(m_hWnd, GW_CHILD); 108 109 /* The task band never has a title */ 110 pdbi->dwMask &= ~DBIM_TITLE; 111 112 /* NOTE: We don't return DBIMF_UNDELETEABLE here, the band site will 113 handle us differently and add this flag for us. The reason for 114 this is future changes that might allow it to be deletable. 115 We want the band site to be in charge of this decision rather 116 the band itself! */ 117 /* FIXME: What about DBIMF_NOGRIPPER and DBIMF_ALWAYSGRIPPER */ 118 pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT; 119 120 /* Obtain the button size, to be used as the minimum size */ 121 DWORD size = SendMessageW(hwndToolbar, TB_GETBUTTONSIZE, 0, 0); 122 pdbi->ptMinSize.x = 0; 123 pdbi->ptMinSize.y = GET_Y_LPARAM(size); 124 125 if (dwViewMode & DBIF_VIEWMODE_VERTICAL) 126 { 127 pdbi->ptIntegral.x = 0; 128 pdbi->ptIntegral.y = 1; 129 } 130 else 131 { 132 pdbi->ptIntegral.x = 0; 133 pdbi->ptIntegral.y = GET_Y_LPARAM(size); 134 } 135 136 /* Ignored: pdbi->ptMaxSize.x */ 137 pdbi->ptMaxSize.y = -1; 138 139 RECT rcToolbar; 140 ::GetWindowRect(hwndToolbar, &rcToolbar); 141 /* FIXME: We should query the height from the task bar object!!! */ 142 pdbi->ptActual.x = rcToolbar.right - rcToolbar.left; 143 pdbi->ptActual.y = rcToolbar.bottom - rcToolbar.top; 144 145 TRACE("H: %d, Min: %d,%d, Integral.y: %d Actual: %d,%d\n", (dwViewMode & DBIF_VIEWMODE_VERTICAL) == 0, 146 pdbi->ptMinSize.x, pdbi->ptMinSize.y, pdbi->ptIntegral.y, 147 pdbi->ptActual.x, pdbi->ptActual.y); 148 149 return S_OK; 150 } 151 152 return E_FAIL; 153 } 154 155 /*****************************************************************************/ 156 // *** IOleCommandTarget methods *** 157 158 STDMETHODIMP 159 QueryStatus( 160 const GUID *pguidCmdGroup, 161 ULONG cCmds, 162 OLECMD prgCmds [], 163 OLECMDTEXT *pCmdText) override 164 { 165 UNIMPLEMENTED; 166 return E_NOTIMPL; 167 } 168 169 STDMETHODIMP 170 Exec( 171 const GUID *pguidCmdGroup, 172 DWORD nCmdID, 173 DWORD nCmdexecopt, 174 VARIANT *pvaIn, 175 VARIANT *pvaOut) override 176 { 177 if (IsEqualIID(*pguidCmdGroup, IID_IBandSite)) 178 { 179 return S_OK; 180 } 181 182 if (IsEqualIID(*pguidCmdGroup, IID_IDeskBand)) 183 { 184 return S_OK; 185 } 186 187 UNIMPLEMENTED; 188 return E_NOTIMPL; 189 } 190 191 /*****************************************************************************/ 192 193 STDMETHODIMP 194 SetClient(IN IUnknown *punkClient) override 195 { 196 TRACE("IDeskBar::SetClient(0x%p)\n", punkClient); 197 return E_NOTIMPL; 198 } 199 200 STDMETHODIMP 201 GetClient(OUT IUnknown **ppunkClient) override 202 { 203 TRACE("IDeskBar::GetClient(0x%p)\n", ppunkClient); 204 return E_NOTIMPL; 205 } 206 207 STDMETHODIMP 208 OnPosRectChangeDB(IN RECT *prc) override 209 { 210 TRACE("IDeskBar::OnPosRectChangeDB(0x%p=(%d,%d,%d,%d))\n", prc, prc->left, prc->top, prc->right, prc->bottom); 211 if (prc->bottom - prc->top == 0) 212 return S_OK; 213 214 return S_FALSE; 215 } 216 217 /*****************************************************************************/ 218 219 STDMETHODIMP 220 GetClassID(OUT CLSID *pClassID) override 221 { 222 TRACE("CTaskBand::GetClassID(0x%p)\n", pClassID); 223 /* We're going to return the (internal!) CLSID of the task band interface */ 224 *pClassID = CLSID_ITaskBand; 225 return S_OK; 226 } 227 228 STDMETHODIMP 229 IsDirty() override 230 { 231 /* The object hasn't changed since the last save! */ 232 return S_FALSE; 233 } 234 235 STDMETHODIMP 236 Load(IN IStream *pStm) override 237 { 238 TRACE("CTaskBand::Load called\n"); 239 /* Nothing to do */ 240 return S_OK; 241 } 242 243 STDMETHODIMP 244 Save( 245 IN IStream *pStm, 246 IN BOOL fClearDirty) override 247 { 248 /* Nothing to do */ 249 return S_OK; 250 } 251 252 STDMETHODIMP 253 GetSizeMax(OUT ULARGE_INTEGER *pcbSize) override 254 { 255 TRACE("CTaskBand::GetSizeMax called\n"); 256 /* We don't need any space for the task band */ 257 pcbSize->QuadPart = 0; 258 return S_OK; 259 } 260 261 /*****************************************************************************/ 262 263 STDMETHODIMP 264 SetSite(IUnknown *pUnkSite) override 265 { 266 HRESULT hRet; 267 HWND hwndSite; 268 269 TRACE("CTaskBand::SetSite(0x%p)\n", pUnkSite); 270 271 hRet = IUnknown_GetWindow(pUnkSite, &hwndSite); 272 if (FAILED_UNEXPECTEDLY(hRet)) 273 return hRet; 274 275 TRACE("CreateTaskSwitchWnd(Parent: 0x%p)\n", hwndSite); 276 277 hRet = CTaskSwitchWnd_CreateInstance(hwndSite, m_Tray, IID_PPV_ARG(IUnknown, &m_TasksWnd)); 278 if (FAILED_UNEXPECTEDLY(hRet)) 279 return hRet; 280 281 hRet = IUnknown_GetWindow(m_TasksWnd, &m_hWnd); 282 if (FAILED_UNEXPECTEDLY(hRet)) 283 return hRet; 284 285 m_Site = pUnkSite; 286 287 return S_OK; 288 } 289 290 STDMETHODIMP 291 GetSite( 292 IN REFIID riid, 293 OUT VOID **ppvSite) override 294 { 295 TRACE("CTaskBand::GetSite(0x%p,0x%p)\n", riid, ppvSite); 296 297 if (m_Site != NULL) 298 { 299 return m_Site->QueryInterface(riid, ppvSite); 300 } 301 302 *ppvSite = NULL; 303 return E_FAIL; 304 } 305 306 /*****************************************************************************/ 307 308 STDMETHODIMP 309 OnWinEvent( 310 HWND hWnd, 311 UINT uMsg, 312 WPARAM wParam, 313 LPARAM lParam, 314 LRESULT *theResult) override 315 { 316 //UNIMPLEMENTED; 317 return E_NOTIMPL; 318 } 319 320 STDMETHODIMP 321 IsWindowOwner(HWND hWnd) override 322 { 323 return (hWnd == m_hWnd) ? S_OK : S_FALSE; 324 } 325 326 /*****************************************************************************/ 327 328 HRESULT STDMETHODCALLTYPE Initialize(IN OUT ITrayWindow *tray, HWND hWndStartButton) 329 { 330 m_Tray = tray; 331 return S_OK; 332 } 333 334 DECLARE_NOT_AGGREGATABLE(CTaskBand) 335 336 DECLARE_PROTECT_FINAL_CONSTRUCT() 337 BEGIN_COM_MAP(CTaskBand) 338 COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand) 339 COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand) 340 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) 341 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) 342 COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream) 343 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler) 344 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) 345 END_COM_MAP() 346}; 347 348HRESULT CTaskBand_CreateInstance(IN ITrayWindow *Tray, HWND hWndStartButton, REFIID riid, void **ppv) 349{ 350 return ShellObjectCreatorInit<CTaskBand>(Tray, hWndStartButton, riid, ppv); 351}