4 * Copyright 2014 David Quintana
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.
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.
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
23 WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand
);
25 #define TBSTYLE_EX_VERTICAL 4
27 #define TIMERID_HOTTRACK 1
28 #define SUBCLASS_ID_MENUBAND 1
30 extern "C" BOOL WINAPI
Shell_GetImageLists(HIMAGELIST
* lpBigList
, HIMAGELIST
* lpSmallList
);
34 class CMenuToolbarBase
37 CMenuToolbarBase(CMenuBand
*menuBand
);
38 virtual ~CMenuToolbarBase() {}
40 HRESULT
CreateToolbar(HWND hwndParent
, DWORD dwFlags
);
41 HRESULT
GetWindow(HWND
*phwnd
);
42 HRESULT
ShowWindow(BOOL fShow
);
45 BOOL
IsWindowOwner(HWND hwnd
) { return m_hwnd
&& m_hwnd
== hwnd
; }
47 virtual HRESULT
FillToolbar() = 0;
48 virtual HRESULT
PopupItem(UINT uItem
) = 0;
49 virtual HRESULT
HasSubMenu(UINT uItem
) = 0;
50 virtual HRESULT
OnCommand(WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
);
51 virtual HRESULT
OnContextMenu(NMMOUSE
* rclick
) = 0;
53 HRESULT
OnHotItemChange(const NMTBHOTITEM
* hot
);
55 HRESULT
PopupSubMenu(UINT index
, IShellMenu
* childShellMenu
);
56 HRESULT
PopupSubMenu(UINT index
, HMENU menu
);
57 HRESULT
DoContextMenu(IContextMenu
* contextMenu
);
59 static LRESULT CALLBACK
s_SubclassProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
62 static const UINT WM_USER_SHOWPOPUPMENU
= WM_USER
+ 1;
64 LRESULT CALLBACK
SubclassProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
66 CMenuBand
*m_menuBand
;
70 WNDPROC m_SubclassOld
;
73 class CMenuStaticToolbar
: public CMenuToolbarBase
76 CMenuStaticToolbar(CMenuBand
*menuBand
);
77 virtual ~CMenuStaticToolbar() {}
79 HRESULT
SetMenu(HMENU hmenu
, HWND hwnd
, DWORD dwFlags
);
80 HRESULT
GetMenu(HMENU
*phmenu
, HWND
*phwnd
, DWORD
*pdwFlags
);
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 virtual HRESULT
OnContextMenu(NMMOUSE
* rclick
);
92 class CMenuSFToolbar
: public CMenuToolbarBase
95 CMenuSFToolbar(CMenuBand
*menuBand
);
96 virtual ~CMenuSFToolbar();
98 HRESULT
SetShellFolder(IShellFolder
*psf
, LPCITEMIDLIST pidlFolder
, HKEY hKey
, DWORD dwFlags
);
99 HRESULT
GetShellFolder(DWORD
*pdwFlags
, LPITEMIDLIST
*ppidl
, REFIID riid
, void **ppv
);
101 virtual HRESULT
FillToolbar();
102 virtual HRESULT
PopupItem(UINT uItem
);
103 virtual HRESULT
HasSubMenu(UINT uItem
);
104 virtual HRESULT
OnCommand(WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
);
105 virtual HRESULT
OnContextMenu(NMMOUSE
* rclick
);
108 LPITEMIDLIST
GetPidlFromId(UINT uItem
, INT
* pIndex
);
110 IShellFolder
* m_shellFolder
;
111 LPCITEMIDLIST m_idList
;
116 public CComCoClass
<CMenuBand
>,
117 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
119 public IObjectWithSite
,
121 public IPersistStream
,
122 public IOleCommandTarget
,
123 public IServiceProvider
,
127 public IWinEventHandler
,
136 IShellMenuCallback
*m_psmc
;
138 CMenuStaticToolbar
*m_staticToolbar
;
139 CMenuSFToolbar
*m_SFToolbar
;
152 // *** IDeskBand methods ***
153 virtual HRESULT STDMETHODCALLTYPE
GetBandInfo(DWORD dwBandID
, DWORD dwViewMode
, DESKBANDINFO
*pdbi
);
155 // *** IDockingWindow methods ***
156 virtual HRESULT STDMETHODCALLTYPE
ShowDW(BOOL fShow
);
157 virtual HRESULT STDMETHODCALLTYPE
CloseDW(DWORD dwReserved
);
158 virtual HRESULT STDMETHODCALLTYPE
ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
);
160 // *** IOleWindow methods ***
161 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*phwnd
);
162 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
164 // *** IObjectWithSite methods ***
165 virtual HRESULT STDMETHODCALLTYPE
SetSite(IUnknown
*pUnkSite
);
166 virtual HRESULT STDMETHODCALLTYPE
GetSite(REFIID riid
, PVOID
*ppvSite
);
168 // *** IInputObject methods ***
169 virtual HRESULT STDMETHODCALLTYPE
UIActivateIO(BOOL fActivate
, LPMSG lpMsg
);
170 virtual HRESULT STDMETHODCALLTYPE
HasFocusIO();
171 virtual HRESULT STDMETHODCALLTYPE
TranslateAcceleratorIO(LPMSG lpMsg
);
173 // *** IPersistStream methods ***
174 virtual HRESULT STDMETHODCALLTYPE
IsDirty();
175 virtual HRESULT STDMETHODCALLTYPE
Load(IStream
*pStm
);
176 virtual HRESULT STDMETHODCALLTYPE
Save(IStream
*pStm
, BOOL fClearDirty
);
177 virtual HRESULT STDMETHODCALLTYPE
GetSizeMax(ULARGE_INTEGER
*pcbSize
);
179 // *** IPersist methods ***
180 virtual HRESULT STDMETHODCALLTYPE
GetClassID(CLSID
*pClassID
);
182 // *** IOleCommandTarget methods ***
183 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
);
184 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
186 // *** IServiceProvider methods ***
187 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
189 // *** IMenuPopup methods ***
190 virtual HRESULT STDMETHODCALLTYPE
Popup(POINTL
*ppt
, RECTL
*prcExclude
, MP_POPUPFLAGS dwFlags
);
191 virtual HRESULT STDMETHODCALLTYPE
OnSelect(DWORD dwSelectType
);
192 virtual HRESULT STDMETHODCALLTYPE
SetSubMenu(IMenuPopup
*pmp
, BOOL fSet
);
194 // *** IDeskBar methods ***
195 virtual HRESULT STDMETHODCALLTYPE
SetClient(IUnknown
*punkClient
);
196 virtual HRESULT STDMETHODCALLTYPE
GetClient(IUnknown
**ppunkClient
);
197 virtual HRESULT STDMETHODCALLTYPE
OnPosRectChangeDB(RECT
*prc
);
199 // *** IMenuBand methods ***
200 virtual HRESULT STDMETHODCALLTYPE
IsMenuMessage(MSG
*pmsg
);
201 virtual HRESULT STDMETHODCALLTYPE
TranslateMenuMessage(MSG
*pmsg
, LRESULT
*plRet
);
203 // *** IShellMenu methods ***
204 virtual HRESULT STDMETHODCALLTYPE
Initialize(IShellMenuCallback
*psmc
, UINT uId
, UINT uIdAncestor
, DWORD dwFlags
);
205 virtual HRESULT STDMETHODCALLTYPE
GetMenuInfo(IShellMenuCallback
**ppsmc
, UINT
*puId
, UINT
*puIdAncestor
, DWORD
*pdwFlags
);
206 virtual HRESULT STDMETHODCALLTYPE
SetShellFolder(IShellFolder
*psf
, LPCITEMIDLIST pidlFolder
, HKEY hKey
, DWORD dwFlags
);
207 virtual HRESULT STDMETHODCALLTYPE
GetShellFolder(DWORD
*pdwFlags
, LPITEMIDLIST
*ppidl
, REFIID riid
, void **ppv
);
208 virtual HRESULT STDMETHODCALLTYPE
SetMenu(HMENU hmenu
, HWND hwnd
, DWORD dwFlags
);
209 virtual HRESULT STDMETHODCALLTYPE
GetMenu(HMENU
*phmenu
, HWND
*phwnd
, DWORD
*pdwFlags
);
210 virtual HRESULT STDMETHODCALLTYPE
InvalidateItem(LPSMDATA psmd
, DWORD dwFlags
);
211 virtual HRESULT STDMETHODCALLTYPE
GetState(LPSMDATA psmd
);
212 virtual HRESULT STDMETHODCALLTYPE
SetMenuToolbar(IUnknown
*punk
, DWORD dwFlags
);
214 // *** IWinEventHandler methods ***
215 virtual HRESULT STDMETHODCALLTYPE
OnWinEvent(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
);
216 virtual HRESULT STDMETHODCALLTYPE
IsWindowOwner(HWND hWnd
);
218 // *** IShellMenu2 methods ***
219 virtual HRESULT STDMETHODCALLTYPE
GetSubMenu(THIS
);
220 virtual HRESULT STDMETHODCALLTYPE
SetToolbar(THIS
);
221 virtual HRESULT STDMETHODCALLTYPE
SetMinWidth(THIS
);
222 virtual HRESULT STDMETHODCALLTYPE
SetNoBorder(THIS
);
223 virtual HRESULT STDMETHODCALLTYPE
SetTheme(THIS
);
225 // *** IShellMenuAcc methods ***
226 virtual HRESULT STDMETHODCALLTYPE
GetTop(THIS
);
227 virtual HRESULT STDMETHODCALLTYPE
GetBottom(THIS
);
228 virtual HRESULT STDMETHODCALLTYPE
GetTracked(THIS
);
229 virtual HRESULT STDMETHODCALLTYPE
GetParentSite(THIS
);
230 virtual HRESULT STDMETHODCALLTYPE
GetState(THIS
);
231 virtual HRESULT STDMETHODCALLTYPE
DoDefaultAction(THIS
);
232 virtual HRESULT STDMETHODCALLTYPE
IsEmpty(THIS
);
234 HRESULT
CallCBWithId(UINT Id
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
235 HRESULT
CallCBWithPidl(LPITEMIDLIST pidl
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
236 HRESULT
TrackPopup(HMENU popup
, INT x
, INT y
);
239 return m_useBigIcons
;
242 DECLARE_NOT_AGGREGATABLE(CMenuBand
)
243 DECLARE_PROTECT_FINAL_CONSTRUCT()
245 BEGIN_COM_MAP(CMenuBand
)
246 COM_INTERFACE_ENTRY_IID(IID_IDeskBar
, IMenuPopup
)
247 COM_INTERFACE_ENTRY_IID(IID_IShellMenu
, IShellMenu
)
248 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
249 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IDeskBand
)
250 COM_INTERFACE_ENTRY_IID(IID_IDockingWindow
, IDockingWindow
)
251 COM_INTERFACE_ENTRY_IID(IID_IDeskBand
, IDeskBand
)
252 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite
, IObjectWithSite
)
253 COM_INTERFACE_ENTRY_IID(IID_IInputObject
, IInputObject
)
254 COM_INTERFACE_ENTRY_IID(IID_IPersistStream
, IPersistStream
)
255 COM_INTERFACE_ENTRY_IID(IID_IPersist
, IPersistStream
)
256 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
257 COM_INTERFACE_ENTRY_IID(IID_IMenuPopup
, IMenuPopup
)
258 COM_INTERFACE_ENTRY_IID(IID_IMenuBand
, IMenuBand
)
259 COM_INTERFACE_ENTRY_IID(IID_IShellMenu2
, IShellMenu2
)
260 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler
, IWinEventHandler
)
261 COM_INTERFACE_ENTRY_IID(IID_IShellMenuAcc
, IShellMenuAcc
)
265 HRESULT
_CallCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, UINT id
= 0, LPITEMIDLIST pidl
= NULL
);
269 HRESULT
CMenuBand_Constructor(REFIID riid
, LPVOID
*ppv
)
273 CMenuBand
* site
= new CComObject
<CMenuBand
>();
276 return E_OUTOFMEMORY
;
278 HRESULT hr
= site
->QueryInterface(riid
, ppv
);
286 CMenuToolbarBase::CMenuToolbarBase(CMenuBand
*menuBand
) :
287 m_menuBand(menuBand
),
293 HRESULT
CMenuToolbarBase::ShowWindow(BOOL fShow
)
295 ::ShowWindow(m_hwnd
, fShow
? SW_SHOW
: SW_HIDE
);
297 HIMAGELIST ilBig
, ilSmall
;
298 Shell_GetImageLists(&ilBig
, &ilSmall
);
300 if (m_menuBand
->UseBigIcons())
302 SendMessageW(m_hwnd
, TB_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(ilBig
));
306 SendMessageW(m_hwnd
, TB_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(ilSmall
));
312 HRESULT
CMenuToolbarBase::Close()
314 DestroyWindow(m_hwnd
);
319 HRESULT
CMenuToolbarBase::CreateToolbar(HWND hwndParent
, DWORD dwFlags
)
321 LONG tbStyles
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
322 TBSTYLE_TOOLTIPS
| TBSTYLE_TRANSPARENT
| TBSTYLE_REGISTERDROP
| TBSTYLE_LIST
| TBSTYLE_FLAT
| TBSTYLE_CUSTOMERASE
|
323 CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_NORESIZE
| CCS_TOP
;
324 LONG tbExStyles
= TBSTYLE_EX_DOUBLEBUFFER
;
326 if (dwFlags
& SMINIT_VERTICAL
)
328 tbStyles
|= CCS_VERT
;
329 tbExStyles
|= TBSTYLE_EX_VERTICAL
| WS_EX_TOOLWINDOW
;
334 if (!::GetClientRect(hwndParent
, &rc
) || (rc
.left
== rc
.right
) || (rc
.top
== rc
.bottom
))
342 HWND hwndToolbar
= CreateWindowEx(
343 tbExStyles
, TOOLBARCLASSNAMEW
, NULL
,
344 tbStyles
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
,
345 hwndParent
, NULL
, _AtlBaseModule
.GetModuleInstance(), 0);
347 if (hwndToolbar
== NULL
)
350 ::SetParent(hwndToolbar
, hwndParent
);
352 m_hwnd
= hwndToolbar
;
354 /* Identify the version of the used Common Controls DLL by sending the size of the TBBUTTON structure */
355 SendMessageW(m_hwnd
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
357 HIMAGELIST ilBig
, ilSmall
;
358 Shell_GetImageLists(&ilBig
, &ilSmall
);
360 //if (dwFlags & SMINIT_TOPLEVEL)
362 // /* Hide the placeholders for the button images */
363 // SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, 0);
366 if (m_menuBand
->UseBigIcons())
368 SendMessageW(m_hwnd
, TB_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(ilBig
));
372 SendMessageW(m_hwnd
, TB_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(ilSmall
));
375 SetWindowLongPtr(m_hwnd
, GWLP_USERDATA
, reinterpret_cast<LONG_PTR
>(this));
376 m_SubclassOld
= (WNDPROC
) SetWindowLongPtr(m_hwnd
, GWLP_WNDPROC
, reinterpret_cast<LONG_PTR
>(CMenuToolbarBase::s_SubclassProc
));
381 HRESULT
CMenuToolbarBase::GetWindow(HWND
*phwnd
)
391 LRESULT CALLBACK
CMenuToolbarBase::s_SubclassProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
393 CMenuToolbarBase
* pthis
= reinterpret_cast<CMenuToolbarBase
*>(GetWindowLongPtr(hWnd
, GWLP_USERDATA
));
394 return pthis
->SubclassProc(hWnd
, uMsg
, wParam
, lParam
);
397 LRESULT
CMenuToolbarBase::SubclassProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
402 if (wParam
== TIMERID_HOTTRACK
)
404 PopupItem(m_hotItem
);
405 KillTimer(hWnd
, TIMERID_HOTTRACK
);
409 return m_SubclassOld(hWnd
, uMsg
, wParam
, lParam
);
412 HRESULT
CMenuToolbarBase::OnHotItemChange(const NMTBHOTITEM
* hot
)
414 if (hot
->dwFlags
& HICF_LEAVING
)
416 KillTimer(m_hwnd
, TIMERID_HOTTRACK
);
418 else if (m_hotItem
!= hot
->idNew
)
420 if (HasSubMenu(hot
->idNew
) == S_OK
)
423 SystemParametersInfo(SPI_GETMENUSHOWDELAY
, 0, &elapsed
, 0);
425 m_hotItem
= hot
->idNew
;
427 SetTimer(m_hwnd
, TIMERID_HOTTRACK
, elapsed
, NULL
);
431 m_menuBand
->OnSelect(MPOS_CHILDTRACKING
);
435 HRESULT
CMenuToolbarBase::PopupSubMenu(UINT index
, IShellMenu
* childShellMenu
)
437 IBandSite
* pBandSite
;
443 if (!SendMessage(m_hwnd
, TB_GETITEMRECT
, index
, reinterpret_cast<LPARAM
>(&rc
)))
446 POINT a
= { rc
.left
, rc
.top
};
447 POINT b
= { rc
.right
, rc
.bottom
};
449 ClientToScreen(m_hwnd
, &a
);
450 ClientToScreen(m_hwnd
, &b
);
452 POINTL pt
= { b
.x
, b
.y
};
453 RECTL rcl
= { a
.x
, a
.y
, b
.x
, b
.y
}; // maybe-TODO: fetch client area of deskbar?
456 #if USE_SYSTEM_MENUSITE
457 hr
= CoCreateInstance(CLSID_MenuBandSite
,
459 CLSCTX_INPROC_SERVER
,
460 IID_PPV_ARG(IBandSite
, &pBandSite
));
462 hr
= CMenuSite_Constructor(IID_PPV_ARG(IBandSite
, &pBandSite
));
467 #if USE_SYSTEM_MENUDESKBAR
468 hr
= CoCreateInstance(CLSID_MenuDeskBar
,
470 CLSCTX_INPROC_SERVER
,
471 IID_PPV_ARG(IDeskBar
, &pDeskBar
));
472 #elif WRAP_MENUDESKBAR
473 hr
= CMenuDeskBar_Wrapper(IID_PPV_ARG(IDeskBar
, &pDeskBar
));
475 hr
= CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar
, &pDeskBar
));
480 hr
= pDeskBar
->SetClient(pBandSite
);
484 hr
= pBandSite
->AddBand(childShellMenu
);
488 CComPtr
<IMenuPopup
> popup
;
489 hr
= pDeskBar
->QueryInterface(IID_PPV_ARG(IMenuPopup
, &popup
));
493 popup
->Popup(&pt
, &rcl
, MPPF_TOP
| MPPF_RIGHT
);
498 HRESULT
CMenuToolbarBase::PopupSubMenu(UINT index
, HMENU menu
)
502 if (!SendMessage(m_hwnd
, TB_GETITEMRECT
, index
, reinterpret_cast<LPARAM
>(&rc
)))
505 POINT b
= { rc
.right
, rc
.bottom
};
507 ClientToScreen(m_hwnd
, &b
);
509 HMENU popup
= GetSubMenu(menu
, index
);
511 m_menuBand
->TrackPopup(popup
, b
.x
, b
.y
);
516 HRESULT
CMenuToolbarBase::DoContextMenu(IContextMenu
* contextMenu
)
519 HMENU hPopup
= CreatePopupMenu();
524 hr
= contextMenu
->QueryContextMenu(hPopup
, 0, 0, UINT_MAX
, CMF_NORMAL
);
531 DWORD dwPos
= GetMessagePos();
532 UINT uCommand
= ::TrackPopupMenu(hPopup
, TPM_RETURNCMD
, GET_X_LPARAM(dwPos
), GET_Y_LPARAM(dwPos
), 0, m_hwnd
, NULL
);
536 CMINVOKECOMMANDINFO cmi
= { 0 };
537 cmi
.cbSize
= sizeof(cmi
);
538 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
540 hr
= contextMenu
->InvokeCommand(&cmi
);
546 HRESULT
CMenuToolbarBase::OnCommand(WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
548 m_menuBand
->OnSelect(MPOS_EXECUTE
);
553 AllocAndGetMenuString(HMENU hMenu
, UINT ItemIDByPosition
, WCHAR
** String
)
557 Length
= GetMenuStringW(hMenu
, ItemIDByPosition
, NULL
, 0, MF_BYPOSITION
);
562 /* Also allocate space for the terminating NULL character */
564 *String
= (PWSTR
) HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
566 GetMenuStringW(hMenu
, ItemIDByPosition
, *String
, Length
, MF_BYPOSITION
);
571 CMenuStaticToolbar::CMenuStaticToolbar(CMenuBand
*menuBand
) :
572 CMenuToolbarBase(menuBand
),
577 HRESULT
CMenuStaticToolbar::GetMenu(
584 *pdwFlags
= m_dwMenuFlags
;
589 HRESULT
CMenuStaticToolbar::SetMenu(
595 m_dwMenuFlags
= dwFlags
;
600 HRESULT
CMenuStaticToolbar::FillToolbar()
603 int ic
= GetMenuItemCount(m_hmenu
);
605 for (i
= 0; i
< ic
; i
++)
608 TBBUTTON tbb
= { 0 };
609 PWSTR MenuString
= NULL
;
611 tbb
.fsState
= TBSTATE_ENABLED
;
614 info
.cbSize
= sizeof(info
);
615 info
.fMask
= MIIM_FTYPE
| MIIM_ID
;
617 GetMenuItemInfoW(m_hmenu
, i
, TRUE
, &info
);
619 if (info
.fType
== MFT_STRING
)
621 if (!AllocAndGetMenuString(m_hmenu
, i
, &MenuString
))
622 return E_OUTOFMEMORY
;
623 if (::GetSubMenu(m_hmenu
, i
) != NULL
)
624 tbb
.fsStyle
|= BTNS_DROPDOWN
;
625 tbb
.iString
= (INT_PTR
) MenuString
;
626 tbb
.idCommand
= info
.wID
;
628 SMINFO
* sminfo
= new SMINFO();
629 sminfo
->dwMask
= SMIM_ICON
| SMIM_FLAGS
;
630 if (SUCCEEDED(m_menuBand
->CallCBWithId(info
.wID
, SMC_GETINFO
, 0, reinterpret_cast<LPARAM
>(sminfo
))))
632 tbb
.iBitmap
= sminfo
->iIcon
;
633 tbb
.dwData
= reinterpret_cast<DWORD_PTR
>(sminfo
);
634 // FIXME: remove before deleting the toolbar or it will leak
639 tbb
.fsStyle
|= BTNS_SEP
;
642 SendMessageW(m_hwnd
, TB_ADDBUTTONS
, 1, reinterpret_cast<LPARAM
>(&tbb
));
645 HeapFree(GetProcessHeap(), 0, MenuString
);
651 HRESULT
CMenuStaticToolbar::OnContextMenu(NMMOUSE
* rclick
)
653 CComPtr
<IContextMenu
> contextMenu
;
654 HRESULT hr
= m_menuBand
->CallCBWithId(rclick
->dwItemSpec
, SMC_GETOBJECT
, reinterpret_cast<WPARAM
>(&IID_IContextMenu
), reinterpret_cast<LPARAM
>(&contextMenu
));
658 return DoContextMenu(contextMenu
);
661 HRESULT
CMenuStaticToolbar::OnCommand(WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
663 HRESULT hr
= m_menuBand
->CallCBWithId(wParam
, SMC_EXEC
, 0, 0);
667 return CMenuToolbarBase::OnCommand(wParam
, lParam
, theResult
);
670 HRESULT
CMenuStaticToolbar::PopupItem(UINT uItem
)
672 TBBUTTONINFO info
= { 0 };
673 info
.cbSize
= sizeof(TBBUTTONINFO
);
675 int index
= SendMessage(m_hwnd
, TB_GETBUTTONINFO
, uItem
, reinterpret_cast<LPARAM
>(&info
));
679 TBBUTTON btn
= { 0 };
680 SendMessage(m_hwnd
, TB_GETBUTTON
, index
, reinterpret_cast<LPARAM
>(&btn
));
682 SMINFO
* nfo
= reinterpret_cast<SMINFO
*>(btn
.dwData
);
686 if (nfo
->dwFlags
&SMIF_TRACKPOPUP
)
688 return PopupSubMenu(index
, m_hmenu
);
692 CComPtr
<IShellMenu
> shellMenu
;
693 HRESULT hr
= m_menuBand
->CallCBWithId(uItem
, SMC_GETOBJECT
, reinterpret_cast<WPARAM
>(&IID_IShellMenu
), reinterpret_cast<LPARAM
>(&shellMenu
));
697 return PopupSubMenu(index
, shellMenu
);
701 HRESULT
CMenuStaticToolbar::HasSubMenu(UINT uItem
)
703 TBBUTTONINFO info
= { 0 };
704 info
.cbSize
= sizeof(TBBUTTONINFO
);
706 int index
= SendMessage(m_hwnd
, TB_GETBUTTONINFO
, uItem
, reinterpret_cast<LPARAM
>(&info
));
709 return ::GetSubMenu(m_hmenu
, index
) ? S_OK
: S_FALSE
;
712 CMenuSFToolbar::CMenuSFToolbar(CMenuBand
* menuBand
) :
713 CMenuToolbarBase(menuBand
),
718 CMenuSFToolbar::~CMenuSFToolbar()
722 HRESULT
CMenuSFToolbar::FillToolbar()
725 TBBUTTON tbb
= { 0 };
729 tbb
.fsState
= TBSTATE_ENABLED
;
733 m_shellFolder
->EnumObjects(m_hwnd
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, &eidl
);
735 LPITEMIDLIST item
= static_cast<LPITEMIDLIST
>(CoTaskMemAlloc(sizeof(ITEMIDLIST
)));
737 while ((hr
= eidl
->Next(1, &item
, &fetched
)) == S_OK
)
742 CComPtr
<IShellItem
> psi
;
743 SHCreateShellItem(NULL
, m_shellFolder
, item
, &psi
);
745 hr
= psi
->GetDisplayName(SIGDN_NORMALDISPLAY
, &MenuString
);
749 index
= SHMapPIDLToSystemImageListIndex(m_shellFolder
, item
, &indexOpen
);
752 hr
= psi
->GetAttributes(SFGAO_FOLDER
, &attrs
);
756 tbb
.fsStyle
|= BTNS_DROPDOWN
;
760 tbb
.iString
= (INT_PTR
) MenuString
;
762 tbb
.dwData
= reinterpret_cast<DWORD_PTR
>(ILClone(item
));
763 // FIXME: remove before deleting the toolbar or it will leak
765 SendMessageW(m_hwnd
, TB_ADDBUTTONS
, 1, reinterpret_cast<LPARAM
>(&tbb
));
766 HeapFree(GetProcessHeap(), 0, MenuString
);
774 HRESULT
CMenuSFToolbar::SetShellFolder(IShellFolder
*psf
, LPCITEMIDLIST pidlFolder
, HKEY hKey
, DWORD dwFlags
)
777 m_idList
= pidlFolder
;
779 m_dwMenuFlags
= dwFlags
;
783 HRESULT
CMenuSFToolbar::GetShellFolder(DWORD
*pdwFlags
, LPITEMIDLIST
*ppidl
, REFIID riid
, void **ppv
)
787 hr
= m_shellFolder
->QueryInterface(riid
, ppv
);
792 *pdwFlags
= m_dwMenuFlags
;
796 LPITEMIDLIST pidl
= NULL
;
800 pidl
= ILClone(m_idList
);
803 (*(IUnknown
**) ppv
)->Release();
814 LPITEMIDLIST
CMenuSFToolbar::GetPidlFromId(UINT uItem
, INT
* pIndex
)
816 TBBUTTONINFO info
= { 0 };
817 info
.cbSize
= sizeof(TBBUTTONINFO
);
819 int index
= SendMessage(m_hwnd
, TB_GETBUTTONINFO
, uItem
, reinterpret_cast<LPARAM
>(&info
));
826 TBBUTTON btn
= { 0 };
827 if (!SendMessage(m_hwnd
, TB_GETBUTTON
, index
, reinterpret_cast<LPARAM
>(&btn
)))
830 return reinterpret_cast<LPITEMIDLIST
>(btn
.dwData
);
833 HRESULT
CMenuSFToolbar::OnContextMenu(NMMOUSE
* rclick
)
836 CComPtr
<IContextMenu
> contextMenu
;
837 LPCITEMIDLIST pidl
= reinterpret_cast<LPCITEMIDLIST
>(rclick
->dwItemData
);
839 hr
= m_shellFolder
->GetUIObjectOf(m_hwnd
, 1, &pidl
, IID_IContextMenu
, NULL
, reinterpret_cast<VOID
**>(&contextMenu
));
843 return DoContextMenu(contextMenu
);
846 HRESULT
CMenuSFToolbar::OnCommand(WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
848 return m_menuBand
->CallCBWithPidl(GetPidlFromId(wParam
, NULL
), SMC_SFEXEC
, 0, 0);
851 HRESULT
CMenuSFToolbar::PopupItem(UINT uItem
)
858 CComPtr
<IShellMenuCallback
> psmc
;
859 CComPtr
<IShellMenu
> shellMenu
;
861 LPITEMIDLIST pidl
= GetPidlFromId(uItem
, &index
);
866 #if USE_SYSTEM_MENUBAND
867 hr
= CoCreateInstance(CLSID_MenuBand
,
869 CLSCTX_INPROC_SERVER
,
870 IID_PPV_ARG(IShellMenu
, &shellMenu
));
872 hr
= CMenuBand_Wrapper(IID_PPV_ARG(IShellMenu
, &shellMenu
));
874 hr
= CMenuBand_Constructor(IID_PPV_ARG(IShellMenu
, &shellMenu
));
879 m_menuBand
->GetMenuInfo(&psmc
, &uId
, &uIdAncestor
, &flags
);
881 // FIXME: not sure waht to use as uId/uIdAncestor here
882 hr
= shellMenu
->Initialize(psmc
, 0, uId
, SMINIT_VERTICAL
);
886 CComPtr
<IShellFolder
> childFolder
;
887 hr
= m_shellFolder
->BindToObject(pidl
, NULL
, IID_PPV_ARG(IShellFolder
, &childFolder
));
891 hr
= shellMenu
->SetShellFolder(childFolder
, NULL
, NULL
, 0);
895 return PopupSubMenu(index
, shellMenu
);
898 HRESULT
CMenuSFToolbar::HasSubMenu(UINT uItem
)
901 CComPtr
<IShellItem
> psi
;
902 SHCreateShellItem(NULL
, m_shellFolder
, GetPidlFromId(uItem
, NULL
), &psi
);
905 hr
= psi
->GetAttributes(SFGAO_FOLDER
, &attrs
);
909 return (attrs
!= 0) ? S_OK
: S_FALSE
;
912 CMenuBand::CMenuBand() :
915 m_staticToolbar(NULL
),
921 CMenuBand::~CMenuBand()
930 delete m_staticToolbar
;
936 HRESULT STDMETHODCALLTYPE
CMenuBand::Initialize(
937 IShellMenuCallback
*psmc
,
947 m_uIdAncestor
= uIdAncestor
;
954 _CallCB(SMC_CREATE
, 0, reinterpret_cast<LPARAM
>(&m_UserData
));
960 HRESULT STDMETHODCALLTYPE
CMenuBand::GetMenuInfo(
961 IShellMenuCallback
**ppsmc
,
966 if (!pdwFlags
) // maybe?
976 *puIdAncestor
= m_uIdAncestor
;
978 *pdwFlags
= m_dwFlags
;
983 HRESULT STDMETHODCALLTYPE
CMenuBand::SetMenu(
988 if (m_staticToolbar
== NULL
)
990 m_staticToolbar
= new CMenuStaticToolbar(this);
995 HRESULT hResult
= m_staticToolbar
->SetMenu(hmenu
, hwnd
, dwFlags
);
1003 hResult
= m_site
->GetWindow(&hwndParent
);
1004 if (FAILED(hResult
))
1007 hResult
= m_staticToolbar
->CreateToolbar(hwndParent
, m_dwFlags
);
1008 if (FAILED(hResult
))
1011 hResult
= m_staticToolbar
->FillToolbar();
1017 HRESULT STDMETHODCALLTYPE
CMenuBand::GetMenu(
1022 if (m_staticToolbar
== NULL
)
1025 return m_staticToolbar
->GetMenu(phmenu
, phwnd
, pdwFlags
);
1028 HRESULT STDMETHODCALLTYPE
CMenuBand::SetSite(IUnknown
*pUnkSite
)
1036 if (pUnkSite
== NULL
)
1040 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IOleWindow
, &m_site
));
1041 if (SUCCEEDED(hResult
))
1043 m_site
->GetWindow(&hwndParent
);
1046 if (!::IsWindow(hwndParent
))
1049 if (m_staticToolbar
!= NULL
)
1051 hResult
= m_staticToolbar
->CreateToolbar(hwndParent
, m_dwFlags
);
1052 if (FAILED(hResult
))
1055 hResult
= m_staticToolbar
->FillToolbar();
1058 if (m_SFToolbar
!= NULL
)
1060 hResult
= m_SFToolbar
->CreateToolbar(hwndParent
, m_dwFlags
);
1061 if (FAILED(hResult
))
1064 hResult
= m_SFToolbar
->FillToolbar();
1070 HRESULT STDMETHODCALLTYPE
CMenuBand::GetSite(REFIID riid
, PVOID
*ppvSite
)
1075 return m_site
->QueryInterface(riid
, ppvSite
);
1078 HRESULT STDMETHODCALLTYPE
CMenuBand::GetWindow(
1081 if (m_SFToolbar
!= NULL
)
1082 return m_SFToolbar
->GetWindow(phwnd
);
1084 if (m_staticToolbar
!= NULL
)
1085 return m_staticToolbar
->GetWindow(phwnd
);
1090 HRESULT STDMETHODCALLTYPE
CMenuBand::OnPosRectChangeDB(RECT
*prc
)
1092 SIZE sizeStaticY
= { 0 };
1093 SIZE sizeShlFldY
= { 0 };
1094 HWND hwndStatic
= NULL
;
1095 HWND hwndShlFld
= NULL
;
1096 HRESULT hResult
= S_OK
;
1098 if (m_staticToolbar
!= NULL
)
1099 hResult
= m_staticToolbar
->GetWindow(&hwndStatic
);
1100 if (FAILED(hResult
))
1103 if (m_SFToolbar
!= NULL
)
1104 hResult
= m_SFToolbar
->GetWindow(&hwndShlFld
);
1105 if (FAILED(hResult
))
1108 if (hwndStatic
== NULL
&& hwndShlFld
== NULL
)
1111 if (hwndStatic
) SendMessageW(hwndStatic
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeStaticY
));
1112 if (hwndShlFld
) SendMessageW(hwndShlFld
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeShlFldY
));
1114 int sy
= max(prc
->bottom
- prc
->top
, sizeStaticY
.cy
+ sizeShlFldY
.cy
);
1118 SetWindowPos(hwndShlFld
, NULL
,
1121 prc
->right
- prc
->left
,
1124 DWORD btnSize
= SendMessage(hwndShlFld
, TB_GETBUTTONSIZE
, 0, 0);
1125 SendMessage(hwndShlFld
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(prc
->right
- prc
->left
, HIWORD(btnSize
)));
1129 SetWindowPos(hwndStatic
, hwndShlFld
,
1131 prc
->top
+ sizeShlFldY
.cy
,
1132 prc
->right
- prc
->left
,
1133 sy
- sizeShlFldY
.cy
,
1135 DWORD btnSize
= SendMessage(hwndStatic
, TB_GETBUTTONSIZE
, 0, 0);
1136 SendMessage(hwndStatic
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(prc
->right
- prc
->left
, HIWORD(btnSize
)));
1142 HRESULT STDMETHODCALLTYPE
CMenuBand::GetBandInfo(
1147 HWND hwndStatic
= NULL
;
1148 HWND hwndShlFld
= NULL
;
1149 HRESULT hResult
= S_OK
;
1151 if (m_staticToolbar
!= NULL
)
1152 hResult
= m_staticToolbar
->GetWindow(&hwndStatic
);
1153 if (FAILED(hResult
))
1156 if (m_SFToolbar
!= NULL
)
1157 hResult
= m_SFToolbar
->GetWindow(&hwndShlFld
);
1158 if (FAILED(hResult
))
1161 if (hwndStatic
== NULL
&& hwndShlFld
== NULL
)
1165 if (pdbi
->dwMask
== 0)
1167 pdbi
->dwMask
= DBIM_MINSIZE
| DBIM_MAXSIZE
| DBIM_INTEGRAL
| DBIM_ACTUAL
| DBIM_TITLE
| DBIM_MODEFLAGS
| DBIM_BKCOLOR
;
1170 if (pdbi
->dwMask
& DBIM_MINSIZE
)
1172 SIZE sizeStatic
= { 0 };
1173 SIZE sizeShlFld
= { 0 };
1175 if (hwndStatic
) SendMessageW(hwndStatic
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeStatic
));
1176 if (hwndShlFld
) SendMessageW(hwndShlFld
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeShlFld
));
1178 pdbi
->ptMinSize
.x
= 0;
1179 pdbi
->ptMinSize
.y
= sizeStatic
.cy
+ sizeShlFld
.cy
;
1181 if (pdbi
->dwMask
& DBIM_MAXSIZE
)
1183 SIZE sizeStatic
= { 0 };
1184 SIZE sizeShlFld
= { 0 };
1186 if (hwndStatic
) SendMessageW(hwndStatic
, TB_GETMAXSIZE
, 0, reinterpret_cast<LPARAM
>(&sizeStatic
));
1187 if (hwndShlFld
) SendMessageW(hwndShlFld
, TB_GETMAXSIZE
, 0, reinterpret_cast<LPARAM
>(&sizeShlFld
));
1189 pdbi
->ptMaxSize
.x
= max(sizeStatic
.cx
, sizeShlFld
.cx
); // ignored
1190 pdbi
->ptMaxSize
.y
= sizeStatic
.cy
+ sizeShlFld
.cy
;
1192 if (pdbi
->dwMask
& DBIM_INTEGRAL
)
1194 pdbi
->ptIntegral
.x
= 0;
1195 pdbi
->ptIntegral
.y
= 0;
1197 if (pdbi
->dwMask
& DBIM_ACTUAL
)
1199 SIZE sizeStatic
= { 0 };
1200 SIZE sizeShlFld
= { 0 };
1202 if (hwndStatic
) SendMessageW(hwndStatic
, TB_GETIDEALSIZE
, FALSE
, reinterpret_cast<LPARAM
>(&sizeStatic
));
1203 if (hwndShlFld
) SendMessageW(hwndShlFld
, TB_GETIDEALSIZE
, FALSE
, reinterpret_cast<LPARAM
>(&sizeShlFld
));
1204 pdbi
->ptActual
.x
= max(sizeStatic
.cx
, sizeShlFld
.cx
);
1206 if (hwndStatic
) SendMessageW(hwndStatic
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeStatic
));
1207 if (hwndShlFld
) SendMessageW(hwndShlFld
, TB_GETIDEALSIZE
, TRUE
, reinterpret_cast<LPARAM
>(&sizeShlFld
));
1208 pdbi
->ptActual
.y
= sizeStatic
.cy
+ sizeShlFld
.cy
;
1210 if (pdbi
->dwMask
& DBIM_TITLE
)
1211 wcscpy(pdbi
->wszTitle
, L
"");
1212 if (pdbi
->dwMask
& DBIM_MODEFLAGS
)
1213 pdbi
->dwModeFlags
= DBIMF_UNDELETEABLE
;
1214 if (pdbi
->dwMask
& DBIM_BKCOLOR
)
1219 /* IDockingWindow */
1220 HRESULT STDMETHODCALLTYPE
CMenuBand::ShowDW(BOOL fShow
)
1224 if (m_staticToolbar
!= NULL
)
1225 hr
= m_staticToolbar
->ShowWindow(fShow
);
1228 if (m_SFToolbar
!= NULL
)
1229 hr
= m_SFToolbar
->ShowWindow(fShow
);
1234 return _CallCB(SMC_INITMENU
, 0, 0);
1239 HRESULT STDMETHODCALLTYPE
CMenuBand::CloseDW(DWORD dwReserved
)
1243 if (m_staticToolbar
!= NULL
)
1244 return m_staticToolbar
->Close();
1246 if (m_SFToolbar
!= NULL
)
1247 return m_SFToolbar
->Close();
1251 HRESULT STDMETHODCALLTYPE
CMenuBand::ResizeBorderDW(LPCRECT prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
)
1257 HRESULT STDMETHODCALLTYPE
CMenuBand::ContextSensitiveHelp(BOOL fEnterMode
)
1263 HRESULT STDMETHODCALLTYPE
CMenuBand::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
1269 HRESULT STDMETHODCALLTYPE
CMenuBand::HasFocusIO()
1275 HRESULT STDMETHODCALLTYPE
CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg
)
1281 HRESULT STDMETHODCALLTYPE
CMenuBand::IsDirty()
1287 HRESULT STDMETHODCALLTYPE
CMenuBand::Load(IStream
*pStm
)
1293 HRESULT STDMETHODCALLTYPE
CMenuBand::Save(IStream
*pStm
, BOOL fClearDirty
)
1299 HRESULT STDMETHODCALLTYPE
CMenuBand::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
1305 HRESULT STDMETHODCALLTYPE
CMenuBand::GetClassID(CLSID
*pClassID
)
1311 HRESULT STDMETHODCALLTYPE
CMenuBand::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1317 HRESULT STDMETHODCALLTYPE
CMenuBand::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1322 if (IsEqualGUID(*pguidCmdGroup
, CLSID_MenuBand
))
1324 if (nCmdID
== 16) // set (big) icon size
1326 this->m_useBigIcons
= TRUE
;
1329 else if (nCmdID
== 19) // popup-related
1339 HRESULT STDMETHODCALLTYPE
CMenuBand::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
1341 if (IsEqualIID(guidService
, SID_SMenuBandChild
) ||
1342 IsEqualIID(guidService
, SID_SMenuBandBottom
) ||
1343 IsEqualIID(guidService
, SID_SMenuBandBottomSelected
))
1344 return this->QueryInterface(riid
, ppvObject
);
1345 WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService
));
1346 return E_NOINTERFACE
;
1349 HRESULT STDMETHODCALLTYPE
CMenuBand::Popup(POINTL
*ppt
, RECTL
*prcExclude
, MP_POPUPFLAGS dwFlags
)
1355 HRESULT STDMETHODCALLTYPE
CMenuBand::OnSelect(DWORD dwSelectType
)
1357 CComPtr
<IMenuPopup
> pmp
;
1358 HRESULT hr
= IUnknown_QueryService(m_site
, SID_SMenuPopup
, IID_PPV_ARG(IMenuPopup
, &pmp
));
1361 pmp
->OnSelect(dwSelectType
);
1365 HRESULT STDMETHODCALLTYPE
CMenuBand::SetSubMenu(IMenuPopup
*pmp
, BOOL fSet
)
1371 HRESULT STDMETHODCALLTYPE
CMenuBand::SetClient(IUnknown
*punkClient
)
1377 HRESULT STDMETHODCALLTYPE
CMenuBand::GetClient(IUnknown
**ppunkClient
)
1383 HRESULT STDMETHODCALLTYPE
CMenuBand::IsMenuMessage(MSG
*pmsg
)
1391 HRESULT STDMETHODCALLTYPE
CMenuBand::TranslateMenuMessage(MSG
*pmsg
, LRESULT
*plRet
)
1397 HRESULT STDMETHODCALLTYPE
CMenuBand::SetShellFolder(IShellFolder
*psf
, LPCITEMIDLIST pidlFolder
, HKEY hKey
, DWORD dwFlags
)
1399 if (m_SFToolbar
== NULL
)
1401 m_SFToolbar
= new CMenuSFToolbar(this);
1404 HRESULT hResult
= m_SFToolbar
->SetShellFolder(psf
, pidlFolder
, hKey
, dwFlags
);
1405 if (FAILED(hResult
))
1412 hResult
= m_site
->GetWindow(&hwndParent
);
1413 if (FAILED(hResult
))
1416 hResult
= m_SFToolbar
->CreateToolbar(hwndParent
, m_dwFlags
);
1417 if (FAILED(hResult
))
1420 hResult
= m_SFToolbar
->FillToolbar();
1426 HRESULT STDMETHODCALLTYPE
CMenuBand::GetShellFolder(DWORD
*pdwFlags
, LPITEMIDLIST
*ppidl
, REFIID riid
, void **ppv
)
1429 return m_SFToolbar
->GetShellFolder(pdwFlags
, ppidl
, riid
, ppv
);
1433 HRESULT STDMETHODCALLTYPE
CMenuBand::InvalidateItem(LPSMDATA psmd
, DWORD dwFlags
)
1439 HRESULT STDMETHODCALLTYPE
CMenuBand::GetState(LPSMDATA psmd
)
1445 HRESULT STDMETHODCALLTYPE
CMenuBand::SetMenuToolbar(IUnknown
*punk
, DWORD dwFlags
)
1451 HRESULT STDMETHODCALLTYPE
CMenuBand::OnWinEvent(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
1458 if (m_staticToolbar
&& m_staticToolbar
->IsWindowOwner(hWnd
))
1460 return m_staticToolbar
->OnCommand(wParam
, lParam
, theResult
);
1463 if (m_SFToolbar
&& m_SFToolbar
->IsWindowOwner(hWnd
))
1465 return m_SFToolbar
->OnCommand(wParam
, lParam
, theResult
);
1471 NMHDR
* hdr
= reinterpret_cast<LPNMHDR
>(lParam
);
1472 NMTBCUSTOMDRAW
* cdraw
;
1477 case TBN_HOTITEMCHANGE
:
1478 hot
= reinterpret_cast<LPNMTBHOTITEM
>(hdr
);
1480 if (m_staticToolbar
&& m_staticToolbar
->IsWindowOwner(hWnd
))
1482 return m_staticToolbar
->OnHotItemChange(hot
);
1485 if (m_SFToolbar
&& m_SFToolbar
->IsWindowOwner(hWnd
))
1487 return m_SFToolbar
->OnHotItemChange(hot
);
1493 rclick
= reinterpret_cast<LPNMMOUSE
>(hdr
);
1495 if (m_staticToolbar
&& m_staticToolbar
->IsWindowOwner(hWnd
))
1497 return m_staticToolbar
->OnContextMenu(rclick
);
1500 if (m_SFToolbar
&& m_SFToolbar
->IsWindowOwner(hWnd
))
1502 return m_SFToolbar
->OnContextMenu(rclick
);
1507 cdraw
= reinterpret_cast<LPNMTBCUSTOMDRAW
>(hdr
);
1508 switch (cdraw
->nmcd
.dwDrawStage
)
1511 *theResult
= CDRF_NOTIFYITEMDRAW
;
1514 case CDDS_ITEMPREPAINT
:
1516 cdraw
->clrBtnFace
= GetSysColor(COLOR_MENU
);
1517 cdraw
->clrBtnHighlight
= GetSysColor(COLOR_MENUHILIGHT
);
1519 cdraw
->clrText
= GetSysColor(COLOR_MENUTEXT
);
1520 cdraw
->clrTextHighlight
= GetSysColor(COLOR_HIGHLIGHTTEXT
);
1521 cdraw
->clrHighlightHotTrack
= GetSysColor(COLOR_HIGHLIGHTTEXT
);
1523 RECT rc
= cdraw
->nmcd
.rc
;
1524 HDC hdc
= cdraw
->nmcd
.hdc
;
1526 HBRUSH bgBrush
= GetSysColorBrush(COLOR_MENU
);
1527 HBRUSH hotBrush
= GetSysColorBrush(COLOR_MENUHILIGHT
);
1529 switch (cdraw
->nmcd
.uItemState
)
1533 FillRect(hdc
, &rc
, hotBrush
);
1536 FillRect(hdc
, &rc
, bgBrush
);
1540 *theResult
= TBCDRF_NOBACKGROUND
| TBCDRF_NOEDGES
| TBCDRF_NOETCHEDEFFECT
| TBCDRF_HILITEHOTTRACK
| TBCDRF_NOOFFSET
;
1551 HRESULT STDMETHODCALLTYPE
CMenuBand::IsWindowOwner(HWND hWnd
)
1553 if (m_staticToolbar
&& m_staticToolbar
->IsWindowOwner(hWnd
))
1556 if (m_SFToolbar
&& m_SFToolbar
->IsWindowOwner(hWnd
))
1562 HRESULT STDMETHODCALLTYPE
CMenuBand::GetSubMenu(THIS
)
1568 HRESULT STDMETHODCALLTYPE
CMenuBand::SetToolbar(THIS
)
1574 HRESULT STDMETHODCALLTYPE
CMenuBand::SetMinWidth(THIS
)
1580 HRESULT STDMETHODCALLTYPE
CMenuBand::SetNoBorder(THIS
)
1586 HRESULT STDMETHODCALLTYPE
CMenuBand::SetTheme(THIS
)
1592 HRESULT STDMETHODCALLTYPE
CMenuBand::GetTop(THIS
)
1598 HRESULT STDMETHODCALLTYPE
CMenuBand::GetBottom(THIS
)
1604 HRESULT STDMETHODCALLTYPE
CMenuBand::GetTracked(THIS
)
1610 HRESULT STDMETHODCALLTYPE
CMenuBand::GetParentSite(THIS
)
1616 HRESULT STDMETHODCALLTYPE
CMenuBand::GetState(THIS
)
1622 HRESULT STDMETHODCALLTYPE
CMenuBand::DoDefaultAction(THIS
)
1628 HRESULT STDMETHODCALLTYPE
CMenuBand::IsEmpty(THIS
)
1634 HRESULT
CMenuBand::CallCBWithId(UINT id
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1636 return _CallCB(uMsg
, wParam
, lParam
, id
);
1639 HRESULT
CMenuBand::CallCBWithPidl(LPITEMIDLIST pidl
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1641 return _CallCB(uMsg
, wParam
, lParam
, 0, pidl
);
1644 HRESULT
CMenuBand::_CallCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, UINT id
, LPITEMIDLIST pidl
)
1652 SMDATA smData
= { 0 };
1653 smData
.punk
= static_cast<IShellMenu2
*>(this);
1655 smData
.uIdParent
= m_uId
;
1656 smData
.uIdAncestor
= m_uIdAncestor
;
1658 smData
.pidlItem
= pidl
;
1659 if (m_staticToolbar
)
1661 smData
.hmenu
= m_hmenu
;
1663 smData
.pvUserData
= NULL
;
1665 m_SFToolbar
->GetShellFolder(NULL
, &smData
.pidlFolder
, IID_PPV_ARG(IShellFolder
, &smData
.psf
));
1666 HRESULT hr
= m_psmc
->CallbackSM(&smData
, uMsg
, wParam
, lParam
);
1667 ILFree(smData
.pidlFolder
);
1669 smData
.psf
->Release();
1673 HRESULT
CMenuBand::TrackPopup(HMENU popup
, INT x
, INT y
)
1675 ::TrackPopupMenu(popup
, 0, x
, y
, 0, m_menuOwner
, NULL
);