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