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