[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
1071 POINT a = { rc.left, rc.top };
1072 POINT b = { rc.right, rc.bottom };
1073
1074 ClientToScreen(m_hwnd, &a);
1075 ClientToScreen(m_hwnd, &b);
1076
1077 POINTL pt = { b.x, b.y };
1078 RECTL rcl = { a.x, a.y, b.x, b.y }; // maybe-TODO: fetch client area of deskbar?
1079
1080 CComPtr<IShellMenu> shellMenu;
1081 HRESULT hr = m_menuBand->CallCBWithId(uItem, SMC_GETOBJECT, (WPARAM) &IID_IShellMenu, (LPARAM) &shellMenu);
1082 if (FAILED(hr))
1083 return hr;
1084
1085 CComPtr<IMenuPopup> popup;
1086 hr = CSubMenu_Constructor(shellMenu, IID_PPV_ARG(IMenuPopup, &popup));
1087 if (FAILED(hr))
1088 return hr;
1089
1090 popup->Popup(&pt, &rcl, MPPF_TOP | MPPF_RIGHT);
1091
1092 return S_OK;
1093 }
1094
1095 HRESULT CMenuStaticToolbar::HasSubMenu(UINT uItem)
1096 {
1097 TBBUTTONINFO info = { 0 };
1098 info.cbSize = sizeof(TBBUTTONINFO);
1099 info.dwMask = 0;
1100 int index = SendMessage(m_hwnd, TB_GETBUTTONINFO, uItem, (LPARAM) &info);
1101 if (index < 0)
1102 return E_FAIL;
1103 return ::GetSubMenu(m_hmenu, index) ? S_OK : S_FALSE;
1104 }
1105
1106 CMenuSFToolbar::CMenuSFToolbar(CMenuBand * menuBand) :
1107 CMenuToolbarBase(menuBand),
1108 m_shellFolder(NULL)
1109 {
1110 }
1111
1112 CMenuSFToolbar::~CMenuSFToolbar()
1113 {
1114 }
1115
1116 HRESULT CMenuSFToolbar::FillToolbar()
1117 {
1118 HRESULT hr;
1119 TBBUTTON tbb = { 0 };
1120 int i = 0;
1121 PWSTR MenuString;
1122
1123 tbb.fsState = TBSTATE_ENABLED;
1124 tbb.fsStyle = 0;
1125
1126 IEnumIDList * eidl;
1127 m_shellFolder->EnumObjects(m_hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &eidl);
1128
1129 LPITEMIDLIST item = (LPITEMIDLIST) CoTaskMemAlloc(sizeof(ITEMIDLIST));
1130 ULONG fetched;
1131 while ((hr = eidl->Next(1, &item, &fetched)) == S_OK)
1132 {
1133 INT index = 0;
1134 INT indexOpen = 0;
1135
1136 IShellItem *psi;
1137 SHCreateShellItem(NULL, m_shellFolder, item, &psi);
1138
1139 hr = psi->GetDisplayName(SIGDN_NORMALDISPLAY, &MenuString);
1140 if (FAILED(hr))
1141 return hr;
1142
1143 index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen);
1144
1145 tbb.idCommand = i++;
1146 tbb.iString = (INT_PTR) MenuString;
1147 tbb.iBitmap = index;
1148
1149 SendMessageW(m_hwnd, TB_ADDBUTTONS, 1, (LPARAM) (LPTBBUTTON) &tbb);
1150 HeapFree(GetProcessHeap(), 0, MenuString);
1151
1152 }
1153 CoTaskMemFree(item);
1154
1155 return hr;
1156 }
1157
1158 HRESULT CMenuSFToolbar::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
1159 {
1160 m_shellFolder = psf;
1161 m_idList = pidlFolder;
1162 m_hKey = hKey;
1163 m_dwMenuFlags = dwFlags;
1164 return S_OK;
1165 }
1166
1167 HRESULT CMenuSFToolbar::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
1168 {
1169 HRESULT hr;
1170
1171 hr = m_shellFolder->QueryInterface(riid, ppv);
1172 if (FAILED(hr))
1173 return hr;
1174
1175 if (pdwFlags)
1176 *pdwFlags = m_dwMenuFlags;
1177
1178 if (ppidl)
1179 {
1180 LPITEMIDLIST pidl = NULL;
1181
1182 if (m_idList)
1183 {
1184 pidl = ILClone(m_idList);
1185 if (!pidl)
1186 {
1187 (*(IUnknown**) ppv)->Release();
1188 return E_FAIL;
1189 }
1190 }
1191
1192 *ppidl = pidl;
1193 }
1194
1195 return hr;
1196 }
1197 HRESULT CMenuSFToolbar::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1198 {
1199 // TODO: return m_menuBand->CallCBWithPidl(GetPidlFromId(wParam), SMC_SFEXEC, 0, 0);
1200 return S_OK;
1201 }
1202
1203 HRESULT CMenuSFToolbar::PopupItem(UINT uItem)
1204 {
1205 return S_OK;
1206 }
1207
1208 HRESULT CMenuSFToolbar::HasSubMenu(UINT uItem)
1209 {
1210 return S_FALSE; // GetSubMenu(m_hmenu, uItem) ? S_OK : S_FALSE;
1211 }
1212
1213 CMenuBand::CMenuBand() :
1214 m_site(NULL),
1215 m_psmc(NULL),
1216 m_staticToolbar(NULL),
1217 m_SFToolbar(NULL),
1218 m_useBigIcons(FALSE)
1219 {
1220 }
1221
1222 CMenuBand::~CMenuBand()
1223 {
1224 if (m_site)
1225 m_site->Release();
1226
1227 if (m_psmc)
1228 m_psmc->Release();
1229
1230 if (m_staticToolbar)
1231 delete m_staticToolbar;
1232
1233 if (m_SFToolbar)
1234 delete m_SFToolbar;
1235 }
1236
1237 HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
1238 IShellMenuCallback *psmc,
1239 UINT uId,
1240 UINT uIdAncestor,
1241 DWORD dwFlags)
1242 {
1243 if (m_psmc)
1244 m_psmc->Release();
1245
1246 m_psmc = psmc;
1247 m_uId = uId;
1248 m_uIdAncestor = uIdAncestor;
1249 m_dwFlags = dwFlags;
1250
1251 if (m_psmc)
1252 {
1253 m_psmc->AddRef();
1254
1255 _CallCB(SMC_CREATE, 0, (LPARAM) &m_UserData);
1256 }
1257
1258 return S_OK;
1259 }
1260
1261 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
1262 IShellMenuCallback **ppsmc,
1263 UINT *puId,
1264 UINT *puIdAncestor,
1265 DWORD *pdwFlags)
1266 {
1267 if (!pdwFlags) // maybe?
1268 return E_INVALIDARG;
1269
1270 if (ppsmc)
1271 *ppsmc = m_psmc;
1272
1273 if (puId)
1274 *puId = m_uId;
1275
1276 if (puIdAncestor)
1277 *puIdAncestor = m_uIdAncestor;
1278
1279 *pdwFlags = m_dwFlags;
1280
1281 return S_OK;
1282 }
1283
1284 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(
1285 HMENU hmenu,
1286 HWND hwnd,
1287 DWORD dwFlags)
1288 {
1289 if (m_staticToolbar == NULL)
1290 {
1291 m_staticToolbar = new CMenuStaticToolbar(this);
1292 }
1293 m_hmenu = hmenu;
1294
1295 HRESULT hResult = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
1296 if (FAILED(hResult))
1297 return hResult;
1298
1299 if (m_site)
1300 {
1301 HWND hwndParent;
1302
1303 hResult = m_site->GetWindow(&hwndParent);
1304 if (FAILED(hResult))
1305 return hResult;
1306
1307 hResult = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
1308 if (FAILED(hResult))
1309 return hResult;
1310
1311 hResult = m_staticToolbar->FillToolbar();
1312 }
1313
1314 return hResult;
1315 }
1316
1317 HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(
1318 HMENU *phmenu,
1319 HWND *phwnd,
1320 DWORD *pdwFlags)
1321 {
1322 if (m_staticToolbar == NULL)
1323 return E_FAIL;
1324
1325 return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags);
1326 }
1327
1328 HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
1329 {
1330 HWND hwndParent;
1331 HRESULT hResult;
1332
1333 if (m_site != NULL)
1334 m_site->Release();
1335
1336 if (pUnkSite == NULL)
1337 return S_OK;
1338
1339 hwndParent = NULL;
1340 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
1341 if (SUCCEEDED(hResult))
1342 {
1343 m_site->GetWindow(&hwndParent);
1344 m_site->Release();
1345 }
1346 if (!::IsWindow(hwndParent))
1347 return E_FAIL;
1348
1349 if (m_staticToolbar != NULL)
1350 {
1351 hResult = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
1352 if (FAILED(hResult))
1353 return hResult;
1354
1355 hResult = m_staticToolbar->FillToolbar();
1356 }
1357
1358 if (m_SFToolbar != NULL)
1359 {
1360 hResult = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
1361 if (FAILED(hResult))
1362 return hResult;
1363
1364 hResult = m_SFToolbar->FillToolbar();
1365 }
1366
1367 return S_OK;
1368 }
1369
1370 HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
1371 {
1372 if (m_site == NULL)
1373 return E_FAIL;
1374
1375 return m_site->QueryInterface(riid, ppvSite);
1376 }
1377
1378 HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(
1379 HWND *phwnd)
1380 {
1381 if (m_SFToolbar != NULL)
1382 return m_SFToolbar->GetWindow(phwnd);
1383
1384 if (m_staticToolbar != NULL)
1385 return m_staticToolbar->GetWindow(phwnd);
1386
1387 return E_FAIL;
1388 }
1389
1390 HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
1391 {
1392 SIZE sizeStaticX = { 0 };
1393 SIZE sizeShlFldX = { 0 };
1394 SIZE sizeStaticY = { 0 };
1395 SIZE sizeShlFldY = { 0 };
1396 HWND hwndStatic = NULL;
1397 HWND hwndShlFld = NULL;
1398 HRESULT hResult = S_OK;
1399
1400 if (m_staticToolbar != NULL)
1401 hResult = m_staticToolbar->GetWindow(&hwndStatic);
1402 if (FAILED(hResult))
1403 return hResult;
1404
1405 if (m_SFToolbar != NULL)
1406 hResult = m_SFToolbar->GetWindow(&hwndShlFld);
1407 if (FAILED(hResult))
1408 return hResult;
1409
1410 if (hwndStatic == NULL && hwndShlFld == NULL)
1411 return E_FAIL;
1412
1413 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStaticY);
1414 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFldY);
1415 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeStaticX);
1416 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeShlFldX);
1417
1418 int sy = max(prc->bottom - prc->top, sizeStaticY.cy + sizeShlFldY.cy);
1419
1420 if (hwndShlFld)
1421 {
1422 SetWindowPos(hwndShlFld, NULL,
1423 prc->left,
1424 prc->top,
1425 prc->right - prc->left,
1426 sizeShlFldY.cy,
1427 0);
1428 DWORD btnSize = SendMessage(hwndShlFld, TB_GETBUTTONSIZE, 0, 0);
1429 SendMessage(hwndShlFld, TB_SETBUTTONSIZE, 0, MAKELPARAM(prc->right - prc->left, HIWORD(btnSize)));
1430 }
1431 if (hwndStatic)
1432 {
1433 SetWindowPos(hwndStatic, hwndShlFld,
1434 prc->left,
1435 prc->top + sizeShlFldY.cy,
1436 prc->right - prc->left,
1437 sy - sizeShlFldY.cy,
1438 0);
1439 DWORD btnSize = SendMessage(hwndStatic, TB_GETBUTTONSIZE, 0, 0);
1440 SendMessage(hwndStatic, TB_SETBUTTONSIZE, 0, MAKELPARAM(prc->right - prc->left, HIWORD(btnSize)));
1441 }
1442
1443 return S_OK;
1444 }
1445
1446 HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
1447 DWORD dwBandID,
1448 DWORD dwViewMode,
1449 DESKBANDINFO *pdbi)
1450 {
1451 HWND hwndStatic = NULL;
1452 HWND hwndShlFld = NULL;
1453 HRESULT hResult = S_OK;
1454
1455 if (m_staticToolbar != NULL)
1456 hResult = m_staticToolbar->GetWindow(&hwndStatic);
1457 if (FAILED(hResult))
1458 return hResult;
1459
1460 if (m_SFToolbar != NULL)
1461 hResult = m_SFToolbar->GetWindow(&hwndShlFld);
1462 if (FAILED(hResult))
1463 return hResult;
1464
1465 if (hwndStatic == NULL && hwndShlFld == NULL)
1466 return E_FAIL;
1467
1468 // HACK (?)
1469 if (pdbi->dwMask == 0)
1470 {
1471 pdbi->dwMask = DBIM_MINSIZE | DBIM_MAXSIZE | DBIM_INTEGRAL | DBIM_ACTUAL | DBIM_TITLE | DBIM_MODEFLAGS | DBIM_BKCOLOR;
1472 }
1473
1474 if (pdbi->dwMask & DBIM_MINSIZE)
1475 {
1476 SIZE sizeStatic = { 0 };
1477 SIZE sizeShlFld = { 0 };
1478
1479 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStatic);
1480 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFld);
1481
1482 pdbi->ptMinSize.x = 0;
1483 pdbi->ptMinSize.y = sizeStatic.cy + sizeShlFld.cy;
1484 }
1485 if (pdbi->dwMask & DBIM_MAXSIZE)
1486 {
1487 SIZE sizeStatic = { 0 };
1488 SIZE sizeShlFld = { 0 };
1489
1490 if (hwndStatic) SendMessageW(hwndStatic, TB_GETMAXSIZE, 0, (LPARAM) &sizeStatic);
1491 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETMAXSIZE, 0, (LPARAM) &sizeShlFld);
1492
1493 pdbi->ptMaxSize.x = max(sizeStatic.cx, sizeShlFld.cx); // ignored
1494 pdbi->ptMaxSize.y = sizeStatic.cy + sizeShlFld.cy;
1495 }
1496 if (pdbi->dwMask & DBIM_INTEGRAL)
1497 {
1498 pdbi->ptIntegral.x = 0;
1499 pdbi->ptIntegral.y = 0;
1500 }
1501 if (pdbi->dwMask & DBIM_ACTUAL)
1502 {
1503 SIZE sizeStatic = { 0 };
1504 SIZE sizeShlFld = { 0 };
1505
1506 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeStatic);
1507 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, FALSE, (LPARAM) &sizeShlFld);
1508 pdbi->ptActual.x = max(sizeStatic.cx, sizeShlFld.cx);
1509
1510 if (hwndStatic) SendMessageW(hwndStatic, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeStatic);
1511 if (hwndShlFld) SendMessageW(hwndShlFld, TB_GETIDEALSIZE, TRUE, (LPARAM) &sizeShlFld);
1512 pdbi->ptActual.y = sizeStatic.cy + sizeShlFld.cy;
1513 }
1514 if (pdbi->dwMask & DBIM_TITLE)
1515 wcscpy(pdbi->wszTitle, L"");
1516 if (pdbi->dwMask & DBIM_MODEFLAGS)
1517 pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
1518 if (pdbi->dwMask & DBIM_BKCOLOR)
1519 pdbi->crBkgnd = 0;
1520 return S_OK;
1521 }
1522
1523 /* IDockingWindow */
1524 HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
1525 {
1526 HRESULT hr = S_OK;
1527
1528 if (m_staticToolbar != NULL)
1529 hr = m_staticToolbar->ShowWindow(fShow);
1530 if (FAILED(hr))
1531 return hr;
1532 if (m_SFToolbar != NULL)
1533 hr = m_SFToolbar->ShowWindow(fShow);
1534 if (FAILED(hr))
1535 return hr;
1536
1537 if (fShow)
1538 return _CallCB(SMC_INITMENU, 0, 0);
1539
1540 return S_OK;
1541 }
1542
1543 HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
1544 {
1545 ShowDW(FALSE);
1546
1547 if (m_staticToolbar != NULL)
1548 return m_staticToolbar->Close();
1549
1550 if (m_SFToolbar != NULL)
1551 return m_SFToolbar->Close();
1552
1553 return S_OK;
1554 }
1555 HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
1556 {
1557 UNIMPLEMENTED;
1558 return S_OK;
1559 }
1560
1561 HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
1562 {
1563 UNIMPLEMENTED;
1564 return S_OK;
1565 }
1566
1567 HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
1568 {
1569 UNIMPLEMENTED;
1570 return S_OK;
1571 }
1572
1573 HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
1574 {
1575 UNIMPLEMENTED;
1576 return S_OK;
1577 }
1578
1579 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
1580 {
1581 UNIMPLEMENTED;
1582 return S_OK;
1583 }
1584
1585 HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
1586 {
1587 UNIMPLEMENTED;
1588 return S_OK;
1589 }
1590
1591 HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
1592 {
1593 UNIMPLEMENTED;
1594 return S_OK;
1595 }
1596
1597 HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
1598 {
1599 UNIMPLEMENTED;
1600 return S_OK;
1601 }
1602
1603 HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
1604 {
1605 UNIMPLEMENTED;
1606 return S_OK;
1607 }
1608
1609 HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
1610 {
1611 UNIMPLEMENTED;
1612 return S_OK;
1613 }
1614
1615 HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
1616 {
1617 UNIMPLEMENTED;
1618 return S_OK;
1619 }
1620
1621 HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1622 {
1623 if (!pguidCmdGroup)
1624 return E_FAIL;
1625
1626 if (IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
1627 {
1628 if (nCmdID == 16) // set (big) icon size
1629 {
1630 this->m_useBigIcons = TRUE;
1631 return S_OK;
1632 }
1633 else if (nCmdID == 19) // popup-related
1634 {
1635 return S_FALSE;
1636 }
1637 }
1638
1639 UNIMPLEMENTED;
1640 return S_OK;
1641 }
1642
1643 HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
1644 {
1645 if (IsEqualIID(guidService, SID_SMenuBandChild))
1646 return this->QueryInterface(riid, ppvObject);
1647 WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService));
1648 return E_NOINTERFACE;
1649 }
1650
1651 HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
1652 {
1653 UNIMPLEMENTED;
1654 return S_OK;
1655 }
1656
1657 HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
1658 {
1659 UNIMPLEMENTED;
1660 return S_OK;
1661 }
1662
1663 HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
1664 {
1665 UNIMPLEMENTED;
1666 return S_OK;
1667 }
1668
1669 HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
1670 {
1671 UNIMPLEMENTED;
1672 return S_OK;
1673 }
1674
1675 HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
1676 {
1677 UNIMPLEMENTED;
1678 return S_OK;
1679 }
1680
1681 HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
1682 {
1683 //UNIMPLEMENTED;
1684 //return S_OK;
1685 return S_FALSE;
1686 //return E_NOTIMPL;
1687 }
1688
1689 HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
1690 {
1691 //UNIMPLEMENTED;
1692 return S_FALSE;
1693 }
1694
1695 HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
1696 {
1697 if (m_SFToolbar == NULL)
1698 {
1699 m_SFToolbar = new CMenuSFToolbar(this);
1700 }
1701
1702 HRESULT hResult = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
1703 if (FAILED(hResult))
1704 return hResult;
1705
1706 if (m_site)
1707 {
1708 HWND hwndParent;
1709
1710 hResult = m_site->GetWindow(&hwndParent);
1711 if (FAILED(hResult))
1712 return hResult;
1713
1714 hResult = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
1715 if (FAILED(hResult))
1716 return hResult;
1717
1718 hResult = m_SFToolbar->FillToolbar();
1719 }
1720
1721 return hResult;
1722 }
1723
1724 HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
1725 {
1726 if (m_SFToolbar)
1727 return m_SFToolbar->GetShellFolder(pdwFlags, ppidl, riid, ppv);
1728 return E_FAIL;
1729 }
1730
1731 HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
1732 {
1733 UNIMPLEMENTED;
1734 return S_OK;
1735 }
1736
1737 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
1738 {
1739 UNIMPLEMENTED;
1740 return S_OK;
1741 }
1742
1743 HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
1744 {
1745 UNIMPLEMENTED;
1746 return S_OK;
1747 }
1748
1749 HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
1750 {
1751 *theResult = 0;
1752 switch (uMsg)
1753 {
1754 case WM_COMMAND:
1755
1756 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1757 {
1758 return m_staticToolbar->OnCommand(wParam, lParam, theResult);
1759 }
1760
1761 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1762 {
1763 return m_SFToolbar->OnCommand(wParam, lParam, theResult);
1764 }
1765
1766 return S_OK;
1767
1768 case WM_NOTIFY:
1769 NMHDR * hdr = (LPNMHDR) lParam;
1770 NMTBCUSTOMDRAW * cdraw;
1771 NMTBHOTITEM * hot;
1772 switch (hdr->code)
1773 {
1774 case TBN_HOTITEMCHANGE:
1775 hot = (NMTBHOTITEM*) hdr;
1776
1777 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1778 {
1779 return m_staticToolbar->OnHotItemChange(hot);
1780 }
1781
1782 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1783 {
1784 return m_SFToolbar->OnHotItemChange(hot);
1785 }
1786
1787 return S_OK;
1788
1789 case NM_CUSTOMDRAW:
1790 cdraw = (LPNMTBCUSTOMDRAW) hdr;
1791 switch (cdraw->nmcd.dwDrawStage)
1792 {
1793 case CDDS_PREPAINT:
1794 *theResult = CDRF_NOTIFYITEMDRAW;
1795 return S_OK;
1796
1797 case CDDS_ITEMPREPAINT:
1798
1799 cdraw->clrBtnFace = GetSysColor(COLOR_MENU);
1800 cdraw->clrBtnHighlight = GetSysColor(COLOR_MENUHILIGHT);
1801
1802 cdraw->clrText = GetSysColor(COLOR_MENUTEXT);
1803 cdraw->clrTextHighlight = GetSysColor(COLOR_HIGHLIGHTTEXT);
1804 cdraw->clrHighlightHotTrack = GetSysColor(COLOR_HIGHLIGHTTEXT);
1805
1806 RECT rc = cdraw->nmcd.rc;
1807 HDC hdc = cdraw->nmcd.hdc;
1808
1809 HBRUSH bgBrush = GetSysColorBrush(COLOR_MENU);
1810 HBRUSH hotBrush = GetSysColorBrush(COLOR_MENUHILIGHT);
1811
1812 switch (cdraw->nmcd.uItemState)
1813 {
1814 case CDIS_HOT:
1815 case CDIS_FOCUS:
1816 FillRect(hdc, &rc, hotBrush);
1817 break;
1818 default:
1819 FillRect(hdc, &rc, bgBrush);
1820 break;
1821 }
1822
1823 *theResult = TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOETCHEDEFFECT | TBCDRF_HILITEHOTTRACK | TBCDRF_NOOFFSET;
1824 return S_OK;
1825 }
1826 return S_OK;
1827 }
1828 return S_OK;
1829 }
1830
1831 return S_FALSE;
1832 }
1833
1834 HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
1835 {
1836 if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd))
1837 return S_OK;
1838
1839 if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd))
1840 return S_OK;
1841
1842 return S_FALSE;
1843 }
1844
1845 HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
1846 {
1847 UNIMPLEMENTED;
1848 return S_OK;
1849 }
1850
1851 HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
1852 {
1853 UNIMPLEMENTED;
1854 return S_OK;
1855 }
1856
1857 HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
1858 {
1859 UNIMPLEMENTED;
1860 return S_OK;
1861 }
1862
1863 HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
1864 {
1865 UNIMPLEMENTED;
1866 return S_OK;
1867 }
1868
1869 HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
1870 {
1871 UNIMPLEMENTED;
1872 return S_OK;
1873 }
1874
1875 HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
1876 {
1877 UNIMPLEMENTED;
1878 return S_OK;
1879 }
1880
1881 HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
1882 {
1883 UNIMPLEMENTED;
1884 return S_OK;
1885 }
1886
1887 HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
1888 {
1889 UNIMPLEMENTED;
1890 return S_OK;
1891 }
1892
1893 HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
1894 {
1895 UNIMPLEMENTED;
1896 return S_OK;
1897 }
1898
1899 HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
1900 {
1901 UNIMPLEMENTED;
1902 return S_OK;
1903 }
1904
1905 HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
1906 {
1907 UNIMPLEMENTED;
1908 return S_OK;
1909 }
1910
1911 HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
1912 {
1913 UNIMPLEMENTED;
1914 return S_OK;
1915 }
1916
1917 HRESULT CMenuBand::CallCBWithId(UINT Id, UINT uMsg, WPARAM wParam, LPARAM lParam)
1918 {
1919 if (!m_psmc)
1920 return S_FALSE;
1921
1922 HWND hwnd;
1923 GetWindow(&hwnd);
1924
1925 SMDATA smData = { 0 };
1926 smData.punk = (IShellMenu2*)this;
1927 smData.uId = Id;
1928 smData.uIdParent = m_uId;
1929 smData.uIdAncestor = m_uIdAncestor;
1930 smData.hwnd = hwnd;
1931 if (m_staticToolbar)
1932 {
1933 smData.hmenu = m_hmenu;
1934 }
1935 smData.pvUserData = NULL;
1936 if (m_SFToolbar)
1937 m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
1938 HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
1939 ILFree(smData.pidlFolder);
1940 if (smData.psf)
1941 smData.psf->Release();
1942 return hr;
1943 }
1944
1945 HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
1946 {
1947 if (!m_psmc)
1948 return S_FALSE;
1949
1950 HWND hwnd;
1951 GetWindow(&hwnd);
1952
1953 SMDATA smData = { 0 };
1954 smData.punk = (IShellMenu2*)this;
1955 smData.uIdParent = m_uId;
1956 smData.uIdAncestor = m_uIdAncestor;
1957 smData.hwnd = hwnd;
1958 if (m_staticToolbar)
1959 {
1960 smData.hmenu = m_hmenu;
1961 }
1962 smData.pvUserData = NULL;
1963 if (m_SFToolbar)
1964 m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
1965 HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
1966 ILFree(smData.pidlFolder);
1967 if (smData.psf)
1968 smData.psf->Release();
1969 return hr;
1970 }
1971 #endif