[TFTPD] Fix compilation, and use the #define MAX_SERVERS where needed instead of...
[reactos.git] / base / shell / rshell / 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
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 }