1 /* 2 * PROJECT: ReactOS shell extensions 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/shellext/qcklnch/CQuickLaunchBand.cpp 5 * PURPOSE: Quick Launch Toolbar (Taskbar Shell Extension) 6 * PROGRAMMERS: Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com> 7 */ 8 9 10 #define WIN32_NO_STATUS 11 #define _INC_WINDOWS 12 #define COM_NO_WINDOWS_H 13 14 #define COBJMACROS 15 16 #include <windef.h> 17 #include <winbase.h> 18 #include <winreg.h> 19 #include <wingdi.h> 20 #include <winnls.h> 21 #include <wincon.h> 22 #include <shellapi.h> 23 #include <shlobj.h> 24 #include <shlobj_undoc.h> 25 #include <shlwapi.h> 26 #include <shlguid_undoc.h> 27 #include <atlbase.h> 28 #include <atlcom.h> 29 #include <atlwin.h> 30 31 #include <undocshell.h> 32 #include <shellutils.h> 33 34 #include "CQuickLaunchBand.h" 35 36 extern "C" 37 HRESULT WINAPI RSHELL_CISFBand_CreateInstance(REFIID riid, void** ppv); 38 39 // {260CB95D-4544-44F6-A079-575BAA60B72F} 40 const GUID CLSID_QuickLaunchBand = { 0x260cb95d, 0x4544, 0x44f6, { 0xa0, 0x79, 0x57, 0x5b, 0xaa, 0x60, 0xb7, 0x2f } }; 41 42 // Componenet Category Registration 43 HRESULT RegisterComCat() 44 { 45 CComPtr<ICatRegister> pcr; 46 HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr)); 47 if (SUCCEEDED(hr)) 48 { 49 CATID catid = CATID_DeskBand; 50 hr = pcr->RegisterClassImplCategories(CLSID_QuickLaunchBand, 1, &catid); 51 } 52 return hr; 53 } 54 55 HRESULT UnregisterComCat() 56 { 57 CComPtr<ICatRegister> pcr; 58 HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ICatRegister, &pcr)); 59 if (SUCCEEDED(hr)) 60 { 61 CATID catid = CATID_DeskBand; 62 hr = pcr->UnRegisterClassImplCategories(CLSID_QuickLaunchBand, 1, &catid); 63 } 64 return hr; 65 } 66 67 // Pidl Browser 68 /*++ 69 * @name PidlBrowse 70 * 71 * Opens a folder browser dialog, 72 * allowing the user to select a folder for enumeration. 73 * 74 * @param hwnd 75 * A handle to browser dialog window. 76 * @param nCSIDL 77 * A CSIDL representing the root from which the browse folder dialog shows the files and folders. 78 * 79 * @return The PIDL to selected folder. 80 * 81 *--*/ 82 LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL) 83 { 84 CComHeapPtr<ITEMIDLIST> pidlRoot; 85 86 WCHAR path[MAX_PATH]; 87 88 if (nCSIDL) 89 { 90 SHGetSpecialFolderLocation(hwnd, nCSIDL, &pidlRoot); 91 } 92 93 BROWSEINFO bi = { hwnd, pidlRoot, path, L"Choose a folder", 0, NULL, 0, 0 }; 94 LPITEMIDLIST pidlSelected = SHBrowseForFolder(&bi); 95 96 return pidlSelected; 97 } 98 99 // CQuickLaunchBand 100 101 CQuickLaunchBand::CQuickLaunchBand() {} 102 103 CQuickLaunchBand::~CQuickLaunchBand() {} 104 105 /*****************************************************************************/ 106 // ATL Construct 107 /*++ 108 * @name FinalConstruct 109 * 110 * Creates an instance of CISFBand, and initializes its Shell Folder Band for enumeration. 111 * 112 * @return The error code. 113 * 114 *--*/ 115 HRESULT CQuickLaunchBand::FinalConstruct() 116 { 117 HRESULT hr = RSHELL_CISFBand_CreateInstance(IID_PPV_ARG(IUnknown, &m_punkISFB)); 118 if (FAILED_UNEXPECTEDLY(hr)) 119 return hr; 120 121 CComPtr<IShellFolderBand> pISFB; 122 hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IShellFolderBand, &pISFB)); 123 if (FAILED_UNEXPECTEDLY(hr)) 124 return hr; 125 126 CComPtr<IShellFolder> pISF; 127 hr = SHGetDesktopFolder(&pISF); 128 if (FAILED_UNEXPECTEDLY(hr)) 129 return hr; 130 131 CComHeapPtr<ITEMIDLIST> pidl(PidlBrowse(m_hWndBro, CSIDL_DESKTOP)); 132 if (pidl == NULL) 133 return E_FAIL; 134 pISFB->InitializeSFB(pISF, pidl); 135 136 return hr; 137 } 138 139 // IObjectWithSite 140 STDMETHODIMP CQuickLaunchBand::SetSite(IUnknown *pUnkSite) 141 { 142 // Internal CISFBand Calls 143 CComPtr<IObjectWithSite> pIOWS; 144 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pIOWS)); 145 if (FAILED(hr)) 146 return hr; 147 148 return pIOWS->SetSite(pUnkSite); 149 } 150 151 STDMETHODIMP CQuickLaunchBand::GetSite(IN REFIID riid, OUT VOID **ppvSite) 152 { 153 CComPtr<IObjectWithSite> pIOWS; 154 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IObjectWithSite, &pIOWS)); 155 if (FAILED(hr)) 156 return hr; 157 158 return pIOWS->GetSite(riid, ppvSite); 159 } 160 161 /*****************************************************************************/ 162 // IDeskBand 163 STDMETHODIMP CQuickLaunchBand::GetWindow(OUT HWND *phwnd) 164 { 165 // Internal CISFBand Calls 166 CComPtr<IDeskBand> pIDB; 167 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 168 if (FAILED(hr)) 169 return hr; 170 171 return pIDB->GetWindow(phwnd); 172 } 173 174 STDMETHODIMP CQuickLaunchBand::ContextSensitiveHelp(IN BOOL fEnterMode) 175 { 176 // Internal CISFBand Calls 177 CComPtr<IDeskBand> pIDB; 178 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 179 if (FAILED(hr)) 180 return hr; 181 182 return pIDB->ContextSensitiveHelp(fEnterMode); 183 } 184 185 STDMETHODIMP CQuickLaunchBand::ShowDW(IN BOOL bShow) 186 { 187 // Internal CISFBand Calls 188 CComPtr<IDeskBand> pIDB; 189 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 190 if (FAILED(hr)) 191 return hr; 192 193 return pIDB->ShowDW(bShow); 194 } 195 196 STDMETHODIMP CQuickLaunchBand::CloseDW(IN DWORD dwReserved) 197 { 198 // Internal CISFBand Calls 199 CComPtr<IDeskBand> pIDB; 200 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 201 if (FAILED(hr)) 202 return hr; 203 204 return pIDB->CloseDW(dwReserved); 205 } 206 207 STDMETHODIMP CQuickLaunchBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved) 208 { 209 // Internal CISFBand Calls 210 CComPtr<IDeskBand> pIDB; 211 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 212 if (FAILED(hr)) 213 return hr; 214 215 return pIDB->ResizeBorderDW(prcBorder, punkToolbarSite, fReserved); 216 } 217 218 STDMETHODIMP CQuickLaunchBand::GetBandInfo(IN DWORD dwBandID, IN DWORD dwViewMode, IN OUT DESKBANDINFO *pdbi) 219 { 220 // Internal CISFBand Calls 221 CComPtr<IDeskBand> pIDB; 222 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IDeskBand, &pIDB)); 223 if (FAILED(hr)) 224 return hr; 225 226 return pIDB->GetBandInfo(dwBandID, dwViewMode, pdbi); 227 } 228 229 /*****************************************************************************/ 230 // IPersistStream 231 STDMETHODIMP CQuickLaunchBand::GetClassID(OUT CLSID *pClassID) 232 { 233 // Internal CISFBand Calls 234 CComPtr<IPersistStream> pIPS; 235 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS)); 236 if (FAILED(hr)) 237 return hr; 238 239 return pIPS->GetClassID(pClassID); 240 } 241 242 STDMETHODIMP CQuickLaunchBand::IsDirty() 243 { 244 // Internal CISFBand Calls 245 CComPtr<IPersistStream> pIPS; 246 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS)); 247 if (FAILED(hr)) 248 return hr; 249 250 return pIPS->IsDirty(); 251 } 252 253 STDMETHODIMP CQuickLaunchBand::Load(IN IStream *pStm) 254 { 255 CComPtr<IPersistStream> pIPS; 256 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS)); 257 if (FAILED(hr)) 258 return hr; 259 260 return pIPS->Load(pStm); 261 } 262 263 STDMETHODIMP CQuickLaunchBand::Save(IN IStream *pStm, IN BOOL fClearDirty) 264 { 265 // Internal CISFBand Calls 266 CComPtr<IPersistStream> pIPS; 267 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS)); 268 if (FAILED(hr)) 269 return hr; 270 271 return pIPS->Save(pStm, fClearDirty); 272 } 273 274 STDMETHODIMP CQuickLaunchBand::GetSizeMax(OUT ULARGE_INTEGER *pcbSize) 275 { 276 CComPtr<IPersistStream> pIPS; 277 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IPersistStream, &pIPS)); 278 if (FAILED(hr)) 279 return hr; 280 281 return pIPS->GetSizeMax(pcbSize); 282 } 283 284 285 /*****************************************************************************/ 286 // IWinEventHandler 287 STDMETHODIMP CQuickLaunchBand::ContainsWindow(IN HWND hWnd) 288 { 289 return E_NOTIMPL; 290 } 291 292 STDMETHODIMP CQuickLaunchBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) 293 { 294 // Internal CISFBand Calls 295 CComPtr<IWinEventHandler> pWEH; 296 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler, &pWEH)); 297 if (FAILED(hr)) 298 return hr; 299 300 return pWEH->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult); 301 } 302 303 STDMETHODIMP CQuickLaunchBand::IsWindowOwner(HWND hWnd) 304 { 305 // Internal CISFBand Calls 306 CComPtr<IWinEventHandler> pWEH; 307 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IWinEventHandler, &pWEH)); 308 if (FAILED(hr)) 309 return hr; 310 311 return pWEH->IsWindowOwner(hWnd); 312 } 313 314 /*****************************************************************************/ 315 // *** IOleCommandTarget methods *** 316 STDMETHODIMP CQuickLaunchBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) 317 { 318 // Internal CISFBand Calls 319 CComPtr<IOleCommandTarget> pOCT; 320 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOCT)); 321 if (FAILED(hr)) 322 return hr; 323 324 return pOCT->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText); 325 } 326 327 STDMETHODIMP CQuickLaunchBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) 328 { 329 // Internal CISFBand Calls 330 CComPtr<IOleCommandTarget> pOCT; 331 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pOCT)); 332 if (FAILED(hr)) 333 return hr; 334 335 return pOCT->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); 336 } 337 338 /*****************************************************************************/ 339 // *** IContextMenu *** 340 STDMETHODIMP CQuickLaunchBand::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax) 341 { 342 // Internal CISFBand Calls 343 CComPtr<IContextMenu> pICM; 344 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM)); 345 if (FAILED(hr)) 346 return hr; 347 348 return pICM->GetCommandString(idCmd, uFlags, pwReserved, pszName, cchMax); 349 } 350 351 STDMETHODIMP CQuickLaunchBand::InvokeCommand(LPCMINVOKECOMMANDINFO pici) 352 { 353 // Internal CISFBand Calls 354 CComPtr<IContextMenu> pICM; 355 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM)); 356 if (FAILED(hr)) 357 return hr; 358 359 return pICM->InvokeCommand(pici); 360 } 361 362 STDMETHODIMP CQuickLaunchBand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) 363 { 364 // Internal CISFBand Calls 365 CComPtr<IContextMenu> pICM; 366 HRESULT hr = m_punkISFB->QueryInterface(IID_PPV_ARG(IContextMenu, &pICM)); 367 if (FAILED(hr)) 368 return hr; 369 370 return pICM->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); 371 }