1c2c66affSColin Finck /*
2c2c66affSColin Finck * Shell Menu Desk Bar
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2014 David Quintana
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck #include "shellmenu.h"
21c2c66affSColin Finck #include <atlwin.h>
22c2c66affSColin Finck #include <shlwapi_undoc.h>
23c2c66affSColin Finck
24c2c66affSColin Finck #include "CMenuDeskBar.h"
25c2c66affSColin Finck
26c2c66affSColin Finck /* As far as I can tell, the submenu hierarchy looks like this:
27c2c66affSColin Finck *
28c2c66affSColin Finck * The DeskBar's Child is the Band it contains.
29c2c66affSColin Finck * The DeskBar's Parent is the SID_SMenuPopup of the Site.
30c2c66affSColin Finck *
31c2c66affSColin Finck * The Band's Child is the IMenuPopup of the child submenu.
32c2c66affSColin Finck * The Band's Parent is the SID_SMenuPopup of the Site (the DeskBar).
33c2c66affSColin Finck *
34c2c66affSColin Finck * When the DeskBar receives a selection event:
35c2c66affSColin Finck * If it requires closing the window, it will notify the Child (Band) using CancelLevel.
36c2c66affSColin Finck * If it has to spread upwards (everything but CancelLevel), it will notify the Parent.
37c2c66affSColin Finck *
38c2c66affSColin Finck * When the Band receives a selection event, this is where it gets fuzzy:
39c2c66affSColin Finck * In which cases does it call the Parent? Probably not CancelLevel.
40c2c66affSColin Finck * In which cases does it call the Child?
41c2c66affSColin Finck * How does it react to calls?
42c2c66affSColin Finck *
43c2c66affSColin Finck */
44c2c66affSColin Finck
45c2c66affSColin Finck
46c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(CMenuDeskBar);
47c2c66affSColin Finck
CMenuDeskBar()48c2c66affSColin Finck CMenuDeskBar::CMenuDeskBar() :
49c2c66affSColin Finck m_Client(NULL),
50c2c66affSColin Finck m_ClientWindow(NULL),
51c2c66affSColin Finck m_IconSize(0),
52c2c66affSColin Finck m_Banner(NULL),
53c2c66affSColin Finck m_Shown(FALSE),
54c2c66affSColin Finck m_ShowFlags(0),
55c2c66affSColin Finck m_didAddRef(FALSE)
56c2c66affSColin Finck {
57c2c66affSColin Finck }
58c2c66affSColin Finck
~CMenuDeskBar()59c2c66affSColin Finck CMenuDeskBar::~CMenuDeskBar()
60c2c66affSColin Finck {
61c2c66affSColin Finck }
62c2c66affSColin Finck
_OnCreate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)63c2c66affSColin Finck LRESULT CMenuDeskBar::_OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
64c2c66affSColin Finck {
65c2c66affSColin Finck if (!m_didAddRef)
66c2c66affSColin Finck {
67c2c66affSColin Finck this->AddRef();
68c2c66affSColin Finck m_didAddRef = TRUE;
69c2c66affSColin Finck }
70c2c66affSColin Finck
71c2c66affSColin Finck bHandled = FALSE;
72c2c66affSColin Finck return 0;
73c2c66affSColin Finck }
74c2c66affSColin Finck
OnFinalMessage(HWND)75c2c66affSColin Finck void CMenuDeskBar::OnFinalMessage(HWND /* hWnd */)
76c2c66affSColin Finck {
77c2c66affSColin Finck if (m_didAddRef)
78c2c66affSColin Finck {
79c2c66affSColin Finck this->Release();
80c2c66affSColin Finck m_didAddRef = FALSE;
81c2c66affSColin Finck }
82c2c66affSColin Finck }
83c2c66affSColin Finck
Initialize(THIS)84c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
85c2c66affSColin Finck {
86c2c66affSColin Finck return S_OK;
87c2c66affSColin Finck }
88c2c66affSColin Finck
GetWindow(HWND * lphwnd)89c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetWindow(HWND *lphwnd)
90c2c66affSColin Finck {
91c2c66affSColin Finck if (lphwnd == NULL)
92c2c66affSColin Finck return E_POINTER;
93c2c66affSColin Finck *lphwnd = m_hWnd;
94c2c66affSColin Finck return S_OK;
95c2c66affSColin Finck }
96c2c66affSColin Finck
ContextSensitiveHelp(BOOL fEnterMode)97c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::ContextSensitiveHelp(BOOL fEnterMode)
98c2c66affSColin Finck {
99c2c66affSColin Finck return E_NOTIMPL;
100c2c66affSColin Finck }
101c2c66affSColin Finck
OnFocusChangeIS(IUnknown * punkObj,BOOL fSetFocus)102c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
103c2c66affSColin Finck {
104c2c66affSColin Finck return IUnknown_OnFocusChangeIS(m_Client, punkObj, fSetFocus);
105c2c66affSColin Finck }
106c2c66affSColin Finck
QueryStatus(const GUID * pguidCmdGroup,ULONG cCmds,OLECMD prgCmds[],OLECMDTEXT * pCmdText)107c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
108c2c66affSColin Finck OLECMD prgCmds [], OLECMDTEXT *pCmdText)
109c2c66affSColin Finck {
110c2c66affSColin Finck return E_NOTIMPL;
111c2c66affSColin Finck }
112c2c66affSColin Finck
Exec(const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdexecopt,VARIANT * pvaIn,VARIANT * pvaOut)113c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
114c2c66affSColin Finck DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
115c2c66affSColin Finck {
116c2c66affSColin Finck if (IsEqualIID(*pguidCmdGroup, CGID_MenuDeskBar))
117c2c66affSColin Finck {
118c2c66affSColin Finck switch (nCmdID)
119c2c66affSColin Finck {
120c2c66affSColin Finck case 2: // refresh
121c2c66affSColin Finck return S_OK;
122c2c66affSColin Finck case 3: // load complete
123c2c66affSColin Finck return S_OK;
124c2c66affSColin Finck case 4: // set font metrics
125c2c66affSColin Finck return _AdjustForTheme(nCmdexecopt);
126c2c66affSColin Finck }
127c2c66affSColin Finck }
128c2c66affSColin Finck if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
129c2c66affSColin Finck {
130c2c66affSColin Finck }
131c2c66affSColin Finck else if (IsEqualIID(*pguidCmdGroup, IID_IDeskBarClient))
132c2c66affSColin Finck {
133c2c66affSColin Finck switch (nCmdID)
134c2c66affSColin Finck {
135c2c66affSColin Finck case 0:
136c2c66affSColin Finck // hide current band
137c2c66affSColin Finck break;
138c2c66affSColin Finck case 2:
139c2c66affSColin Finck break;
140c2c66affSColin Finck case 3:
141c2c66affSColin Finck break;
142c2c66affSColin Finck }
143c2c66affSColin Finck }
144c2c66affSColin Finck return E_NOTIMPL;
145c2c66affSColin Finck }
146c2c66affSColin Finck
QueryService(REFGUID guidService,REFIID riid,void ** ppvObject)147c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
148c2c66affSColin Finck {
149c2c66affSColin Finck HRESULT hr;
150c2c66affSColin Finck
151c2c66affSColin Finck if (IsEqualGUID(guidService, SID_SMenuPopup) ||
152c2c66affSColin Finck IsEqualGUID(guidService, SID_SMenuBandParent) ||
153c2c66affSColin Finck IsEqualGUID(guidService, SID_STopLevelBrowser))
154c2c66affSColin Finck {
155c2c66affSColin Finck hr = this->QueryInterface(riid, ppvObject);
156c2c66affSColin Finck if (SUCCEEDED(hr))
157c2c66affSColin Finck return hr;
158c2c66affSColin Finck }
159c2c66affSColin Finck
160c2c66affSColin Finck if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
161c2c66affSColin Finck IsEqualGUID(guidService, SID_SMenuBandBottomSelected) ||
162c2c66affSColin Finck IsEqualGUID(guidService, SID_SMenuBandChild))
163c2c66affSColin Finck {
164c2c66affSColin Finck if (m_Client == NULL)
165c2c66affSColin Finck return E_NOINTERFACE;
166c2c66affSColin Finck
167c2c66affSColin Finck hr = IUnknown_QueryService(m_Client, guidService, riid, ppvObject);
168c2c66affSColin Finck if (SUCCEEDED(hr))
169c2c66affSColin Finck return hr;
170c2c66affSColin Finck }
171c2c66affSColin Finck
172c2c66affSColin Finck
173c2c66affSColin Finck if (m_Site == NULL)
174c2c66affSColin Finck return E_NOINTERFACE;
175c2c66affSColin Finck
176c2c66affSColin Finck return IUnknown_QueryService(m_Site, guidService, riid, ppvObject);
177c2c66affSColin Finck }
178c2c66affSColin Finck
UIActivateIO(BOOL fActivate,LPMSG lpMsg)179c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
180c2c66affSColin Finck {
181c2c66affSColin Finck return IUnknown_UIActivateIO(m_Client, fActivate, lpMsg);
182c2c66affSColin Finck }
183c2c66affSColin Finck
HasFocusIO()184c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::HasFocusIO()
185c2c66affSColin Finck {
186c2c66affSColin Finck return IUnknown_HasFocusIO(m_Client);
187c2c66affSColin Finck }
188c2c66affSColin Finck
TranslateAcceleratorIO(LPMSG lpMsg)189c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::TranslateAcceleratorIO(LPMSG lpMsg)
190c2c66affSColin Finck {
191c2c66affSColin Finck return IUnknown_TranslateAcceleratorIO(m_Client, lpMsg);
192c2c66affSColin Finck }
193c2c66affSColin Finck
SetClient(IUnknown * punkClient)194c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
195c2c66affSColin Finck {
196c2c66affSColin Finck CComPtr<IDeskBarClient> pDeskBandClient;
197c2c66affSColin Finck HRESULT hr;
198c2c66affSColin Finck
199c2c66affSColin Finck if (m_Client)
200c2c66affSColin Finck {
201c2c66affSColin Finck hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient));
202c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
203c2c66affSColin Finck return hr;
204c2c66affSColin Finck
205c2c66affSColin Finck pDeskBandClient->SetDeskBarSite(NULL);
206c2c66affSColin Finck
207c2c66affSColin Finck pDeskBandClient = NULL;
208c2c66affSColin Finck m_Client = NULL;
209c2c66affSColin Finck }
210c2c66affSColin Finck
211c2c66affSColin Finck if (punkClient == NULL)
212c2c66affSColin Finck return S_OK;
213c2c66affSColin Finck
214c2c66affSColin Finck if (m_hWnd == NULL)
215c2c66affSColin Finck {
216c2c66affSColin Finck Create(NULL);
217c2c66affSColin Finck }
218c2c66affSColin Finck
219c2c66affSColin Finck hr = punkClient->QueryInterface(IID_PPV_ARG(IUnknown, &m_Client));
220c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
221c2c66affSColin Finck return hr;
222c2c66affSColin Finck
223c2c66affSColin Finck hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient));
224c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
225c2c66affSColin Finck return hr;
226c2c66affSColin Finck
227c2c66affSColin Finck hr = pDeskBandClient->SetDeskBarSite(static_cast<IDeskBar*>(this));
228c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
229c2c66affSColin Finck return hr;
230c2c66affSColin Finck
231c2c66affSColin Finck return IUnknown_GetWindow(m_Client, &m_ClientWindow);
232c2c66affSColin Finck }
233c2c66affSColin Finck
GetClient(IUnknown ** ppunkClient)234c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetClient(IUnknown **ppunkClient)
235c2c66affSColin Finck {
236c2c66affSColin Finck if (ppunkClient == NULL)
237c2c66affSColin Finck return E_POINTER;
238c2c66affSColin Finck
239c2c66affSColin Finck if (!m_Client)
240c2c66affSColin Finck return E_FAIL;
241c2c66affSColin Finck
242c2c66affSColin Finck return m_Client->QueryInterface(IID_PPV_ARG(IUnknown, ppunkClient));
243c2c66affSColin Finck }
244c2c66affSColin Finck
OnPosRectChangeDB(LPRECT prc)245c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnPosRectChangeDB(LPRECT prc)
246c2c66affSColin Finck {
247c2c66affSColin Finck if (prc == NULL)
248c2c66affSColin Finck return E_POINTER;
249c2c66affSColin Finck
250c2c66affSColin Finck return S_OK;
251c2c66affSColin Finck }
252c2c66affSColin Finck
SetSite(IUnknown * pUnkSite)253c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
254c2c66affSColin Finck {
255c2c66affSColin Finck // Windows closes the bar if this is called when the bar is shown
256c2c66affSColin Finck
257c2c66affSColin Finck if (m_Shown)
258c2c66affSColin Finck _CloseBar();
259c2c66affSColin Finck
260c2c66affSColin Finck m_SubMenuParent = NULL;
261c2c66affSColin Finck
262c2c66affSColin Finck m_Site = pUnkSite;
263c2c66affSColin Finck
264c2c66affSColin Finck if (m_Site)
265c2c66affSColin Finck {
266c2c66affSColin Finck IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent));
267c2c66affSColin Finck }
268c2c66affSColin Finck else
269c2c66affSColin Finck {
270c2c66affSColin Finck SetClient(NULL);
271c2c66affSColin Finck DestroyWindow();
272c2c66affSColin Finck }
273c2c66affSColin Finck
274c2c66affSColin Finck return S_OK;
275c2c66affSColin Finck }
276c2c66affSColin Finck
GetSite(REFIID riid,void ** ppvSite)277c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetSite(REFIID riid, void **ppvSite)
278c2c66affSColin Finck {
279c2c66affSColin Finck if (m_Site == NULL)
280c2c66affSColin Finck return E_FAIL;
281c2c66affSColin Finck
282c2c66affSColin Finck return m_Site->QueryInterface(riid, ppvSite);
283c2c66affSColin Finck }
284c2c66affSColin Finck
AdjustForExcludeArea(BOOL alignLeft,BOOL alignTop,BOOL preferVertical,PINT px,PINT py,INT cx,INT cy,RECTL rcExclude)285c2c66affSColin Finck static void AdjustForExcludeArea(BOOL alignLeft, BOOL alignTop, BOOL preferVertical, PINT px, PINT py, INT cx, INT cy, RECTL rcExclude) {
286c2c66affSColin Finck RECT rcWindow = { *px, *py, *px + cx, *py + cy };
287c2c66affSColin Finck
288c2c66affSColin Finck if (rcWindow.right > rcExclude.left && rcWindow.left < rcExclude.right &&
289c2c66affSColin Finck rcWindow.bottom > rcExclude.top && rcWindow.top < rcExclude.bottom)
290c2c66affSColin Finck {
291c2c66affSColin Finck if (preferVertical)
292c2c66affSColin Finck {
293c2c66affSColin Finck if (alignTop && rcWindow.bottom > rcExclude.top)
294c2c66affSColin Finck *py = rcExclude.top - cy;
295c2c66affSColin Finck else if (!alignTop && rcWindow.top < rcExclude.bottom)
296c2c66affSColin Finck *py = rcExclude.bottom;
297c2c66affSColin Finck else if (alignLeft && rcWindow.right > rcExclude.left)
298c2c66affSColin Finck *px = rcExclude.left - cx;
299c2c66affSColin Finck else if (!alignLeft && rcWindow.left < rcExclude.right)
300c2c66affSColin Finck *px = rcExclude.right;
301c2c66affSColin Finck }
302c2c66affSColin Finck else
303c2c66affSColin Finck {
304c2c66affSColin Finck if (alignLeft && rcWindow.right > rcExclude.left)
305c2c66affSColin Finck *px = rcExclude.left - cx;
306c2c66affSColin Finck else if (!alignLeft && rcWindow.left < rcExclude.right)
307c2c66affSColin Finck *px = rcExclude.right;
308c2c66affSColin Finck else if (alignTop && rcWindow.bottom > rcExclude.top)
309c2c66affSColin Finck *py = rcExclude.top - cy;
310c2c66affSColin Finck else if (!alignTop && rcWindow.top < rcExclude.bottom)
311c2c66affSColin Finck *py = rcExclude.bottom;
312c2c66affSColin Finck }
313c2c66affSColin Finck }
314c2c66affSColin Finck }
315c2c66affSColin Finck
Popup(POINTL * ppt,RECTL * prcExclude,MP_POPUPFLAGS dwFlags)316c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
317c2c66affSColin Finck {
318c2c66affSColin Finck HRESULT hr;
319c2c66affSColin Finck CComPtr<IOleCommandTarget> oct;
320c2c66affSColin Finck CComPtr<IInputObject> io;
321c2c66affSColin Finck CComPtr<IDeskBand> band;
322c2c66affSColin Finck CComPtr<IDeskBarClient> dbc;
323c2c66affSColin Finck
324c2c66affSColin Finck if (m_hWnd == NULL)
325c2c66affSColin Finck return E_FAIL;
326c2c66affSColin Finck
327c2c66affSColin Finck hr = IUnknown_QueryService(m_Client, SID_SMenuBandChild, IID_PPV_ARG(IOleCommandTarget, &oct));
328c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
329c2c66affSColin Finck return hr;
330c2c66affSColin Finck
331c2c66affSColin Finck hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
332c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
333c2c66affSColin Finck return hr;
334c2c66affSColin Finck
335c2c66affSColin Finck // Windows calls this, but it appears to be unimplemented?
336c2c66affSColin Finck hr = dbc->SetModeDBC(1);
337c2c66affSColin Finck // Allow it to fail with E_NOTIMPL.
338c2c66affSColin Finck
339c2c66affSColin Finck // No clue about the arg, using anything != 0
340c2c66affSColin Finck hr = dbc->UIActivateDBC(TRUE);
341c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
342c2c66affSColin Finck return hr;
343c2c66affSColin Finck
344c2c66affSColin Finck RECT rc = { 0 };
345c2c66affSColin Finck hr = dbc->GetSize(0, &rc);
346c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
347c2c66affSColin Finck return hr;
348c2c66affSColin Finck
349c2c66affSColin Finck // Unknown meaning
350c2c66affSColin Finck const int CMD = 19;
351c2c66affSColin Finck const int CMD_EXEC_OPT = 0;
352c2c66affSColin Finck
353c2c66affSColin Finck hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
354c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
355c2c66affSColin Finck return hr;
356c2c66affSColin Finck
357c2c66affSColin Finck ::AdjustWindowRect(&rc, ::GetWindowLong(m_hWnd, GWL_STYLE), FALSE);
358c2c66affSColin Finck ::OffsetRect(&rc, -rc.left, -rc.top);
359c2c66affSColin Finck
360c2c66affSColin Finck if (m_Banner != NULL)
361c2c66affSColin Finck {
362c2c66affSColin Finck BITMAP bm;
363c2c66affSColin Finck ::GetObject(m_Banner, sizeof(bm), &bm);
364c2c66affSColin Finck rc.right += bm.bmWidth;
365c2c66affSColin Finck }
366c2c66affSColin Finck
367c2c66affSColin Finck RECT rcWorkArea;
368c2c66affSColin Finck ::GetWindowRect(GetDesktopWindow(), &rcWorkArea);
369c2c66affSColin Finck int cxWorkArea = rcWorkArea.right - rcWorkArea.left;
370c2c66affSColin Finck int cyWorkArea = rcWorkArea.bottom - rcWorkArea.top;
371c2c66affSColin Finck
372c2c66affSColin Finck int x = ppt->x;
373c2c66affSColin Finck int y = ppt->y;
374c2c66affSColin Finck int cx = rc.right - rc.left;
375c2c66affSColin Finck int cy = rc.bottom - rc.top;
376c2c66affSColin Finck
377c2c66affSColin Finck // TODO: Make alignLeft default to TRUE in LTR systems or whenever necessary.
378c2c66affSColin Finck BOOL alignLeft = FALSE;
379c2c66affSColin Finck BOOL alignTop = FALSE;
380c2c66affSColin Finck BOOL preferVertical = FALSE;
381c2c66affSColin Finck switch (dwFlags & MPPF_POS_MASK)
382c2c66affSColin Finck {
383c2c66affSColin Finck case MPPF_TOP:
384c2c66affSColin Finck alignTop = TRUE;
385c2c66affSColin Finck preferVertical = TRUE;
386c2c66affSColin Finck break;
387c2c66affSColin Finck case MPPF_LEFT:
388c2c66affSColin Finck alignLeft = TRUE;
389c2c66affSColin Finck break;
390c2c66affSColin Finck case MPPF_BOTTOM:
391c2c66affSColin Finck alignTop = FALSE;
392c2c66affSColin Finck preferVertical = TRUE;
393c2c66affSColin Finck break;
394c2c66affSColin Finck case MPPF_RIGHT:
395c2c66affSColin Finck alignLeft = FALSE;
396c2c66affSColin Finck break;
397c2c66affSColin Finck }
398c2c66affSColin Finck
399c2c66affSColin Finck // Try the selected alignment and verify that it doesn't escape the work area.
400c2c66affSColin Finck if (alignLeft)
401c2c66affSColin Finck {
402c2c66affSColin Finck x = ppt->x - cx;
403c2c66affSColin Finck }
404c2c66affSColin Finck else
405c2c66affSColin Finck {
406c2c66affSColin Finck x = ppt->x;
407c2c66affSColin Finck }
408c2c66affSColin Finck
409c2c66affSColin Finck if (alignTop)
410c2c66affSColin Finck {
411c2c66affSColin Finck y = ppt->y - cy;
412c2c66affSColin Finck }
413c2c66affSColin Finck else
414c2c66affSColin Finck {
415c2c66affSColin Finck y = ppt->y;
416c2c66affSColin Finck }
417c2c66affSColin Finck
418c2c66affSColin Finck if (prcExclude)
419c2c66affSColin Finck AdjustForExcludeArea(alignLeft, alignTop, preferVertical, &x, &y, cx, cy, *prcExclude);
420c2c66affSColin Finck
421c2c66affSColin Finck // Verify that it doesn't escape the work area, and flip.
422c2c66affSColin Finck if (alignLeft)
423c2c66affSColin Finck {
424c2c66affSColin Finck if (x < rcWorkArea.left && (ppt->x+cx) <= rcWorkArea.right)
425c2c66affSColin Finck {
426c2c66affSColin Finck alignLeft = FALSE;
427c2c66affSColin Finck if (prcExclude)
428c2c66affSColin Finck x = prcExclude->right - ((x + cx) - prcExclude->left);
429c2c66affSColin Finck else
430c2c66affSColin Finck x = ppt->x;
431c2c66affSColin Finck }
432c2c66affSColin Finck }
433c2c66affSColin Finck else
434c2c66affSColin Finck {
435c2c66affSColin Finck if ((ppt->x + cx) > rcWorkArea.right && x >= rcWorkArea.left)
436c2c66affSColin Finck {
437c2c66affSColin Finck alignLeft = TRUE;
438c2c66affSColin Finck if (prcExclude)
439c2c66affSColin Finck x = prcExclude->left - cx + (prcExclude->right - x);
440c2c66affSColin Finck else
441c2c66affSColin Finck x = ppt->x - cx;
442c2c66affSColin Finck }
443c2c66affSColin Finck }
444c2c66affSColin Finck
445c2c66affSColin Finck BOOL flipV = FALSE;
446c2c66affSColin Finck if (alignTop)
447c2c66affSColin Finck {
448c2c66affSColin Finck if (y < rcWorkArea.top && (ppt->y + cy) <= rcWorkArea.bottom)
449c2c66affSColin Finck {
450c2c66affSColin Finck alignTop = FALSE;
451c2c66affSColin Finck if (prcExclude)
452c2c66affSColin Finck y = prcExclude->bottom - ((y + cy) - prcExclude->top);
453c2c66affSColin Finck else
454c2c66affSColin Finck y = ppt->y;
455c2c66affSColin Finck
456c2c66affSColin Finck flipV = true;
457c2c66affSColin Finck }
458c2c66affSColin Finck }
459c2c66affSColin Finck else
460c2c66affSColin Finck {
461c2c66affSColin Finck if ((ppt->y + cy) > rcWorkArea.bottom && y >= rcWorkArea.top)
462c2c66affSColin Finck {
463c2c66affSColin Finck alignTop = TRUE;
464c2c66affSColin Finck if (prcExclude)
465c2c66affSColin Finck y = prcExclude->top - cy + (prcExclude->bottom - y);
466c2c66affSColin Finck else
467c2c66affSColin Finck y = ppt->y - cy;
468c2c66affSColin Finck
469c2c66affSColin Finck flipV = true;
470c2c66affSColin Finck }
471c2c66affSColin Finck }
472c2c66affSColin Finck
473c2c66affSColin Finck if (prcExclude)
474c2c66affSColin Finck AdjustForExcludeArea(alignLeft, alignTop, preferVertical, &x, &y, cx, cy, *prcExclude);
475c2c66affSColin Finck
476c2c66affSColin Finck if (x < rcWorkArea.left)
477c2c66affSColin Finck x = rcWorkArea.left;
478c2c66affSColin Finck
479c2c66affSColin Finck if (cx > cxWorkArea)
480c2c66affSColin Finck cx = cxWorkArea;
481c2c66affSColin Finck
482c2c66affSColin Finck if (x + cx > rcWorkArea.right)
483c2c66affSColin Finck x = rcWorkArea.right - cx;
484c2c66affSColin Finck
485c2c66affSColin Finck if (y < rcWorkArea.top)
486c2c66affSColin Finck y = rcWorkArea.top;
487c2c66affSColin Finck
488c2c66affSColin Finck if (cy > cyWorkArea)
489c2c66affSColin Finck cy = cyWorkArea;
490c2c66affSColin Finck
491c2c66affSColin Finck if (y + cy > rcWorkArea.bottom)
492c2c66affSColin Finck y = rcWorkArea.bottom - cy;
493c2c66affSColin Finck
494c2c66affSColin Finck int flags = SWP_SHOWWINDOW | SWP_NOACTIVATE;
495c2c66affSColin Finck
496c2c66affSColin Finck this->SetWindowPos(HWND_TOPMOST, x, y, cx, cy, flags);
497c2c66affSColin Finck
498c2c66affSColin Finck if (flipV)
499c2c66affSColin Finck {
500c2c66affSColin Finck if (dwFlags & MPPF_INITIALSELECT)
501c2c66affSColin Finck dwFlags = (dwFlags ^ MPPF_INITIALSELECT) | MPPF_FINALSELECT;
502c2c66affSColin Finck else if (dwFlags & MPPF_FINALSELECT)
503c2c66affSColin Finck dwFlags = (dwFlags ^ MPPF_FINALSELECT) | MPPF_INITIALSELECT;
504c2c66affSColin Finck }
505c2c66affSColin Finck
506c2c66affSColin Finck m_ShowFlags = dwFlags;
507c2c66affSColin Finck m_Shown = true;
508c2c66affSColin Finck
509c2c66affSColin Finck // HACK: The bar needs to be notified of the size AFTER it is shown.
510c2c66affSColin Finck // Quick & dirty way of getting it done.
511c2c66affSColin Finck BOOL bHandled;
512c2c66affSColin Finck _OnSize(WM_SIZE, 0, 0, bHandled);
513c2c66affSColin Finck
514c2c66affSColin Finck UIActivateIO(TRUE, NULL);
515c2c66affSColin Finck
516c2c66affSColin Finck if (dwFlags & (MPPF_INITIALSELECT | MPPF_FINALSELECT))
517c2c66affSColin Finck {
518c2c66affSColin Finck const int CMD_SELECT = 5;
519c2c66affSColin Finck int CMD_SELECT_OPTS = dwFlags & MPPF_INITIALSELECT ? 0 : -2;
520c2c66affSColin Finck IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD_SELECT, CMD_SELECT_OPTS, NULL, NULL);
521c2c66affSColin Finck }
522c2c66affSColin Finck
523c2c66affSColin Finck return S_OK;
524c2c66affSColin Finck }
525c2c66affSColin Finck
SetIconSize(THIS_ DWORD iIcon)526c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetIconSize(THIS_ DWORD iIcon)
527c2c66affSColin Finck {
528c2c66affSColin Finck HRESULT hr;
529c2c66affSColin Finck m_IconSize = iIcon;
530c2c66affSColin Finck
531c2c66affSColin Finck // Unknown meaning (set flags? set icon size?)
532c2c66affSColin Finck const int CMD = 16;
533c2c66affSColin Finck const int CMD_EXEC_OPT = iIcon ? 0 : 2; // seems to work
534c2c66affSColin Finck
535c2c66affSColin Finck hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
536c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
537c2c66affSColin Finck return hr;
538c2c66affSColin Finck
539c2c66affSColin Finck BOOL bHandled;
540c2c66affSColin Finck _OnSize(WM_SIZE, 0, 0, bHandled);
541c2c66affSColin Finck
542c2c66affSColin Finck return hr;
543c2c66affSColin Finck }
544c2c66affSColin Finck
GetIconSize(THIS_ DWORD * piIcon)545c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetIconSize(THIS_ DWORD* piIcon)
546c2c66affSColin Finck {
547c2c66affSColin Finck if (piIcon)
548c2c66affSColin Finck *piIcon = m_IconSize;
549c2c66affSColin Finck return S_OK;
550c2c66affSColin Finck }
551c2c66affSColin Finck
SetBitmap(THIS_ HBITMAP hBitmap)552c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetBitmap(THIS_ HBITMAP hBitmap)
553c2c66affSColin Finck {
554*ad748b0bSKatayama Hirofumi MZ if (m_Banner && m_Banner != hBitmap)
555*ad748b0bSKatayama Hirofumi MZ ::DeleteObject(m_Banner);
556*ad748b0bSKatayama Hirofumi MZ
557c2c66affSColin Finck m_Banner = hBitmap;
558c2c66affSColin Finck
559c2c66affSColin Finck BOOL bHandled;
560c2c66affSColin Finck _OnSize(WM_SIZE, 0, 0, bHandled);
561c2c66affSColin Finck
562c2c66affSColin Finck return S_OK;
563c2c66affSColin Finck }
564c2c66affSColin Finck
GetBitmap(THIS_ HBITMAP * phBitmap)565c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetBitmap(THIS_ HBITMAP* phBitmap)
566c2c66affSColin Finck {
567c2c66affSColin Finck if (phBitmap)
568c2c66affSColin Finck *phBitmap = m_Banner;
569c2c66affSColin Finck return S_OK;
570c2c66affSColin Finck }
571c2c66affSColin Finck
SetSubMenu(IMenuPopup * pmp,BOOL fSet)572c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
573c2c66affSColin Finck {
574c2c66affSColin Finck // Called by the MenuBand to assign itself as the logical child of the DeskBar
575c2c66affSColin Finck
576c2c66affSColin Finck if (fSet)
577c2c66affSColin Finck {
578c2c66affSColin Finck m_SubMenuChild = pmp;
579c2c66affSColin Finck }
580c2c66affSColin Finck else
581c2c66affSColin Finck {
582c2c66affSColin Finck if (m_SubMenuChild)
583c2c66affSColin Finck {
584c2c66affSColin Finck if (pmp == m_SubMenuChild)
585c2c66affSColin Finck {
586c2c66affSColin Finck m_SubMenuChild = NULL;
587c2c66affSColin Finck }
588c2c66affSColin Finck }
589c2c66affSColin Finck }
590c2c66affSColin Finck return S_OK;
591c2c66affSColin Finck }
592c2c66affSColin Finck
OnSelect(DWORD dwSelectType)593c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
594c2c66affSColin Finck {
595c2c66affSColin Finck CComPtr<IDeskBar> safeThis = this;
596c2c66affSColin Finck CComPtr<IMenuPopup> oldParent = m_SubMenuParent;
597c2c66affSColin Finck
598c2c66affSColin Finck TRACE("OnSelect dwSelectType=%d\n", this, dwSelectType);
599c2c66affSColin Finck switch (dwSelectType)
600c2c66affSColin Finck {
601c2c66affSColin Finck case MPOS_EXECUTE:
602c2c66affSColin Finck case MPOS_FULLCANCEL:
603c2c66affSColin Finck case MPOS_CANCELLEVEL:
604c2c66affSColin Finck
605c2c66affSColin Finck _CloseBar();
606c2c66affSColin Finck
607c2c66affSColin Finck if (dwSelectType == MPOS_CANCELLEVEL)
608c2c66affSColin Finck return S_OK;
609c2c66affSColin Finck
610c2c66affSColin Finck case MPOS_SELECTLEFT:
611c2c66affSColin Finck case MPOS_SELECTRIGHT:
612c2c66affSColin Finck case MPOS_CHILDTRACKING:
613c2c66affSColin Finck if (oldParent)
614c2c66affSColin Finck return oldParent->OnSelect(dwSelectType);
615c2c66affSColin Finck break;
616c2c66affSColin Finck }
617c2c66affSColin Finck
618c2c66affSColin Finck return S_OK;
619c2c66affSColin Finck }
620c2c66affSColin Finck
_CloseBar()621c2c66affSColin Finck HRESULT CMenuDeskBar::_CloseBar()
622c2c66affSColin Finck {
623c2c66affSColin Finck CComPtr<IDeskBarClient> dbc;
624c2c66affSColin Finck HRESULT hr;
625c2c66affSColin Finck
626c2c66affSColin Finck // Ensure that our data isn't destroyed while we are working
627c2c66affSColin Finck CComPtr<IDeskBar> safeThis = this;
628c2c66affSColin Finck
629c2c66affSColin Finck m_Shown = false;
630c2c66affSColin Finck
631c2c66affSColin Finck if (m_SubMenuParent)
632c2c66affSColin Finck {
633c2c66affSColin Finck m_SubMenuParent->SetSubMenu(this, FALSE);
634c2c66affSColin Finck }
635c2c66affSColin Finck
636c2c66affSColin Finck if (m_SubMenuChild)
637c2c66affSColin Finck {
638c2c66affSColin Finck hr = m_SubMenuChild->OnSelect(MPOS_CANCELLEVEL);
639c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
640c2c66affSColin Finck return hr;
641c2c66affSColin Finck }
642c2c66affSColin Finck
643c2c66affSColin Finck hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
644c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
645c2c66affSColin Finck return hr;
646c2c66affSColin Finck
647c2c66affSColin Finck hr = dbc->UIActivateDBC(FALSE);
648c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
649c2c66affSColin Finck return hr;
650c2c66affSColin Finck
65196e3c7bcSMark Jansen if (m_hWnd)
652c2c66affSColin Finck SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE);
653c2c66affSColin Finck
654c2c66affSColin Finck return UIActivateIO(FALSE, NULL);
655c2c66affSColin Finck }
656c2c66affSColin Finck
_IsSubMenuParent(HWND hwnd)657c2c66affSColin Finck BOOL CMenuDeskBar::_IsSubMenuParent(HWND hwnd)
658c2c66affSColin Finck {
659c2c66affSColin Finck CComPtr<IMenuPopup> popup = m_SubMenuParent;
660c2c66affSColin Finck
661c2c66affSColin Finck while (popup)
662c2c66affSColin Finck {
663c2c66affSColin Finck HRESULT hr;
664c2c66affSColin Finck HWND parent;
665c2c66affSColin Finck
666c2c66affSColin Finck hr = IUnknown_GetWindow(popup, &parent);
667c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
668c2c66affSColin Finck return FALSE;
669c2c66affSColin Finck if (hwnd == parent)
670c2c66affSColin Finck return TRUE;
671c2c66affSColin Finck
672c2c66affSColin Finck hr = IUnknown_GetSite(popup, IID_PPV_ARG(IMenuPopup, &popup));
673c2c66affSColin Finck if (FAILED(hr))
674c2c66affSColin Finck return FALSE;
675c2c66affSColin Finck }
676c2c66affSColin Finck
677c2c66affSColin Finck return FALSE;
678c2c66affSColin Finck }
679c2c66affSColin Finck
_OnSize(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)680c2c66affSColin Finck LRESULT CMenuDeskBar::_OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
681c2c66affSColin Finck {
682c2c66affSColin Finck if (m_Client)
683c2c66affSColin Finck {
684c2c66affSColin Finck RECT rc;
685c2c66affSColin Finck
686c2c66affSColin Finck GetClientRect(&rc);
687c2c66affSColin Finck
688*ad748b0bSKatayama Hirofumi MZ if (m_Banner && m_IconSize != BMICON_SMALL)
689c2c66affSColin Finck {
690c2c66affSColin Finck BITMAP bm;
691c2c66affSColin Finck ::GetObject(m_Banner, sizeof(bm), &bm);
692c2c66affSColin Finck rc.left += bm.bmWidth;
693c2c66affSColin Finck }
694c2c66affSColin Finck
695c2c66affSColin Finck ::SetWindowPos(m_ClientWindow, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 0);
696c2c66affSColin Finck }
697c2c66affSColin Finck
698c2c66affSColin Finck return 0;
699c2c66affSColin Finck }
700c2c66affSColin Finck
_OnNotify(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)701c2c66affSColin Finck LRESULT CMenuDeskBar::_OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
702c2c66affSColin Finck {
703c2c66affSColin Finck if (!m_Client)
704c2c66affSColin Finck return 0;
705c2c66affSColin Finck
706c2c66affSColin Finck CComPtr<IWinEventHandler> winEventHandler;
707c2c66affSColin Finck HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
708c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
709c2c66affSColin Finck return 0;
710c2c66affSColin Finck
711c2c66affSColin Finck if (winEventHandler)
712c2c66affSColin Finck {
713c2c66affSColin Finck LRESULT result;
714c2c66affSColin Finck hr = winEventHandler->OnWinEvent(NULL, uMsg, wParam, lParam, &result);
715c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
716c2c66affSColin Finck return 0;
717c2c66affSColin Finck return result;
718c2c66affSColin Finck }
719c2c66affSColin Finck
720c2c66affSColin Finck return 0;
721c2c66affSColin Finck }
722c2c66affSColin Finck
_OnPaint(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)723c2c66affSColin Finck LRESULT CMenuDeskBar::_OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
724c2c66affSColin Finck {
725c2c66affSColin Finck bHandled = FALSE;
726c2c66affSColin Finck
727c2c66affSColin Finck if (m_Banner && !m_IconSize)
728c2c66affSColin Finck {
729c2c66affSColin Finck BITMAP bm;
730c2c66affSColin Finck PAINTSTRUCT ps;
731c2c66affSColin Finck HDC hdc = BeginPaint(&ps);
732c2c66affSColin Finck
733c2c66affSColin Finck HDC hdcMem = ::CreateCompatibleDC(hdc);
734c2c66affSColin Finck HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_Banner);
735c2c66affSColin Finck
736c2c66affSColin Finck ::GetObject(m_Banner, sizeof(bm), &bm);
737c2c66affSColin Finck
738c2c66affSColin Finck RECT rc;
739c2c66affSColin Finck if (!GetClientRect(&rc))
740c2c66affSColin Finck WARN("GetClientRect failed\n");
741c2c66affSColin Finck
742c2c66affSColin Finck const int bx = bm.bmWidth;
743c2c66affSColin Finck const int by = bm.bmHeight;
744c2c66affSColin Finck const int cy = rc.bottom;
745c2c66affSColin Finck
746c2c66affSColin Finck TRACE("Painting banner: %d by %d\n", bm.bmWidth, bm.bmHeight);
747c2c66affSColin Finck
748c2c66affSColin Finck if (!::StretchBlt(hdc, 0, 0, bx, cy - by, hdcMem, 0, 0, bx, 1, SRCCOPY))
749c2c66affSColin Finck WARN("StretchBlt failed\n");
750c2c66affSColin Finck
751c2c66affSColin Finck if (!::BitBlt(hdc, 0, cy - by, bx, by, hdcMem, 0, 0, SRCCOPY))
752c2c66affSColin Finck WARN("BitBlt failed\n");
753c2c66affSColin Finck
754c2c66affSColin Finck ::SelectObject(hdcMem, hbmOld);
755c2c66affSColin Finck ::DeleteDC(hdcMem);
756c2c66affSColin Finck
757c2c66affSColin Finck EndPaint(&ps);
758c2c66affSColin Finck }
759c2c66affSColin Finck
760c2c66affSColin Finck return TRUE;
761c2c66affSColin Finck }
762c2c66affSColin Finck
_OnActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)763c2c66affSColin Finck LRESULT CMenuDeskBar::_OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
764c2c66affSColin Finck {
765c2c66affSColin Finck // BUG in ReactOS: WM_ACTIVATE/WA_INACTIVE makes no sense with lParam==hWnd
766c2c66affSColin Finck if (LOWORD(wParam) != 0 || reinterpret_cast<HWND>(lParam) == m_hWnd)
767c2c66affSColin Finck {
768c2c66affSColin Finck return 0;
769c2c66affSColin Finck }
770c2c66affSColin Finck
771c2c66affSColin Finck // HACK! I just want it to work !!!
772c2c66affSColin Finck CComPtr<IDeskBar> db;
773c2c66affSColin Finck HRESULT hr = IUnknown_QueryService(m_Client, SID_SMenuBandChild, IID_PPV_ARG(IDeskBar, &db));
774c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
775c2c66affSColin Finck return 0;
776c2c66affSColin Finck
777c2c66affSColin Finck CComPtr<IUnknown> punk;
778c2c66affSColin Finck
779c2c66affSColin Finck hr = db->GetClient(&punk);
780c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
781c2c66affSColin Finck return 0;
782c2c66affSColin Finck
783c2c66affSColin Finck if (!punk && m_Shown)
784c2c66affSColin Finck {
785c2c66affSColin Finck if (!_IsSubMenuParent(reinterpret_cast<HWND>(lParam)))
786c2c66affSColin Finck {
787c2c66affSColin Finck OnSelect(MPOS_FULLCANCEL);
788c2c66affSColin Finck }
789c2c66affSColin Finck }
790c2c66affSColin Finck
791c2c66affSColin Finck return 0;
792c2c66affSColin Finck }
793c2c66affSColin Finck
_OnMouseActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)794c2c66affSColin Finck LRESULT CMenuDeskBar::_OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
795c2c66affSColin Finck {
796c2c66affSColin Finck return MA_NOACTIVATE;
797c2c66affSColin Finck }
798c2c66affSColin Finck
_OnAppActivate(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)799c2c66affSColin Finck LRESULT CMenuDeskBar::_OnAppActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
800c2c66affSColin Finck {
801c2c66affSColin Finck #if 0
802c2c66affSColin Finck if (wParam == 0 && m_Shown)
803c2c66affSColin Finck {
804c2c66affSColin Finck OnSelect(MPOS_FULLCANCEL);
805c2c66affSColin Finck }
806c2c66affSColin Finck #endif
807c2c66affSColin Finck return 0;
808c2c66affSColin Finck }
809c2c66affSColin Finck
_OnWinIniChange(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)810c2c66affSColin Finck LRESULT CMenuDeskBar::_OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
811c2c66affSColin Finck {
812c2c66affSColin Finck if (wParam == SPI_SETFLATMENU)
813c2c66affSColin Finck return _OnNotify(uMsg, wParam, lParam, bHandled);
814c2c66affSColin Finck
815c2c66affSColin Finck return 0;
816c2c66affSColin Finck }
817c2c66affSColin Finck
_OnNcPaint(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)818c2c66affSColin Finck LRESULT CMenuDeskBar::_OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
819c2c66affSColin Finck {
820c2c66affSColin Finck /* If it is a flat style menu we need to handle WM_NCPAINT
821c2c66affSColin Finck * and paint the border with the right colour */
822c2c66affSColin Finck if ((GetStyle() & WS_BORDER) == 0)
823c2c66affSColin Finck {
824c2c66affSColin Finck /* This isn't a flat style menu. */
825c2c66affSColin Finck bHandled = FALSE;
826c2c66affSColin Finck return 0;
827c2c66affSColin Finck }
828c2c66affSColin Finck
829c2c66affSColin Finck HDC hdc;
830c2c66affSColin Finck RECT rcWindow;
831c2c66affSColin Finck
832c2c66affSColin Finck hdc = GetWindowDC();
833c2c66affSColin Finck GetWindowRect(&rcWindow);
834c2c66affSColin Finck OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
835c2c66affSColin Finck FrameRect(hdc, &rcWindow, GetSysColorBrush(COLOR_BTNSHADOW));
836c2c66affSColin Finck ReleaseDC(hdc);
837c2c66affSColin Finck return 0;
838c2c66affSColin Finck }
839c2c66affSColin Finck
_OnClose(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)840c2c66affSColin Finck LRESULT CMenuDeskBar::_OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
841c2c66affSColin Finck {
842c2c66affSColin Finck /* Prevent the CMenuDeskBar from destroying on being sent a WM_CLOSE */
843c2c66affSColin Finck return 0;
844c2c66affSColin Finck }
845c2c66affSColin Finck
_AdjustForTheme(BOOL bFlatStyle)846c2c66affSColin Finck HRESULT CMenuDeskBar::_AdjustForTheme(BOOL bFlatStyle)
847c2c66affSColin Finck {
848c2c66affSColin Finck DWORD style = bFlatStyle ? WS_BORDER : WS_CLIPCHILDREN|WS_DLGFRAME;
849c2c66affSColin Finck DWORD mask = WS_BORDER|WS_CLIPCHILDREN|WS_DLGFRAME;
850c2c66affSColin Finck SHSetWindowBits(m_hWnd, GWL_STYLE, mask, style);
851c2c66affSColin Finck return S_OK;
852c2c66affSColin Finck }
853c2c66affSColin Finck
854c2c66affSColin Finck extern "C"
RSHELL_CMenuDeskBar_CreateInstance(REFIID riid,LPVOID * ppv)855c2c66affSColin Finck HRESULT WINAPI RSHELL_CMenuDeskBar_CreateInstance(REFIID riid, LPVOID *ppv)
856c2c66affSColin Finck {
857c2c66affSColin Finck return ShellObjectCreator<CMenuDeskBar>(riid, ppv);
858c2c66affSColin Finck }
859