[RSHELL]
[reactos.git] / base / shell / rshell / CMenuBand.cpp
1 /*
2 * Shell Menu Band
3 *
4 * Copyright 2014 David Quintana
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 St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20 #include "precomp.h"
21 #include "wraplog.h"
22 #include <windowsx.h>
23
24 WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand);
25
26 #define WRAP_LOG 0
27
28 #define TBSTYLE_EX_VERTICAL 4
29
30 #define TIMERID_HOTTRACK 1
31 #define SUBCLASS_ID_MENUBAND 1
32
33 extern "C" BOOL WINAPI Shell_GetImageLists(HIMAGELIST * lpBigList, HIMAGELIST * lpSmallList);
34
35 class CMenuBand;
36
37 class CMenuToolbarBase
38 {
39 public:
40 CMenuToolbarBase(CMenuBand *menuBand);
41 virtual ~CMenuToolbarBase() {}
42
43 HRESULT CreateToolbar(HWND hwndParent, DWORD dwFlags);
44 HRESULT GetWindow(HWND *phwnd);
45 HRESULT ShowWindow(BOOL fShow);
46 HRESULT Close();
47
48 BOOL IsWindowOwner(HWND hwnd) { return m_hwnd && m_hwnd == hwnd; }
49
50 virtual HRESULT FillToolbar() = 0;
51 virtual HRESULT PopupItem(UINT uItem) = 0;
52 virtual HRESULT HasSubMenu(UINT uItem) = 0;
53 virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult) = 0;
54 virtual HRESULT OnContextMenu(NMMOUSE * rclick) = 0;
55
56 HRESULT OnHotItemChange(const NMTBHOTITEM * hot);
57
58 HRESULT PopupSubMenu(UINT index, IShellMenu* childShellMenu);
59 HRESULT DoContextMenu(IContextMenu* contextMenu);
60
61 static LRESULT CALLBACK s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
62 protected:
63
64 static const UINT WM_USER_SHOWPOPUPMENU = WM_USER + 1;
65
66 LRESULT CALLBACK SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
67
68 CMenuBand *m_menuBand;
69 HWND m_hwnd;
70 DWORD m_dwMenuFlags;
71 UINT m_hotItem;
72 WNDPROC m_SubclassOld;
73 };
74
75 class CMenuStaticToolbar : public CMenuToolbarBase
76 {
77 public:
78 CMenuStaticToolbar(CMenuBand *menuBand);
79 virtual ~CMenuStaticToolbar() {}
80
81 HRESULT SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags);
82 HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
83
84 virtual HRESULT FillToolbar();
85 virtual HRESULT PopupItem(UINT uItem);
86 virtual HRESULT HasSubMenu(UINT uItem);
87 virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
88 virtual HRESULT OnContextMenu(NMMOUSE * rclick);
89
90 private:
91 HMENU m_hmenu;
92 };
93
94 class CMenuSFToolbar : public CMenuToolbarBase
95 {
96 public:
97 CMenuSFToolbar(CMenuBand *menuBand);
98 virtual ~CMenuSFToolbar();
99
100 HRESULT SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags);
101 HRESULT GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv);
102
103 virtual HRESULT FillToolbar();
104 virtual HRESULT PopupItem(UINT uItem);
105 virtual HRESULT HasSubMenu(UINT uItem);
106 virtual HRESULT OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult);
107 virtual HRESULT OnContextMenu(NMMOUSE * rclick);
108
109 private:
110 LPITEMIDLIST GetPidlFromId(UINT uItem, INT* pIndex);
111
112 IShellFolder * m_shellFolder;
113 LPCITEMIDLIST m_idList;
114 HKEY m_hKey;
115 };
116
117 class CMenuBand :
118 public CComCoClass<CMenuBand>,
119 public CComObjectRootEx<CComMultiThreadModelNoCS>,
120 public IDeskBand,
121 public IObjectWithSite,
122 public IInputObject,
123 public IPersistStream,
124 public IOleCommandTarget,
125 public IServiceProvider,
126 public IMenuPopup,
127 public IMenuBand,
128 public IShellMenu2,
129 public IWinEventHandler,
130 public IShellMenuAcc
131 {
132 public:
133 CMenuBand();
134 ~CMenuBand();
135
136 private:
137 #if WRAP_LOG
138 IUnknown * m_IUnknown;
139 IDeskBand * m_IDeskBand;
140 IDockingWindow * m_IDockingWindow;
141 IOleWindow * m_IOleWindow;
142 IObjectWithSite * m_IObjectWithSite;
143 IInputObject * m_IInputObject;
144 IPersistStream * m_IPersistStream;
145 IPersist * m_IPersist;
146 IOleCommandTarget * m_IOleCommandTarget;
147 IServiceProvider * m_IServiceProvider;
148 IMenuPopup * m_IMenuPopup;
149 IDeskBar * m_IDeskBar;
150 IMenuBand * m_IMenuBand;
151 IShellMenu2 * m_IShellMenu2;
152 IShellMenu * m_IShellMenu;
153 IWinEventHandler * m_IWinEventHandler;
154 IShellMenuAcc * m_IShellMenuAcc;
155 #else
156 IOleWindow *m_site;
157 IShellMenuCallback *m_psmc;
158
159 CMenuStaticToolbar *m_staticToolbar;
160 CMenuSFToolbar *m_SFToolbar;
161
162 UINT m_uId;
163 UINT m_uIdAncestor;
164 DWORD m_dwFlags;
165 PVOID m_UserData;
166 HMENU m_hmenu;
167 #endif
168
169 BOOL m_useBigIcons;
170
171 public:
172
173 // *** IDeskBand methods ***
174 virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi);
175
176 // *** IDockingWindow methods ***
177 virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow);
178 virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved);
179 virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved);
180
181 // *** IOleWindow methods ***
182 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
183 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
184
185 // *** IObjectWithSite methods ***
186 virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
187 virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, PVOID *ppvSite);
188
189 // *** IInputObject methods ***
190 virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg);
191 virtual HRESULT STDMETHODCALLTYPE HasFocusIO();
192 virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg);
193
194 // *** IPersistStream methods ***
195 virtual HRESULT STDMETHODCALLTYPE IsDirty();
196 virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm);
197 virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty);
198 virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize);
199
200 // *** IPersist methods ***
201 virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
202
203 // *** IOleCommandTarget methods ***
204 virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
205 virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
206
207 // *** IServiceProvider methods ***
208 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
209
210 // *** IMenuPopup methods ***
211 virtual HRESULT STDMETHODCALLTYPE Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags);
212 virtual HRESULT STDMETHODCALLTYPE OnSelect(DWORD dwSelectType);
213 virtual HRESULT STDMETHODCALLTYPE SetSubMenu(IMenuPopup *pmp, BOOL fSet);
214
215 // *** IDeskBar methods ***
216 virtual HRESULT STDMETHODCALLTYPE SetClient(IUnknown *punkClient);
217 virtual HRESULT STDMETHODCALLTYPE GetClient(IUnknown **ppunkClient);
218 virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB(RECT *prc);
219
220 // *** IMenuBand methods ***
221 virtual HRESULT STDMETHODCALLTYPE IsMenuMessage(MSG *pmsg);
222 virtual HRESULT STDMETHODCALLTYPE TranslateMenuMessage(MSG *pmsg, LRESULT *plRet);
223
224 // *** IShellMenu methods ***
225 virtual HRESULT STDMETHODCALLTYPE Initialize(IShellMenuCallback *psmc, UINT uId, UINT uIdAncestor, DWORD dwFlags);
226 virtual HRESULT STDMETHODCALLTYPE GetMenuInfo(IShellMenuCallback **ppsmc, UINT *puId, UINT *puIdAncestor, DWORD *pdwFlags);
227 virtual HRESULT STDMETHODCALLTYPE SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags);
228 virtual HRESULT STDMETHODCALLTYPE GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv);
229 virtual HRESULT STDMETHODCALLTYPE SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags);
230 virtual HRESULT STDMETHODCALLTYPE GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
231 virtual HRESULT STDMETHODCALLTYPE InvalidateItem(LPSMDATA psmd, DWORD dwFlags);
232 virtual HRESULT STDMETHODCALLTYPE GetState(LPSMDATA psmd);
233 virtual HRESULT STDMETHODCALLTYPE SetMenuToolbar(IUnknown *punk, DWORD dwFlags);
234
235 // *** IWinEventHandler methods ***
236 virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult);
237 virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd);
238
239 // *** IShellMenu2 methods ***
240 virtual HRESULT STDMETHODCALLTYPE GetSubMenu(THIS);
241 virtual HRESULT STDMETHODCALLTYPE SetToolbar(THIS);
242 virtual HRESULT STDMETHODCALLTYPE SetMinWidth(THIS);
243 virtual HRESULT STDMETHODCALLTYPE SetNoBorder(THIS);
244 virtual HRESULT STDMETHODCALLTYPE SetTheme(THIS);
245
246 // *** IShellMenuAcc methods ***
247 virtual HRESULT STDMETHODCALLTYPE GetTop(THIS);
248 virtual HRESULT STDMETHODCALLTYPE GetBottom(THIS);
249 virtual HRESULT STDMETHODCALLTYPE GetTracked(THIS);
250 virtual HRESULT STDMETHODCALLTYPE GetParentSite(THIS);
251 virtual HRESULT STDMETHODCALLTYPE GetState(THIS);
252 virtual HRESULT STDMETHODCALLTYPE DoDefaultAction(THIS);
253 virtual HRESULT STDMETHODCALLTYPE IsEmpty(THIS);
254
255 HRESULT CallCBWithId(UINT Id, UINT uMsg, WPARAM wParam, LPARAM lParam);
256 HRESULT CallCBWithPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam);
257
258 BOOL UseBigIcons() {
259 return m_useBigIcons;
260 }
261
262 DECLARE_NOT_AGGREGATABLE(CMenuBand)
263 DECLARE_PROTECT_FINAL_CONSTRUCT()
264
265 BEGIN_COM_MAP(CMenuBand)
266 COM_INTERFACE_ENTRY_IID(IID_IDeskBar, IMenuPopup)
267 COM_INTERFACE_ENTRY_IID(IID_IShellMenu, IShellMenu)
268 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
269 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IDeskBand)
270 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
271 COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
272 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
273 COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
274 COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
275 COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersistStream)
276 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
277 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup)
278 COM_INTERFACE_ENTRY_IID(IID_IMenuBand, IMenuBand)
279 COM_INTERFACE_ENTRY_IID(IID_IShellMenu2, IShellMenu2)
280 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler)
281 COM_INTERFACE_ENTRY_IID(IID_IShellMenuAcc, IShellMenuAcc)
282 END_COM_MAP()
283
284 private:
285 HRESULT _CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id = 0, LPITEMIDLIST pidl = NULL);
286 };
287
288 extern "C"
289 HRESULT CMenuBand_Constructor(REFIID riid, LPVOID *ppv)
290 {
291 *ppv = NULL;
292
293 CMenuBand * site = new CComObject<CMenuBand>();
294
295 if (!site)
296 return E_OUTOFMEMORY;
297
298 HRESULT hr = site->QueryInterface(riid, ppv);
299
300 if (FAILED(hr))
301 site->Release();
302
303 return hr;
304 }
305
306
307 #if WRAP_LOG
308 CMenuBand::CMenuBand()
309 {
310 HRESULT hr;
311 WrapLogOpen();
312
313 hr = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellMenu, &m_IShellMenu));
314 hr = m_IShellMenu->QueryInterface(IID_PPV_ARG(IUnknown, &m_IUnknown));
315 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IDeskBand, &m_IDeskBand));
316 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IDockingWindow, &m_IDockingWindow));
317 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IOleWindow, &m_IOleWindow));
318 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IObjectWithSite, &m_IObjectWithSite));
319 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IInputObject, &m_IInputObject));
320 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IPersistStream, &m_IPersistStream));
321 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IPersist, &m_IPersist));
322 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &m_IOleCommandTarget));
323 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IServiceProvider, &m_IServiceProvider));
324 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_IMenuPopup));
325 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IDeskBar, &m_IDeskBar));
326 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IMenuBand, &m_IMenuBand));
327 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IShellMenu2, &m_IShellMenu2));
328 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IWinEventHandler, &m_IWinEventHandler));
329 hr = m_IUnknown->QueryInterface(IID_PPV_ARG(IShellMenuAcc, &m_IShellMenuAcc));
330 }
331
332 CMenuBand::~CMenuBand()
333 {
334 m_IUnknown->Release();
335 m_IDeskBand->Release();
336 m_IDockingWindow->Release();
337 m_IOleWindow->Release();
338 m_IObjectWithSite->Release();
339 m_IInputObject->Release();
340 m_IPersistStream->Release();
341 m_IPersist->Release();
342 m_IOleCommandTarget->Release();
343 m_IServiceProvider->Release();
344 m_IMenuPopup->Release();
345 m_IDeskBar->Release();
346 m_IMenuBand->Release();
347 m_IShellMenu2->Release();
348 m_IShellMenu->Release();
349 m_IWinEventHandler->Release();
350 m_IShellMenuAcc->Release();
351 WrapLogClose();
352 }
353
354
355 // *** IShellMenu2 methods ***
356 HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
357 {
358 WrapLogEnter("CMenuBand<%p>::GetSubMenu()\n", this);
359 HRESULT hr = m_IShellMenu2->GetSubMenu();
360 WrapLogExit("CMenuBand::GetSubMenu() = %08x\n", hr);
361 return hr;
362 }
363
364 HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
365 {
366 WrapLogEnter("CMenuBand<%p>::SetToolbar()\n", this);
367 HRESULT hr = m_IShellMenu2->SetToolbar();
368 WrapLogExit("CMenuBand::SetToolbar() = %08x\n", hr);
369 return hr;
370 }
371
372 HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
373 {
374 WrapLogEnter("CMenuBand<%p>::SetMinWidth()\n", this);
375 HRESULT hr = m_IShellMenu2->SetMinWidth();
376 WrapLogExit("CMenuBand::SetMinWidth() = %08x\n", hr);
377 return hr;
378 }
379
380 HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
381 {
382 WrapLogEnter("CMenuBand<%p>::SetNoBorder()\n", this);
383 HRESULT hr = m_IShellMenu2->SetNoBorder();
384 WrapLogExit("CMenuBand::SetNoBorder() = %08x\n", hr);
385 return hr;
386 }
387
388 HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
389 {
390 WrapLogEnter("CMenuBand<%p>::SetTheme()\n", this);
391 HRESULT hr = m_IShellMenu2->SetTheme();
392 WrapLogExit("CMenuBand::SetTheme() = %08x\n", hr);
393 return hr;
394 }
395
396
397 // *** IShellMenuAcc methods ***
398 HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
399 {
400 WrapLogEnter("CMenuBand<%p>::GetTop()\n", this);
401 HRESULT hr = m_IShellMenuAcc->GetTop();
402 WrapLogExit("CMenuBand::GetTop() = %08x\n", hr);
403 return hr;
404 }
405
406 HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
407 {
408 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
409 HRESULT hr = m_IShellMenuAcc->GetBottom();
410 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
411 return hr;
412 }
413
414 HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
415 {
416 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
417 HRESULT hr = m_IShellMenuAcc->GetBottom();
418 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
419 return hr;
420 }
421
422 HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
423 {
424 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
425 HRESULT hr = m_IShellMenuAcc->GetBottom();
426 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
427 return hr;
428 }
429
430 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
431 {
432 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
433 HRESULT hr = m_IShellMenuAcc->GetBottom();
434 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
435 return hr;
436 }
437
438 HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
439 {
440 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
441 HRESULT hr = m_IShellMenuAcc->GetBottom();
442 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
443 return hr;
444 }
445
446 HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
447 {
448 WrapLogEnter("CMenuBand<%p>::GetBottom()\n", this);
449 HRESULT hr = m_IShellMenuAcc->GetBottom();
450 WrapLogExit("CMenuBand::GetBottom() = %08x\n", hr);
451 return hr;
452 }
453
454 // *** IDeskBand methods ***
455 HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
456 {
457 WrapLogEnter("CMenuBand<%p>::GetBandInfo(DWORD dwBandID=%d, DWORD dwViewMode=%d, DESKBANDINFO *pdbi=%p)\n", this, dwBandID, dwViewMode, pdbi);
458 HRESULT hr = m_IDeskBand->GetBandInfo(dwBandID, dwViewMode, pdbi);
459 WrapLogExit("CMenuBand::GetBandInfo() = %08x\n", hr);
460 return hr;
461 }
462
463 // *** IDockingWindow methods ***
464 HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
465 {
466 WrapLogEnter("CMenuBand<%p>::ShowDW(BOOL fShow=%d)\n", this, fShow);
467 HRESULT hr = m_IDockingWindow->ShowDW(fShow);
468 WrapLogExit("CMenuBand::ShowDW() = %08x\n", hr);
469 return hr;
470 }
471
472 HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
473 {
474 WrapLogEnter("CMenuBand<%p>::CloseDW(DWORD dwReserved=%d)\n", this, dwReserved);
475 HRESULT hr = m_IDockingWindow->CloseDW(dwReserved);
476 WrapLogExit("CMenuBand::CloseDW() = %08x\n", hr);
477 return hr;
478 }
479
480 HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
481 {
482 WrapLogEnter("CMenuBand<%p>::ResizeBorderDW(LPCRECT prcBorder=%p, IUnknown *punkToolbarSite=%p, BOOL fReserved=%d)\n", this, prcBorder, punkToolbarSite, fReserved);
483 if (prcBorder) WrapLogMsg("*prcBorder=%s\n", Wrap(*prcBorder));
484 HRESULT hr = m_IDockingWindow->ResizeBorderDW(prcBorder, punkToolbarSite, fReserved);
485 if (prcBorder) WrapLogMsg("*prcBorder=%s\n", Wrap(*prcBorder));
486 WrapLogExit("CMenuBand::ResizeBorderDW() = %08x\n", hr);
487 return hr;
488 }
489
490 // *** IOleWindow methods ***
491 HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(HWND *phwnd)
492 {
493 WrapLogEnter("CMenuBand<%p>::GetWindow(HWND *phwnd=%p)\n", this, phwnd);
494 HRESULT hr = m_IOleWindow->GetWindow(phwnd);
495 if (phwnd) WrapLogMsg("*phwnd=%p\n", *phwnd);
496 WrapLogExit("CMenuBand::GetWindow() = %08x\n", hr);
497 return hr;
498 }
499 HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
500 {
501 WrapLogEnter("CMenuBand<%p>::ContextSensitiveHelp(BOOL fEnterMode=%d)\n", this, fEnterMode);
502 HRESULT hr = m_IOleWindow->ContextSensitiveHelp(fEnterMode);
503 WrapLogExit("CMenuBand::ContextSensitiveHelp() = %08x\n", hr);
504 return hr;
505 }
506
507 // *** IWinEventHandler methods ***
508 HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
509 {
510 //WrapLogEnter("CMenuBand<%p>::OnWinEvent(HWND hWnd=%p, UINT uMsg=%u, WPARAM wParam=%08x, LPARAM lParam=%08x, LRESULT *theResult=%p)\n", this, hWnd, uMsg, wParam, lParam, theResult);
511 HRESULT hr = m_IWinEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
512 //WrapLogExit("CMenuBand::OnWinEvent() = %08x\n", hr);
513 return hr;
514 }
515
516 HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
517 {
518 //WrapLogEnter("CMenuBand<%p>::IsWindowOwner(HWND hWnd=%08x)\n", this, hWnd);
519 HRESULT hr = m_IWinEventHandler->IsWindowOwner(hWnd);
520 //WrapLogExit("CMenuBand::IsWindowOwner() = %08x\n", hr);
521 return hr;
522 }
523
524 // *** IObjectWithSite methods ***
525 HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
526 {
527 WrapLogEnter("CMenuBand<%p>::SetSite(IUnknown *pUnkSite=%p)\n", this, pUnkSite);
528 HRESULT hr = m_IObjectWithSite->SetSite(pUnkSite);
529 WrapLogExit("CMenuBand::SetSite() = %08x\n", hr);
530 return hr;
531 }
532
533 HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
534 {
535 WrapLogEnter("CMenuBand<%p>::GetSite(REFIID riid=%s, PVOID *ppvSite=%p)\n", this, Wrap(riid), ppvSite);
536 HRESULT hr = m_IObjectWithSite->GetSite(riid, ppvSite);
537 if (ppvSite) WrapLogMsg("*ppvSite=%p\n", *ppvSite);
538 WrapLogExit("CMenuBand::GetSite() = %08x\n", hr);
539 return hr;
540 }
541
542 // *** IInputObject methods ***
543 HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
544 {
545 WrapLogEnter("CMenuBand<%p>::UIActivateIO(BOOL fActivate=%d, LPMSG lpMsg=%p)\n", this, fActivate, lpMsg);
546 HRESULT hr = m_IInputObject->UIActivateIO(fActivate, lpMsg);
547 WrapLogExit("CMenuBand::UIActivateIO() = %08x\n", hr);
548 return hr;
549 }
550
551 HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
552 {
553 WrapLogEnter("CMenuBand<%p>::HasFocusIO()\n", this);
554 HRESULT hr = m_IInputObject->HasFocusIO();
555 WrapLogExit("CMenuBand::HasFocusIO() = %08x\n", hr);
556 return hr;
557 }
558
559 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
560 {
561 WrapLogEnter("CMenuBand<%p>::TranslateAcceleratorIO(LPMSG lpMsg=%p)\n", this, lpMsg);
562 if (lpMsg) WrapLogMsg("*lpMsg=%s\n", Wrap(*lpMsg));
563 HRESULT hr = m_IInputObject->TranslateAcceleratorIO(lpMsg);
564 WrapLogExit("CMenuBand::TranslateAcceleratorIO() = %08x\n", hr);
565 return hr;
566 }
567
568 // *** IPersistStream methods ***
569 HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
570 {
571 WrapLogEnter("CMenuBand<%p>::IsDirty()\n", this);
572 HRESULT hr = m_IPersistStream->IsDirty();
573 WrapLogExit("CMenuBand::IsDirty() = %08x\n", hr);
574 return hr;
575 }
576 HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
577 {
578 WrapLogEnter("CMenuBand<%p>::Load(IStream *pStm=%p)\n", this, pStm);
579 HRESULT hr = m_IPersistStream->Load(pStm);
580 WrapLogExit("CMenuBand::Load() = %08x\n", hr);
581 return hr;
582 }
583 HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
584 {
585 WrapLogEnter("CMenuBand<%p>::Save(IStream *pStm=%p, BOOL fClearDirty=%d)\n", this, pStm, fClearDirty);
586 HRESULT hr = m_IPersistStream->Save(pStm, fClearDirty);
587 WrapLogExit("CMenuBand::Save() = %08x\n", hr);
588 return hr;
589 }
590 HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
591 {
592 WrapLogEnter("CMenuBand<%p>::GetSizeMax(ULARGE_INTEGER *pcbSize=%p)\n", this, pcbSize);
593 HRESULT hr = m_IPersistStream->GetSizeMax(pcbSize);
594 WrapLogExit("CMenuBand::GetSizeMax() = %08x\n", hr);
595 return hr;
596 }
597
598 // *** IPersist methods ***
599 HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
600 {
601 WrapLogEnter("CMenuBand<%p>::GetClassID(CLSID *pClassID=%p)\n", this, pClassID);
602 HRESULT hr = m_IPersist->GetClassID(pClassID);
603 if (pClassID) WrapLogMsg("*pClassID=%s\n", Wrap(*pClassID));
604 WrapLogExit("CMenuBand::GetClassID() = %08x\n", hr);
605 return hr;
606 }
607
608 // *** IOleCommandTarget methods ***
609 HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
610 {
611 WrapLogEnter("CMenuBand<%p>::QueryStatus(const GUID *pguidCmdGroup=%p, ULONG cCmds=%u, prgCmds=%p, pCmdText=%p)\n", this, pguidCmdGroup, cCmds, prgCmds, pCmdText);
612 HRESULT hr = m_IOleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
613 if (pguidCmdGroup) WrapLogMsg("*pguidCmdGroup=%s\n", Wrap(*pguidCmdGroup));
614 WrapLogExit("CMenuBand::QueryStatus() = %08x\n", hr);
615 return hr;
616 }
617
618 HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
619 {
620 bool b;
621
622 WrapLogEnter("CMenuBand<%p>::Exec(const GUID *pguidCmdGroup=%p, DWORD nCmdID=%d, DWORD nCmdexecopt=%d, VARIANT *pvaIn=%p, VARIANT *pvaOut=%p)\n", this, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
623
624 if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
625 {
626 if (nCmdID == 19) // popup
627 {
628 b = true;
629 }
630 }
631
632
633 if (pguidCmdGroup) WrapLogMsg("*pguidCmdGroup=%s\n", Wrap(*pguidCmdGroup));
634 HRESULT hr = m_IOleCommandTarget->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
635 WrapLogExit("CMenuBand::Exec() = %08x\n", hr);
636 return hr;
637 }
638
639 // *** IServiceProvider methods ***
640 HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
641 {
642 WrapLogEnter("CMenuBand<%p>::QueryService(REFGUID guidService=%s, REFIID riid=%s, void **ppvObject=%p)\n", this, Wrap(guidService), Wrap(riid), ppvObject);
643
644 if (IsEqualIID(guidService, SID_SMenuBandChild))
645 {
646 WrapLogMsg("SID is SID_SMenuBandChild. Using QueryInterface of self instead of wrapped object.\n");
647 HRESULT hr = this->QueryInterface(riid, ppvObject);
648 if (ppvObject) WrapLogMsg("*ppvObject=%p\n", *ppvObject);
649 WrapLogExit("CMenuBand::QueryService() = %08x\n", hr);
650 return hr;
651 }
652 else
653 {
654 WrapLogMsg("SID not identified.\n");
655 }
656 HRESULT hr = m_IServiceProvider->QueryService(guidService, riid, ppvObject);
657 if (ppvObject) WrapLogMsg("*ppvObject=%p\n", *ppvObject);
658 WrapLogExit("CMenuBand::QueryService() = %08x\n", hr);
659 return hr;
660 }
661
662
663 // *** IMenuPopup methods ***
664 HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
665 {
666 WrapLogEnter("CMenuBand<%p>::Popup(POINTL *ppt=%p, RECTL *prcExclude=%p, MP_POPUPFLAGS dwFlags=%08x)\n", this, ppt, prcExclude, dwFlags);
667 HRESULT hr = m_IMenuPopup->Popup(ppt, prcExclude, dwFlags);
668 WrapLogExit("CMenuBand::Popup() = %08x\n", hr);
669 return hr;
670 }
671
672 HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
673 {
674 WrapLogEnter("CMenuBand<%p>::OnSelect(DWORD dwSelectType=%08x)\n", this, dwSelectType);
675 HRESULT hr = m_IMenuPopup->OnSelect(dwSelectType);
676 WrapLogExit("CMenuBand::OnSelect() = %08x\n", hr);
677 return hr;
678 }
679
680 HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
681 {
682 WrapLogEnter("CMenuBand<%p>::SetSubMenu(IMenuPopup *pmp=%p, BOOL fSet=%d)\n", this, pmp, fSet);
683 HRESULT hr = m_IMenuPopup->SetSubMenu(pmp, fSet);
684 WrapLogExit("CMenuBand::SetSubMenu() = %08x\n", hr);
685 return hr;
686 }
687
688
689 // *** IDeskBar methods ***
690 HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
691 {
692 WrapLogEnter("CMenuBand<%p>::SetClient(IUnknown *punkClient=%p)\n", this, punkClient);
693 HRESULT hr = m_IDeskBar->SetClient(punkClient);
694 WrapLogExit("CMenuBand::SetClient() = %08x\n", hr);
695 return hr;
696 }
697
698 HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
699 {
700 WrapLogEnter("CMenuBand<%p>::GetClient(IUnknown **ppunkClient=%p)\n", this, ppunkClient);
701 HRESULT hr = m_IDeskBar->GetClient(ppunkClient);
702 if (ppunkClient) WrapLogMsg("*ppunkClient=%p\n", *ppunkClient);
703 WrapLogExit("CMenuBand::GetClient() = %08x\n", hr);
704 return hr;
705 }
706
707 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
708 {
709 WrapLogEnter("CMenuBand<%p>::OnPosRectChangeDB(RECT *prc=%p)\n", this, prc);
710 HRESULT hr = m_IDeskBar->OnPosRectChangeDB(prc);
711 if (prc) WrapLogMsg("*prc=%s\n", Wrap(*prc));
712 WrapLogExit("CMenuBand::OnPosRectChangeDB() = %08x\n", hr);
713 return hr;
714 }
715
716
717 // *** IMenuBand methods ***
718 HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
719 {
720 //WrapLogEnter("CMenuBand<%p>::IsMenuMessage(MSG *pmsg=%p)\n", this, pmsg);
721 HRESULT hr = m_IMenuBand->IsMenuMessage(pmsg);
722 //WrapLogExit("CMenuBand::IsMenuMessage() = %08x\n", hr);
723 return hr;
724 }
725
726 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
727 {
728 //WrapLogEnter("CMenuBand<%p>::TranslateMenuMessage(MSG *pmsg=%p, LRESULT *plRet=%p)\n", this, pmsg, plRet);
729 HRESULT hr = m_IMenuBand->TranslateMenuMessage(pmsg, plRet);
730 //WrapLogExit("CMenuBand::TranslateMenuMessage(*plRet=%d) = %08x\n", *plRet, hr);
731 return hr;
732 }
733
734 // *** IShellMenu methods ***
735 HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(IShellMenuCallback *psmc, UINT uId, UINT uIdAncestor, DWORD dwFlags)
736 {
737 WrapLogEnter("CMenuBand<%p>::Initialize(IShellMenuCallback *psmc=%p, UINT uId=%u, UINT uIdAncestor=%u, DWORD dwFlags=%08x)\n", this, psmc, uId, uIdAncestor, dwFlags);
738 HRESULT hr = m_IShellMenu->Initialize(psmc, uId, uIdAncestor, dwFlags);
739 WrapLogExit("CMenuBand::Initialize() = %08x\n", hr);
740 return hr;
741 }
742
743 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(IShellMenuCallback **ppsmc, UINT *puId, UINT *puIdAncestor, DWORD *pdwFlags)
744 {
745 WrapLogEnter("CMenuBand<%p>::GetMenuInfo(IShellMenuCallback **ppsmc=%p, UINT *puId=%p, UINT *puIdAncestor=%p, DWORD *pdwFlags=%p)\n", this, ppsmc, puId, puIdAncestor, pdwFlags);
746 HRESULT hr = m_IShellMenu->GetMenuInfo(ppsmc, puId, puIdAncestor, pdwFlags);
747 if (ppsmc) WrapLogMsg("*ppsmc=%p\n", *ppsmc);
748 if (puId) WrapLogMsg("*puId=%u\n", *puId);
749 if (puIdAncestor) WrapLogMsg("*puIdAncestor=%u\n", *puIdAncestor);
750 if (pdwFlags) WrapLogMsg("*pdwFlags=%08x\n", *pdwFlags);
751 WrapLogExit("CMenuBand::GetMenuInfo() = %08x\n", hr);
752 return hr;
753 }
754
755 HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
756 {
757 WrapLogEnter("CMenuBand<%p>::SetShellFolder(IShellFolder *psf=%p, LPCITEMIDLIST pidlFolder=%p, HKEY hKey=%p, DWORD dwFlags=%08x)\n", this, psf, pidlFolder, hKey, dwFlags);
758 HRESULT hr = m_IShellMenu->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
759 WrapLogExit("CMenuBand::SetShellFolder() = %08x\n", hr);
760 return hr;
761 }
762
763 HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
764 {
765 WrapLogEnter("CMenuBand<%p>::GetShellFolder(DWORD *pdwFlags=%p, LPITEMIDLIST *ppidl=%p, REFIID riid=%s, void **ppv=%p)\n", this, pdwFlags, ppidl, Wrap(riid), ppv);
766 HRESULT hr = m_IShellMenu->GetShellFolder(pdwFlags, ppidl, riid, ppv);
767 if (pdwFlags) WrapLogMsg("*pdwFlags=%08x\n", *pdwFlags);
768 if (ppidl) WrapLogMsg("*ppidl=%p\n", *ppidl);
769 if (ppv) WrapLogMsg("*ppv=%p\n", *ppv);
770 WrapLogExit("CMenuBand::GetShellFolder() = %08x\n", hr);
771 return hr;
772 }
773
774 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags)
775 {
776 WrapLogEnter("CMenuBand<%p>::SetMenu(HMENU hmenu=%p, HWND hwnd=%p, DWORD dwFlags=%08x)\n", this, hmenu, hwnd, dwFlags);
777 HRESULT hr = m_IShellMenu->SetMenu(hmenu, hwnd, dwFlags);
778 WrapLogExit("CMenuBand::SetMenu() = %08x\n", hr);
779 return hr;
780 }
781
782 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags)
783 {
784 WrapLogEnter("CMenuBand<%p>::GetMenu(HMENU *phmenu=%p, HWND *phwnd=%p, DWORD *pdwFlags=%p)\n", this, phmenu, phwnd, pdwFlags);
785 HRESULT hr = m_IShellMenu->GetMenu(phmenu, phwnd, pdwFlags);
786 if (phmenu) WrapLogMsg("*phmenu=%p\n", *phmenu);
787 if (phwnd) WrapLogMsg("*phwnd=%p\n", *phwnd);
788 if (pdwFlags) WrapLogMsg("*pdwFlags=%08x\n", *pdwFlags);
789 WrapLogExit("CMenuBand::GetMenu() = %08x\n", hr);
790 return hr;
791 }
792
793 HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
794 {
795 WrapLogEnter("CMenuBand<%p>::InvalidateItem(LPSMDATA psmd=%p, DWORD dwFlags=%08x)\n", this, psmd, dwFlags);
796 HRESULT hr = m_IShellMenu->InvalidateItem(psmd, dwFlags);
797 WrapLogExit("CMenuBand::InvalidateItem() = %08x\n", hr);
798 return hr;
799 }
800
801 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
802 {
803 WrapLogEnter("CMenuBand<%p>::GetState(LPSMDATA psmd=%p)\n", this, psmd);
804 HRESULT hr = m_IShellMenu->GetState(psmd);
805 WrapLogExit("CMenuBand::GetState() = %08x\n", hr);
806 return hr;
807 }
808
809 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
810 {
811 WrapLogEnter("CMenuBand<%p>::SetMenuToolbar(IUnknown *punk=%p, DWORD dwFlags=%08x)\n", this, punk, dwFlags);
812 HRESULT hr = m_IShellMenu->SetMenuToolbar(punk, dwFlags);
813 WrapLogExit("CMenuBand::SetMenuToolbar() = %08x\n", hr);
814 return hr;
815 }
816 #else
817
818 CMenuToolbarBase::CMenuToolbarBase(CMenuBand *menuBand) :
819 m_menuBand(menuBand),
820 m_hwnd(NULL),
821 m_dwMenuFlags(0)
822 {
823 }
824
825 HRESULT CMenuToolbarBase::ShowWindow(BOOL fShow)
826 {
827 ::ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE);
828
829 HIMAGELIST ilBig, ilSmall;
830 Shell_GetImageLists(&ilBig, &ilSmall);
831
832 if (m_menuBand->UseBigIcons())
833 {
834 SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, (LPARAM) ilBig);
835 }
836 else
837 {
838 SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, (LPARAM) ilSmall);
839 }
840
841 return S_OK;
842 }
843
844 HRESULT CMenuToolbarBase::Close()
845 {
846 DestroyWindow(m_hwnd);
847 m_hwnd = NULL;
848 return S_OK;
849 }
850
851 HRESULT CMenuToolbarBase::CreateToolbar(HWND hwndParent, DWORD dwFlags)
852 {
853 LONG tbStyles = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
854 TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_CUSTOMERASE |
855 CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP;
856 LONG tbExStyles = TBSTYLE_EX_DOUBLEBUFFER;
857
858 if (dwFlags & SMINIT_VERTICAL)
859 {
860 tbStyles |= CCS_VERT;
861 tbExStyles |= TBSTYLE_EX_VERTICAL | WS_EX_TOOLWINDOW;
862 }
863
864 RECT rc;
865
866 if (!::GetClientRect(hwndParent, &rc) || (rc.left == rc.right) || (rc.top == rc.bottom))
867 {
868 rc.left = 0;
869 rc.top = 0;
870 rc.right = 1;
871 rc.bottom = 1;
872 }
873
874 HWND hwndToolbar = CreateWindowEx(
875 tbExStyles, TOOLBARCLASSNAMEW, NULL,
876 tbStyles, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
877 hwndParent, NULL, _AtlBaseModule.GetModuleInstance(), 0);
878
879 if (hwndToolbar == NULL)
880 return E_FAIL;
881
882 ::SetParent(hwndToolbar, hwndParent);
883
884 m_hwnd = hwndToolbar;
885
886 /* Identify the version of the used Common Controls DLL by sending the size of the TBBUTTON structure */
887 SendMessageW(m_hwnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
888
889 HIMAGELIST ilBig, ilSmall;
890 Shell_GetImageLists(&ilBig, &ilSmall);
891
892 //if (dwFlags & SMINIT_TOPLEVEL)
893 //{
894 // /* Hide the placeholders for the button images */
895 // SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, 0);
896 //}
897 //else
898 if (m_menuBand->UseBigIcons())
899 {
900 SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, (LPARAM) ilBig);
901 }
902 else
903 {
904 SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, (LPARAM) ilSmall);
905 }
906
907 SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);
908 m_SubclassOld = (WNDPROC) SetWindowLongPtr(m_hwnd, GWLP_WNDPROC, (LONG_PTR) CMenuToolbarBase::s_SubclassProc);
909
910 return S_OK;
911 }
912
913 HRESULT CMenuToolbarBase::GetWindow(HWND *phwnd)
914 {
915 if (!phwnd)
916 return E_FAIL;
917
918 *phwnd = m_hwnd;
919
920 return S_OK;
921 }
922
923 LRESULT CALLBACK CMenuToolbarBase::s_SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
924 {
925 CMenuToolbarBase * pthis = reinterpret_cast<CMenuToolbarBase *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
926 return pthis->SubclassProc(hWnd, uMsg, wParam, lParam);
927 }
928
929 LRESULT CMenuToolbarBase::SubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
930 {
931 switch (uMsg)
932 {
933 case WM_TIMER:
934 if (wParam == TIMERID_HOTTRACK)
935 {
936 PopupItem(m_hotItem);
937 KillTimer(hWnd, TIMERID_HOTTRACK);
938 }
939 }
940
941 return m_SubclassOld(hWnd, uMsg, wParam, lParam);
942 }
943
944 HRESULT CMenuToolbarBase::OnHotItemChange(const NMTBHOTITEM * hot)
945 {
946 if (hot->dwFlags & HICF_LEAVING)
947 {
948 KillTimer(m_hwnd, TIMERID_HOTTRACK);
949 }
950 else if (m_hotItem != hot->idNew)
951 {
952 if (HasSubMenu(hot->idNew) == S_OK)
953 {
954 DWORD elapsed;
955 SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &elapsed, 0);
956
957 m_hotItem = hot->idNew;
958
959 SetTimer(m_hwnd, TIMERID_HOTTRACK, elapsed, NULL);
960 }
961 }
962
963 return S_OK;
964 }
965
966 HRESULT CMenuToolbarBase::PopupSubMenu(UINT index, IShellMenu* childShellMenu)
967 {
968 IBandSite* pBandSite;
969 IDeskBar* pDeskBar;
970
971 HRESULT hr;
972
973 RECT rc;
974 if (!SendMessage(m_hwnd, TB_GETITEMRECT, index, (LPARAM) &rc))
975 return E_FAIL;
976
977 POINT a = { rc.left, rc.top };
978 POINT b = { rc.right, rc.bottom };
979
980 ClientToScreen(m_hwnd, &a);
981 ClientToScreen(m_hwnd, &b);
982
983 POINTL pt = { b.x, b.y };
984 RECTL rcl = { a.x, a.y, b.x, b.y }; // maybe-TODO: fetch client area of deskbar?
985
986
987 #ifndef USE_BUILTIN_MENUSITE
988 hr = CoCreateInstance(CLSID_MenuBandSite,
989 NULL,
990 CLSCTX_INPROC_SERVER,
991 IID_PPV_ARG(IBandSite, &pBandSite));
992 #else
993 hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite));
994 #endif
995 if (FAILED(hr))
996 return hr;
997
998 #ifndef USE_BUILTIN_MENUDESKBAR
999 hr = CoCreateInstance(CLSID_MenuDeskBar,
1000 NULL,
1001 CLSCTX_INPROC_SERVER,
1002 IID_PPV_ARG(IDeskBar, &pDeskBar));
1003 #else
1004 hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar));
1005 #endif
1006 if (FAILED(hr))
1007 return hr;
1008
1009 hr = pDeskBar->SetClient(pBandSite);
1010 if (FAILED(hr))
1011 return hr;
1012
1013 hr = pBandSite->AddBand(childShellMenu);
1014 if (FAILED(hr))
1015 return hr;
1016
1017 CComPtr<IMenuPopup> popup;
1018 hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
1019 if (FAILED(hr))
1020 return hr;
1021
1022 popup->Popup(&pt, &rcl, MPPF_TOP | MPPF_RIGHT);
1023
1024 return S_OK;
1025 }
1026
1027 HRESULT CMenuToolbarBase::DoContextMenu(IContextMenu* contextMenu)
1028 {
1029 HRESULT hr;
1030 HMENU hPopup = CreatePopupMenu();
1031
1032 if (hPopup == NULL)
1033 return E_FAIL;
1034
1035 hr = contextMenu->QueryContextMenu(hPopup, 0, 0, UINT_MAX, CMF_NORMAL);
1036 if (FAILED(hr))
1037 {
1038 DestroyMenu(hPopup);
1039 return hr;
1040 }
1041
1042 DWORD dwPos = GetMessagePos();
1043 UINT uCommand = ::TrackPopupMenu(hPopup, TPM_RETURNCMD, GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos), 0, m_hwnd, NULL);
1044 if (uCommand == 0)
1045 return S_FALSE;
1046
1047 CMINVOKECOMMANDINFO cmi = { 0 };
1048 cmi.cbSize = sizeof(cmi);
1049 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1050 cmi.hwnd = m_hwnd;
1051 hr = contextMenu->InvokeCommand(&cmi);
1052
1053 DestroyMenu(hPopup);
1054 return hr;
1055 }
1056
1057 BOOL
1058 AllocAndGetMenuString(HMENU hMenu, UINT ItemIDByPosition, WCHAR** String)
1059 {
1060 int Length;
1061
1062 Length = GetMenuStringW(hMenu, ItemIDByPosition, NULL, 0, MF_BYPOSITION);
1063
1064 if (!Length)
1065 return FALSE;
1066
1067 /* Also allocate space for the terminating NULL character */
1068 ++Length;
1069 *String = (PWSTR) HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1070
1071 GetMenuStringW(hMenu, ItemIDByPosition, *String, Length, MF_BYPOSITION);
1072
1073 return TRUE;
1074 }
1075
1076 CMenuStaticToolbar::CMenuStaticToolbar(CMenuBand *menuBand) :
1077 CMenuToolbarBase(menuBand),
1078 m_hmenu(NULL)
1079 {
1080 }
1081
1082 HRESULT CMenuStaticToolbar::GetMenu(
1083 HMENU *phmenu,
1084 HWND *phwnd,
1085 DWORD *pdwFlags)
1086 {
1087 *phmenu = m_hmenu;
1088 *phwnd = NULL;
1089 *pdwFlags = m_dwMenuFlags;
1090
1091 return S_OK;
1092 }
1093
1094 HRESULT CMenuStaticToolbar::SetMenu(
1095 HMENU hmenu,
1096 HWND hwnd,
1097 DWORD dwFlags)
1098 {
1099 m_hmenu = hmenu;
1100 m_dwMenuFlags = dwFlags;
1101
1102 return S_OK;
1103 }
1104
1105 HRESULT CMenuStaticToolbar::FillToolbar()
1106 {
1107 int i;
1108 int ic = GetMenuItemCount(m_hmenu);
1109
1110 for (i = 0; i < ic; i++)
1111 {
1112 MENUITEMINFOW info;
1113 TBBUTTON tbb = { 0 };
1114 PWSTR MenuString = NULL;
1115
1116 tbb.fsState = TBSTATE_ENABLED;
1117 tbb.fsStyle = 0;
1118
1119 info.cbSize = sizeof(info);
1120 info.fMask = MIIM_FTYPE | MIIM_ID;
1121
1122 GetMenuItemInfoW(m_hmenu, i, TRUE, &info);
1123
1124 if (info.fType == MFT_STRING)
1125 {
1126 if (!AllocAndGetMenuString(m_hmenu, i, &MenuString))
1127 return E_OUTOFMEMORY;
1128 if (::GetSubMenu(m_hmenu, i) != NULL)
1129 tbb.fsStyle |= BTNS_DROPDOWN;
1130 tbb.iString = (INT_PTR) MenuString;
1131 tbb.idCommand = info.wID;
1132
1133 SMINFO sminfo;
1134 if (info.wID >= 0 && SUCCEEDED(m_menuBand->CallCBWithId(info.wID, SMC_GETINFO, 0, (LPARAM) &sminfo)))
1135 {
1136 tbb.iBitmap = sminfo.iIcon;
1137 }
1138 }
1139 else
1140 {
1141 tbb.fsStyle |= BTNS_SEP;
1142 }
1143
1144 SendMessageW(m_hwnd, TB_ADDBUTTONS, 1, (LPARAM) (LPTBBUTTON) &tbb);
1145
1146 if (MenuString)
1147 HeapFree(GetProcessHeap(), 0, MenuString);
1148 }
1149
1150 return S_OK;
1151 }
1152
1153 HRESULT CMenuStaticToolbar::OnContextMenu(NMMOUSE * rclick)
1154 {
1155 CComPtr<IContextMenu> contextMenu;
1156 HRESULT hr = m_menuBand->CallCBWithId(rclick->dwItemSpec, SMC_GETOBJECT, (WPARAM) &IID_IContextMenu, (LPARAM) &contextMenu);
1157 if (hr != S_OK)
1158 return hr;
1159
1160 return DoContextMenu(contextMenu);
1161 }
1162
1163 HRESULT CMenuStaticToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1164 {
1165 return m_menuBand->CallCBWithId(wParam, SMC_EXEC, 0, 0);
1166 }
1167
1168 HRESULT CMenuStaticToolbar::PopupItem(UINT uItem)
1169 {
1170 CComPtr<IShellMenu> shellMenu;
1171 HRESULT hr = m_menuBand->CallCBWithId(uItem, SMC_GETOBJECT, (WPARAM) &IID_IShellMenu, (LPARAM) &shellMenu);
1172 if (FAILED(hr))
1173 return hr;
1174
1175 TBBUTTONINFO info = { 0 };
1176 info.cbSize = sizeof(TBBUTTONINFO);
1177 info.dwMask = 0;
1178 int index = SendMessage(m_hwnd, TB_GETBUTTONINFO, uItem, (LPARAM) &info);
1179 if (index < 0)
1180 return E_FAIL;
1181
1182 return PopupSubMenu(index, shellMenu);
1183 }
1184
1185 HRESULT CMenuStaticToolbar::HasSubMenu(UINT uItem)
1186 {
1187 TBBUTTONINFO info = { 0 };
1188 info.cbSize = sizeof(TBBUTTONINFO);
1189 info.dwMask = 0;
1190 int index = SendMessage(m_hwnd, TB_GETBUTTONINFO, uItem, (LPARAM) &info);
1191 if (index < 0)
1192 return E_FAIL;
1193 return ::GetSubMenu(m_hmenu, index) ? S_OK : S_FALSE;
1194 }
1195
1196 CMenuSFToolbar::CMenuSFToolbar(CMenuBand * menuBand) :
1197 CMenuToolbarBase(menuBand),
1198 m_shellFolder(NULL)
1199 {
1200 }
1201
1202 CMenuSFToolbar::~CMenuSFToolbar()
1203 {
1204 }
1205
1206 HRESULT CMenuSFToolbar::FillToolbar()
1207 {
1208 HRESULT hr;
1209 TBBUTTON tbb = { 0 };
1210 int i = 0;
1211 PWSTR MenuString;
1212
1213 tbb.fsState = TBSTATE_ENABLED;
1214 tbb.fsStyle = 0;
1215
1216 IEnumIDList * eidl;
1217 m_shellFolder->EnumObjects(m_hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &eidl);
1218
1219 LPITEMIDLIST item = (LPITEMIDLIST) CoTaskMemAlloc(sizeof(ITEMIDLIST));
1220 ULONG fetched;
1221 while ((hr = eidl->Next(1, &item, &fetched)) == S_OK)
1222 {
1223 INT index = 0;
1224 INT indexOpen = 0;
1225
1226 CComPtr<IShellItem> psi;
1227 SHCreateShellItem(NULL, m_shellFolder, item, &psi);
1228
1229 hr = psi->GetDisplayName(SIGDN_NORMALDISPLAY, &MenuString);
1230 if (FAILED(hr))
1231 return hr;
1232
1233 index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen);
1234
1235 SFGAOF attrs;
1236 hr = psi->GetAttributes(SFGAO_FOLDER, &attrs);
1237
1238 if (attrs != 0)
1239 {
1240 tbb.fsStyle |= BTNS_DROPDOWN;
1241 }
1242
1243 tbb.idCommand = i++;
1244 tbb.iString = (INT_PTR) MenuString;
1245 tbb.iBitmap = index;
1246 tbb.dwData = (DWORD_PTR) ILClone(item);
1247
1248 SendMessageW(m_hwnd, TB_ADDBUTTONS, 1, (LPARAM) (LPTBBUTTON) &tbb);
1249 HeapFree(GetProcessHeap(), 0, MenuString);
1250
1251 }
1252 CoTaskMemFree(item);
1253
1254 return hr;
1255 }
1256
1257 HRESULT CMenuSFToolbar::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
1258 {
1259 m_shellFolder = psf;
1260 m_idList = pidlFolder;
1261 m_hKey = hKey;
1262 m_dwMenuFlags = dwFlags;
1263 return S_OK;
1264 }
1265
1266 HRESULT CMenuSFToolbar::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
1267 {
1268 HRESULT hr;
1269
1270 hr = m_shellFolder->QueryInterface(riid, ppv);
1271 if (FAILED(hr))
1272 return hr;
1273
1274 if (pdwFlags)
1275 *pdwFlags = m_dwMenuFlags;
1276
1277 if (ppidl)
1278 {
1279 LPITEMIDLIST pidl = NULL;
1280
1281 if (m_idList)
1282 {
1283 pidl = ILClone(m_idList);
1284 if (!pidl)
1285 {
1286 (*(IUnknown**) ppv)->Release();
1287 return E_FAIL;
1288 }
1289 }
1290
1291 *ppidl = pidl;
1292 }
1293
1294 return hr;
1295 }
1296
1297 LPITEMIDLIST CMenuSFToolbar::GetPidlFromId(UINT uItem, INT* pIndex)
1298 {
1299 TBBUTTONINFO info = { 0 };
1300 info.cbSize = sizeof(TBBUTTONINFO);
1301 info.dwMask = 0;
1302 int index = SendMessage(m_hwnd, TB_GETBUTTONINFO, uItem, (LPARAM) &info);
1303 if (index < 0)
1304 return NULL;
1305
1306 if (pIndex)
1307 *pIndex = index;
1308
1309 TBBUTTON btn = { 0 };
1310 if (!SendMessage(m_hwnd, TB_GETBUTTON, index, (LPARAM) &btn))
1311 return NULL;
1312
1313 return (LPITEMIDLIST) btn.dwData;
1314 }
1315
1316 HRESULT CMenuSFToolbar::OnContextMenu(NMMOUSE * rclick)
1317 {
1318 HRESULT hr;
1319 CComPtr<IContextMenu> contextMenu;
1320 LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(rclick->dwItemData);
1321
1322 hr = m_shellFolder->GetUIObjectOf(m_hwnd, 1, &pidl, IID_IContextMenu, NULL, reinterpret_cast<VOID **>(&contextMenu));
1323 if (hr != S_OK)
1324 return hr;
1325
1326 return DoContextMenu(contextMenu);
1327 }
1328
1329 HRESULT CMenuSFToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1330 {
1331 return m_menuBand->CallCBWithPidl(GetPidlFromId(wParam, NULL), SMC_SFEXEC, 0, 0);
1332 }
1333
1334 HRESULT CMenuSFToolbar::PopupItem(UINT uItem)
1335 {
1336 HRESULT hr;
1337 UINT uId;
1338 UINT uIdAncestor;
1339 DWORD flags;
1340 int index;
1341 CComPtr<IShellMenuCallback> psmc;
1342 CComPtr<IShellMenu> shellMenu;
1343
1344 LPITEMIDLIST pidl = GetPidlFromId(uItem, &index);
1345
1346 if (!pidl)
1347 return E_FAIL;
1348
1349 #ifndef USE_BUILTIN_MENUBAND
1350 hr = CoCreateInstance(CLSID_MenuBand,
1351 NULL,
1352 CLSCTX_INPROC_SERVER,
1353 IID_PPV_ARG(IShellMenu, &pShellMenu));
1354 #else
1355 hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &shellMenu));
1356 #endif
1357 if (FAILED(hr))
1358 return hr;
1359
1360 m_menuBand->GetMenuInfo(&psmc, &uId, &uIdAncestor, &flags);
1361
1362 // FIXME: not sure waht to use as uId/uIdAncestor here
1363 hr = shellMenu->Initialize(psmc, 0, uId, SMINIT_VERTICAL);
1364 if (FAILED(hr))
1365 return hr;
1366
1367 CComPtr<IShellFolder> childFolder;
1368 hr = m_shellFolder->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &childFolder));
1369 if (FAILED(hr))
1370 return hr;
1371
1372 hr = shellMenu->SetShellFolder(childFolder, NULL, NULL, 0);
1373 if (FAILED(hr))
1374 return hr;
1375
1376 return PopupSubMenu(index, shellMenu);
1377 }
1378
1379 HRESULT CMenuSFToolbar::HasSubMenu(UINT uItem)
1380 {
1381 HRESULT hr;
1382 CComPtr<IShellItem> psi;
1383 SHCreateShellItem(NULL, m_shellFolder, GetPidlFromId(uItem, NULL), &psi);
1384
1385 SFGAOF attrs;
1386 hr = psi->GetAttributes(SFGAO_FOLDER, &attrs);
1387
1388 return (attrs != 0) ? S_OK : S_FALSE;
1389 }
1390
1391 CMenuBand::CMenuBand() :
1392 m_site(NULL),
1393 m_psmc(NULL),
1394 m_staticToolbar(NULL),
1395 m_SFToolbar(NULL),
1396 m_useBigIcons(FALSE)
1397 {
1398 }
1399
1400 CMenuBand::~CMenuBand()
1401 {
1402 if (m_site)
1403 m_site->Release();
1404
1405 if (m_psmc)
1406 m_psmc->Release();
1407
1408 if (m_staticToolbar)
1409 delete m_staticToolbar;
1410
1411 if (m_SFToolbar)
1412 delete m_SFToolbar;
1413 }
1414
1415 HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
1416 IShellMenuCallback *psmc,
1417 UINT uId,
1418 UINT uIdAncestor,
1419 DWORD dwFlags)
1420 {
1421 if (m_psmc)
1422 m_psmc->Release();
1423
1424 m_psmc = psmc;
1425 m_uId = uId;
1426 m_uIdAncestor = uIdAncestor;
1427 m_dwFlags = dwFlags;
1428
1429 if (m_psmc)
1430 {
1431 m_psmc->AddRef();
1432
1433 _CallCB(SMC_CREATE, 0, (LPARAM) &m_UserData);
1434 }
1435
1436 return S_OK;
1437 }
1438
1439 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
1440 IShellMenuCallback **ppsmc,
1441 UINT *puId,
1442 UINT *puIdAncestor,
1443 DWORD *pdwFlags)
1444 {
1445 if (!pdwFlags) // maybe?
1446 return E_INVALIDARG;
1447
1448 if (ppsmc)
1449 *ppsmc = m_psmc;
1450
1451 if (puId)
1452 *puId = m_uId;
1453
1454 if (puIdAncestor)
1455 *puIdAncestor = m_uIdAncestor;
1456
1457 *pdwFlags = m_dwFlags;
1458
1459 return S_OK;
1460 }
1461
1462 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(
1463 HMENU hmenu,
1464 HWND hwnd,
1465 DWORD dwFlags)
1466 {
1467 if (m_staticToolbar == NULL)
1468 {
1469 m_staticToolbar = new CMenuStaticToolbar(this);
1470 }
1471 m_hmenu = hmenu;
1472
1473 HRESULT hResult = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
1474 if (FAILED(hResult))
1475 return hResult;
1476
1477 if (m_site)
1478 {
1479 HWND hwndParent;
1480
1481 hResult = m_site->GetWindow(&hwndParent);
1482 if (FAILED(hResult))
1483 return hResult;
1484
1485 hResult = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
1486 if (FAILED(hResult))
1487 return hResult;
1488
1489 hResult = m_staticToolbar->FillToolbar();
1490 }
1491
1492 return hResult;
1493 }
1494
1495 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(
1496 HMENU *phmenu,
1497 HWND *phwnd,
1498 DWORD *pdwFlags)
1499 {
1500 if (m_staticToolbar == NULL)
1501 return E_FAIL;
1502
1503 return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags);
1504 }
1505
1506 HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
1507 {
1508 HWND hwndParent;
1509 HRESULT hResult;
1510
1511 if (m_site != NULL)
1512 m_site->Release();
1513
1514 if (pUnkSite == NULL)
1515 return S_OK;
1516
1517 hwndParent = NULL;
1518 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
1519 if (SUCCEEDED(hResult))
1520 {
1521 m_site->GetWindow(&hwndParent);
1522 m_site->Release();
1523 }
1524 if (!::IsWindow(hwndParent))
1525 return E_FAIL;
1526
1527 if (m_staticToolbar != NULL)
1528 {
1529 hResult = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
1530 if (FAILED(hResult))
1531 return hResult;
1532
1533 hResult = m_staticToolbar->FillToolbar();
1534 }
1535
1536 if (m_SFToolbar != NULL)
1537 {
1538 hResult = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
1539 if (FAILED(hResult))
1540 return hResult;
1541
1542 hResult = m_SFToolbar->FillToolbar();
1543 }
1544
1545 return S_OK;
1546 }
1547
1548 HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
1549 {
1550 if (m_site == NULL)
1551 return E_FAIL;
1552
1553 return m_site->QueryInterface(riid, ppvSite);
1554 }
1555
1556 HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(
1557 HWND *phwnd)
1558 {
1559 if (m_SFToolbar != NULL)
1560 return m_SFToolbar->GetWindow(phwnd);
1561
1562 if (m_staticToolbar != NULL)
1563 return m_staticToolbar->GetWindow(phwnd);
1564
1565 return E_FAIL;
1566 }
1567
1568 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
1569 {
1570 SIZE sizeStaticY = { 0 };
1571 SIZE sizeShlFldY = { 0 };
1572 HWND hwndStatic = NULL;
1573 HWND hwndShlFld = NULL;
1574 HRESULT hResult = S_OK;
1575
1576 if (m_staticToolbar != NULL)
1577 hResult = m_staticToolbar->GetWindow(&hwndStatic);
1578 if (FAILED(hResult))
1579 return hResult;
1580
1581 if (m_SFToolbar != NULL)
1582 hResult = m_SFToolbar->GetWindow(&hwndShlFld);
1583 if (FAILED(hResult))
1584 return hResult;
1585
1586 if (hwndStatic == NULL && hwndShlFld == NULL)
1587 return E_FAIL;
1588
1589 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStaticY);
1590 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFldY);
1591
1592 int sy = max(prc->bottom - prc->top, sizeStaticY.cy + sizeShlFldY.cy);
1593
1594 if (hwndShlFld)
1595 {
1596 SetWindowPos(hwndShlFld, NULL,
1597 prc->left,
1598 prc->top,
1599 prc->right - prc->left,
1600 sizeShlFldY.cy,
1601 0);
1602 DWORD btnSize = SendMessage(hwndShlFld, TB_GETBUTTONSIZE, 0, 0);
1603 SendMessage(hwndShlFld, TB_SETBUTTONSIZE, 0, MAKELPARAM(prc->right - prc->left, HIWORD(btnSize)));
1604 }
1605 if (hwndStatic)
1606 {
1607 SetWindowPos(hwndStatic, hwndShlFld,
1608 prc->left,
1609 prc->top + sizeShlFldY.cy,
1610 prc->right - prc->left,
1611 sy - sizeShlFldY.cy,
1612 0);
1613 DWORD btnSize = SendMessage(hwndStatic, TB_GETBUTTONSIZE, 0, 0);
1614 SendMessage(hwndStatic, TB_SETBUTTONSIZE, 0, MAKELPARAM(prc->right - prc->left, HIWORD(btnSize)));
1615 }
1616
1617 return S_OK;
1618 }
1619
1620 HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
1621 DWORD dwBandID,
1622 DWORD dwViewMode,
1623 DESKBANDINFO *pdbi)
1624 {
1625 HWND hwndStatic = NULL;
1626 HWND hwndShlFld = NULL;
1627 HRESULT hResult = S_OK;
1628
1629 if (m_staticToolbar != NULL)
1630 hResult = m_staticToolbar->GetWindow(&hwndStatic);
1631 if (FAILED(hResult))
1632 return hResult;
1633
1634 if (m_SFToolbar != NULL)
1635 hResult = m_SFToolbar->GetWindow(&hwndShlFld);
1636 if (FAILED(hResult))
1637 return hResult;
1638
1639 if (hwndStatic == NULL && hwndShlFld == NULL)
1640 return E_FAIL;
1641
1642 // HACK (?)
1643 if (pdbi->dwMask == 0)
1644 {
1645 pdbi->dwMask = DBIM_MINSIZE | DBIM_MAXSIZE | DBIM_INTEGRAL | DBIM_ACTUAL | DBIM_TITLE | DBIM_MODEFLAGS | DBIM_BKCOLOR;
1646 }
1647
1648 if (pdbi->dwMask & DBIM_MINSIZE)
1649 {
1650 SIZE sizeStatic = { 0 };
1651 SIZE sizeShlFld = { 0 };
1652
1653 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStatic);
1654 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFld);
1655
1656 pdbi->ptMinSize.x = 0;
1657 pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
1658 }
1659 if (pdbi->dwMask & DBIM_MAXSIZE)
1660 {
1661 SIZE sizeStatic = { 0 };
1662 SIZE sizeShlFld = { 0 };
1663
1664 if (hwndStatic) SendMessageW(hwndStatic, TB_GETMAXSIZE, 0, (LPARAM) &sizeStatic);
1665 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETMAXSIZE, 0, (LPARAM) &sizeShlFld);
1666
1667 pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx); // ignored
1668 pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
1669 }
1670 if (pdbi->dwMask & DBIM_INTEGRAL)
1671 {
1672 pdbi->ptIntegral.x = 0;
1673 pdbi->ptIntegral.y = 0;
1674 }
1675 if (pdbi->dwMask & DBIM_ACTUAL)
1676 {
1677 SIZE sizeStatic = { 0 };
1678 SIZE sizeShlFld = { 0 };
1679
1680 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeStatic);
1681 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeShlFld);
1682 pdbi->ptActual.x = max(sizeStatic.cx, sizeShlFld.cx);
1683
1684 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStatic);
1685 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFld);
1686 pdbi->ptActual.y = sizeStatic.cy + sizeShlFld.cy;
1687 }
1688 if (pdbi->dwMask & DBIM_TITLE)
1689 wcscpy(pdbi->wszTitle, L"");
1690 if (pdbi->dwMask & DBIM_MODEFLAGS)
1691 pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
1692 if (pdbi->dwMask & DBIM_BKCOLOR)
1693 pdbi->crBkgnd = 0;
1694 return S_OK;
1695 }
1696
1697 /* IDockingWindow */
1698 HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
1699 {
1700 HRESULT hr = S_OK;
1701
1702 if (m_staticToolbar != NULL)
1703 hr = m_staticToolbar->ShowWindow(fShow);
1704 if (FAILED(hr))
1705 return hr;
1706 if (m_SFToolbar != NULL)
1707 hr = m_SFToolbar->ShowWindow(fShow);
1708 if (FAILED(hr))
1709 return hr;
1710
1711 if (fShow)
1712 return _CallCB(SMC_INITMENU, 0, 0);
1713
1714 return S_OK;
1715 }
1716
1717 HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
1718 {
1719 ShowDW(FALSE);
1720
1721 if (m_staticToolbar != NULL)
1722 return m_staticToolbar->Close();
1723
1724 if (m_SFToolbar != NULL)
1725 return m_SFToolbar->Close();
1726
1727 return S_OK;
1728 }
1729 HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
1730 {
1731 UNIMPLEMENTED;
1732 return S_OK;
1733 }
1734
1735 HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
1736 {
1737 UNIMPLEMENTED;
1738 return S_OK;
1739 }
1740
1741 HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
1742 {
1743 UNIMPLEMENTED;
1744 return S_OK;
1745 }
1746
1747 HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
1748 {
1749 UNIMPLEMENTED;
1750 return S_OK;
1751 }
1752
1753 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
1754 {
1755 UNIMPLEMENTED;
1756 return S_OK;
1757 }
1758
1759 HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
1760 {
1761 UNIMPLEMENTED;
1762 return S_OK;
1763 }
1764
1765 HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
1766 {
1767 UNIMPLEMENTED;
1768 return S_OK;
1769 }
1770
1771 HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
1772 {
1773 UNIMPLEMENTED;
1774 return S_OK;
1775 }
1776
1777 HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
1778 {
1779 UNIMPLEMENTED;
1780 return S_OK;
1781 }
1782
1783 HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
1784 {
1785 UNIMPLEMENTED;
1786 return S_OK;
1787 }
1788
1789 HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
1790 {
1791 UNIMPLEMENTED;
1792 return S_OK;
1793 }
1794
1795 HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1796 {
1797 if (!pguidCmdGroup)
1798 return E_FAIL;
1799
1800 if (IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
1801 {
1802 if (nCmdID == 16) // set (big) icon size
1803 {
1804 this->m_useBigIcons = TRUE;
1805 return S_OK;
1806 }
1807 else if (nCmdID == 19) // popup-related
1808 {
1809 return S_FALSE;
1810 }
1811 }
1812
1813 UNIMPLEMENTED;
1814 return S_OK;
1815 }
1816
1817 HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1818 {
1819 if (IsEqualIID(guidService, SID_SMenuBandChild))
1820 return this->QueryInterface(riid, ppvObject);
1821 WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService));
1822 return E_NOINTERFACE;
1823 }
1824
1825 HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
1826 {
1827 UNIMPLEMENTED;
1828 return S_OK;
1829 }
1830
1831 HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
1832 {
1833 UNIMPLEMENTED;
1834 return S_OK;
1835 }
1836
1837 HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
1838 {
1839 UNIMPLEMENTED;
1840 return S_OK;
1841 }
1842
1843 HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
1844 {
1845 UNIMPLEMENTED;
1846 return S_OK;
1847 }
1848
1849 HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
1850 {
1851 UNIMPLEMENTED;
1852 return S_OK;
1853 }
1854
1855 HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
1856 {
1857 //UNIMPLEMENTED;
1858 //return S_OK;
1859 return S_FALSE;
1860 //return E_NOTIMPL;
1861 }
1862
1863 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
1864 {
1865 //UNIMPLEMENTED;
1866 return S_FALSE;
1867 }
1868
1869 HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
1870 {
1871 if (m_SFToolbar == NULL)
1872 {
1873 m_SFToolbar = new CMenuSFToolbar(this);
1874 }
1875
1876 HRESULT hResult = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
1877 if (FAILED(hResult))
1878 return hResult;
1879
1880 if (m_site)
1881 {
1882 HWND hwndParent;
1883
1884 hResult = m_site->GetWindow(&hwndParent);
1885 if (FAILED(hResult))
1886 return hResult;
1887
1888 hResult = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
1889 if (FAILED(hResult))
1890 return hResult;
1891
1892 hResult = m_SFToolbar->FillToolbar();
1893 }
1894
1895 return hResult;
1896 }
1897
1898 HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
1899 {
1900 if (m_SFToolbar)
1901 return m_SFToolbar->GetShellFolder(pdwFlags, ppidl, riid, ppv);
1902 return E_FAIL;
1903 }
1904
1905 HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
1906 {
1907 UNIMPLEMENTED;
1908 return S_OK;
1909 }
1910
1911 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
1912 {
1913 UNIMPLEMENTED;
1914 return S_OK;
1915 }
1916
1917 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
1918 {
1919 UNIMPLEMENTED;
1920 return S_OK;
1921 }
1922
1923 HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1924 {
1925 *theResult = 0;
1926 switch (uMsg)
1927 {
1928 case WM_COMMAND:
1929
1930 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1931 {
1932 return m_staticToolbar->OnCommand(wParam, lParam, theResult);
1933 }
1934
1935 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1936 {
1937 return m_SFToolbar->OnCommand(wParam, lParam, theResult);
1938 }
1939
1940 return S_OK;
1941
1942 case WM_NOTIFY:
1943 NMHDR * hdr = reinterpret_cast<LPNMHDR>(lParam);
1944 NMTBCUSTOMDRAW * cdraw;
1945 NMTBHOTITEM * hot;
1946 NMMOUSE * rclick;
1947 switch (hdr->code)
1948 {
1949 case TBN_HOTITEMCHANGE:
1950 hot = reinterpret_cast<LPNMTBHOTITEM>(hdr);
1951
1952 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1953 {
1954 return m_staticToolbar->OnHotItemChange(hot);
1955 }
1956
1957 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1958 {
1959 return m_SFToolbar->OnHotItemChange(hot);
1960 }
1961
1962 return S_OK;
1963
1964 case NM_RCLICK:
1965 rclick = reinterpret_cast<LPNMMOUSE>(hdr);
1966
1967 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1968 {
1969 return m_staticToolbar->OnContextMenu(rclick);
1970 }
1971
1972 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1973 {
1974 return m_SFToolbar->OnContextMenu(rclick);
1975 }
1976
1977 return S_OK;
1978 case NM_CUSTOMDRAW:
1979 cdraw = reinterpret_cast<LPNMTBCUSTOMDRAW>(hdr);
1980 switch (cdraw->nmcd.dwDrawStage)
1981 {
1982 case CDDS_PREPAINT:
1983 *theResult = CDRF_NOTIFYITEMDRAW;
1984 return S_OK;
1985
1986 case CDDS_ITEMPREPAINT:
1987
1988 cdraw->clrBtnFace = GetSysColor(COLOR_MENU);
1989 cdraw->clrBtnHighlight = GetSysColor(COLOR_MENUHILIGHT);
1990
1991 cdraw->clrText = GetSysColor(COLOR_MENUTEXT);
1992 cdraw->clrTextHighlight = GetSysColor(COLOR_HIGHLIGHTTEXT);
1993 cdraw->clrHighlightHotTrack = GetSysColor(COLOR_HIGHLIGHTTEXT);
1994
1995 RECT rc = cdraw->nmcd.rc;
1996 HDC hdc = cdraw->nmcd.hdc;
1997
1998 HBRUSH bgBrush = GetSysColorBrush(COLOR_MENU);
1999 HBRUSH hotBrush = GetSysColorBrush(COLOR_MENUHILIGHT);
2000
2001 switch (cdraw->nmcd.uItemState)
2002 {
2003 case CDIS_HOT:
2004 case CDIS_FOCUS:
2005 FillRect(hdc, &rc, hotBrush);
2006 break;
2007 default:
2008 FillRect(hdc, &rc, bgBrush);
2009 break;
2010 }
2011
2012 *theResult = TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOETCHEDEFFECT | TBCDRF_HILITEHOTTRACK | TBCDRF_NOOFFSET;
2013 return S_OK;
2014 }
2015 return S_OK;
2016 }
2017 return S_OK;
2018 }
2019
2020 return S_FALSE;
2021 }
2022
2023 HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
2024 {
2025 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
2026 return S_OK;
2027
2028 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
2029 return S_OK;
2030
2031 return S_FALSE;
2032 }
2033
2034 HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
2035 {
2036 UNIMPLEMENTED;
2037 return S_OK;
2038 }
2039
2040 HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
2041 {
2042 UNIMPLEMENTED;
2043 return S_OK;
2044 }
2045
2046 HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
2047 {
2048 UNIMPLEMENTED;
2049 return S_OK;
2050 }
2051
2052 HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
2053 {
2054 UNIMPLEMENTED;
2055 return S_OK;
2056 }
2057
2058 HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
2059 {
2060 UNIMPLEMENTED;
2061 return S_OK;
2062 }
2063
2064 HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
2065 {
2066 UNIMPLEMENTED;
2067 return S_OK;
2068 }
2069
2070 HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
2071 {
2072 UNIMPLEMENTED;
2073 return S_OK;
2074 }
2075
2076 HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
2077 {
2078 UNIMPLEMENTED;
2079 return S_OK;
2080 }
2081
2082 HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
2083 {
2084 UNIMPLEMENTED;
2085 return S_OK;
2086 }
2087
2088 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
2089 {
2090 UNIMPLEMENTED;
2091 return S_OK;
2092 }
2093
2094 HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
2095 {
2096 UNIMPLEMENTED;
2097 return S_OK;
2098 }
2099
2100 HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
2101 {
2102 UNIMPLEMENTED;
2103 return S_OK;
2104 }
2105
2106 HRESULT CMenuBand::CallCBWithId(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam)
2107 {
2108 return _CallCB(uMsg, wParam, lParam, id);
2109 }
2110
2111 HRESULT CMenuBand::CallCBWithPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam)
2112 {
2113 return _CallCB(uMsg, wParam, lParam, 0, pidl);
2114 }
2115
2116 HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPITEMIDLIST pidl)
2117 {
2118 if (!m_psmc)
2119 return S_FALSE;
2120
2121 HWND hwnd;
2122 GetWindow(&hwnd);
2123
2124 SMDATA smData = { 0 };
2125 smData.punk = static_cast<IShellMenu2*>(this);
2126 smData.uId = id;
2127 smData.uIdParent = m_uId;
2128 smData.uIdAncestor = m_uIdAncestor;
2129 smData.hwnd = hwnd;
2130 smData.pidlItem = pidl;
2131 if (m_staticToolbar)
2132 {
2133 smData.hmenu = m_hmenu;
2134 }
2135 smData.pvUserData = NULL;
2136 if (m_SFToolbar)
2137 m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
2138 HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
2139 ILFree(smData.pidlFolder);
2140 if (smData.psf)
2141 smData.psf->Release();
2142 return hr;
2143 }
2144 #endif