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 #pragma once
21 
22 class CMenuBand;
23 class CMenuFocusManager;
24 
25 #define WM_USER_ISTRACKEDITEM (WM_APP+41)
26 #define WM_USER_CHANGETRACKEDITEM (WM_APP+42)
27 
28 class CMenuToolbarBase :
29     public CWindowImplBaseT< CToolbar<DWORD_PTR>, CControlWinTraits >
30 {
31     CContainedWindow m_pager;
32 private:
33     HFONT   m_marlett;
34     BOOL    m_useFlatMenus;
35     BOOL    m_disableMouseTrack;
36     BOOL    m_timerEnabled;
37 
38 protected:
39     CMenuBand * m_menuBand;
40     DWORD       m_dwMenuFlags;
41     BOOL        m_hasSizes;
42     SIZE        m_idealSize;
43     SIZE        m_itemSize;
44     BOOL        m_usePager;
45     CMenuToolbarBase * m_hotBar;
46     INT                m_hotItem;
47     CMenuToolbarBase * m_popupBar;
48     INT                m_popupItem;
49 
50     DWORD m_initFlags;
51     BOOL m_isTrackingPopup;
52 
53     INT m_executeIndex;
54     INT m_executeItem;
55     DWORD_PTR m_executeData;
56 
57     BOOL m_cancelingPopup;
58 
59 public:
60     CMenuToolbarBase(CMenuBand *menuBand, BOOL usePager);
61     virtual ~CMenuToolbarBase();
62 
63     HRESULT IsWindowOwner(HWND hwnd);
64     HRESULT CreateToolbar(HWND hwndParent, DWORD dwFlags);
65     HRESULT GetWindow(HWND *phwnd);
66     HRESULT ShowDW(BOOL fShow);
67     HRESULT Close();
68 
69     HRESULT OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult);
70 
71     HRESULT ChangeHotItem(CMenuToolbarBase * toolbar, INT item, DWORD dwFlags);
72     HRESULT ChangePopupItem(CMenuToolbarBase * toolbar, INT item);
73 
74     HRESULT PopupSubMenu(UINT itemId, UINT index, IShellMenu* childShellMenu, BOOL keyInitiated);
75     HRESULT PopupSubMenu(UINT itemId, UINT index, HMENU menu);
76     HRESULT TrackContextMenu(IContextMenu* contextMenu, POINT pt);
77 
78     HRESULT KeyboardItemChange(DWORD changeType);
79 
80     HRESULT PrepareExecuteItem(INT iItem);
81     HRESULT ExecuteItem();
82 
83     HRESULT GetSizes(SIZE* pMinSize, SIZE* pMaxSize, SIZE* pIntegralSize);
84     HRESULT SetPosSize(int x, int y, int cx, int cy);
85 
86     void InvalidateDraw();
87 
88     HRESULT DisableMouseTrack(BOOL bDisable);
89 
90     virtual HRESULT FillToolbar(BOOL clearFirst=FALSE) = 0;
91 
92     HRESULT CancelCurrentPopup();
93     HRESULT PopupItem(INT iItem, BOOL keyInitiated);
94     HRESULT GetDataFromId(INT iItem, INT* pIndex, DWORD_PTR* pData);
95 
96     HRESULT KillPopupTimer();
97 
98     HRESULT MenuBarMouseDown(INT iIndex, BOOL isLButton);
99     HRESULT MenuBarMouseUp(INT iIndex, BOOL isLButton);
100     HRESULT ProcessClick(INT iItem);
101     HRESULT ProcessContextMenu(INT iItem);
102     HRESULT BeforeCancelPopup();
103 
104 protected:
105     virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) PURE;
106 
107     virtual HRESULT InternalGetTooltip(INT iItem, INT index, DWORD_PTR dwData, LPWSTR pszText, INT cchTextMax) PURE;
108     virtual HRESULT InternalExecuteItem(INT iItem, INT index, DWORD_PTR dwData) PURE;
109     virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData, BOOL keyInitiated) PURE;
110     virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData) PURE;
111     virtual HRESULT InternalContextMenu(INT iItem, INT index, DWORD_PTR dwData, POINT pt) PURE;
112 
113     HRESULT AddButton(DWORD commandId, LPCWSTR caption, BOOL hasSubMenu, INT iconId, DWORD_PTR buttonData, BOOL last);
114     HRESULT AddSeparator(BOOL last);
115     HRESULT AddPlaceholder();
116     HRESULT ClearToolbar();
117 
GetToolbar()118     HWND GetToolbar() { return m_hWnd; }
119 
120 private:
121     HRESULT UpdateImageLists();
122 
123     HRESULT OnPagerCalcSize(LPNMPGCALCSIZE csize);
124     HRESULT OnCustomDraw(LPNMTBCUSTOMDRAW cdraw, LRESULT * theResult);
125     HRESULT OnGetInfoTip(NMTBGETINFOTIP * tip);
126 
127     LRESULT IsTrackedItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
128     LRESULT ChangeTrackedItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
129     LRESULT OnWinEventWrap(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
130     HRESULT OnPopupTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
131 
132     BEGIN_MSG_MAP(CMenuToolbarBase)
133         MESSAGE_HANDLER(WM_USER_ISTRACKEDITEM, IsTrackedItem)
134         MESSAGE_HANDLER(WM_USER_CHANGETRACKEDITEM, ChangeTrackedItem)
135         MESSAGE_HANDLER(WM_COMMAND, OnWinEventWrap)
136         MESSAGE_HANDLER(WM_NOTIFY, OnWinEventWrap)
137         MESSAGE_HANDLER(WM_TIMER, OnPopupTimer)
138     END_MSG_MAP()
139 };
140 
141 class CMenuStaticToolbar :
142     public CMenuToolbarBase
143 {
144 private:
145     HMENU m_hmenu;
146     HWND m_hwndMenu;
147 
148 public:
149     CMenuStaticToolbar(CMenuBand *menuBand);
150     virtual ~CMenuStaticToolbar();
151 
152     HRESULT SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags);
153     HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags);
154 
155     virtual HRESULT FillToolbar(BOOL clearFirst=FALSE) override;
156 
157 protected:
158     virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) override;
159 
160     virtual HRESULT InternalGetTooltip(INT iItem, INT index, DWORD_PTR dwData, LPWSTR pszText, INT cchTextMax) override;
161     virtual HRESULT InternalExecuteItem(INT iItem, INT index, DWORD_PTR dwData) override;
162     virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData, BOOL keyInitiated) override;
163     virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData) override;
164     virtual HRESULT InternalContextMenu(INT iItem, INT index, DWORD_PTR dwData, POINT pt) override;
165 };
166 
167 class CMenuSFToolbar :
168     public CMenuToolbarBase
169 {
170 private:
171     CComPtr<IShellFolder> m_shellFolder;
172     LPCITEMIDLIST  m_idList;
173     HKEY           m_hKey;
174 
175 public:
176     CMenuSFToolbar(CMenuBand *menuBand);
177     virtual ~CMenuSFToolbar();
178 
179     HRESULT SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags);
180     HRESULT GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv);
181 
182     virtual HRESULT FillToolbar(BOOL clearFirst=FALSE) override;
183 
184 protected:
185     virtual HRESULT OnDeletingButton(const NMTOOLBAR * tb) override;
186 
187     virtual HRESULT InternalGetTooltip(INT iItem, INT index, DWORD_PTR dwData, LPWSTR pszText, INT cchTextMax) override;
188     virtual HRESULT InternalExecuteItem(INT iItem, INT index, DWORD_PTR dwData) override;
189     virtual HRESULT InternalPopupItem(INT iItem, INT index, DWORD_PTR dwData, BOOL keyInitiated) override;
190     virtual HRESULT InternalHasSubMenu(INT iItem, INT index, DWORD_PTR dwData) override;
191     virtual HRESULT InternalContextMenu(INT iItem, INT index, DWORD_PTR dwData, POINT pt) override;
192 };
193