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