[RSHELL]
[reactos.git] / base / shell / rshell / CMenuDeskBar.cpp
1 /*
2 * Shell Menu Desk Bar
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 <atlwin.h>
22 #include <shlwapi_undoc.h>
23
24 #include "CMenuDeskBar.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(CMenuDeskBar);
27
28 const static GUID CGID_MenuDeskBar = { 0x5C9F0A12, 0x959E, 0x11D0, { 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x08, 0x26, 0x36 } };
29
30 extern "C"
31 HRESULT WINAPI CMenuDeskBar_Constructor(REFIID riid, LPVOID *ppv)
32 {
33 return ShellObjectCreator<CMenuDeskBar>(riid, ppv);
34 }
35
36 CMenuDeskBar::CMenuDeskBar() :
37 m_Client(NULL),
38 m_ClientWindow(NULL),
39 m_IconSize(0),
40 m_Banner(NULL),
41 m_Shown(FALSE),
42 m_ShowFlags(0),
43 m_didAddRef(FALSE)
44 {
45 }
46
47 CMenuDeskBar::~CMenuDeskBar()
48 {
49 }
50
51 LRESULT CMenuDeskBar::_OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
52 {
53 if (!m_didAddRef)
54 {
55 this->AddRef();
56 m_didAddRef = TRUE;
57 }
58
59 bHandled = FALSE;
60 return 0;
61 }
62
63 void CMenuDeskBar::OnFinalMessage(HWND /* hWnd */)
64 {
65 if (m_didAddRef)
66 {
67 this->Release();
68 m_didAddRef = FALSE;
69 }
70 }
71
72 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
73 {
74 return S_OK;
75 }
76
77 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetWindow(HWND *lphwnd)
78 {
79 if (lphwnd == NULL)
80 return E_POINTER;
81 *lphwnd = m_hWnd;
82 return S_OK;
83 }
84
85 HRESULT STDMETHODCALLTYPE CMenuDeskBar::ContextSensitiveHelp(BOOL fEnterMode)
86 {
87 return E_NOTIMPL;
88 }
89
90 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
91 {
92 CComPtr<IInputObjectSite> ios;
93
94 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObjectSite, &ios));
95 if (FAILED_UNEXPECTEDLY(hr))
96 return hr;
97
98 return ios->OnFocusChangeIS(punkObj, fSetFocus);
99 }
100
101 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds,
102 OLECMD prgCmds [], OLECMDTEXT *pCmdText)
103 {
104 return E_NOTIMPL;
105 }
106
107 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
108 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
109 {
110 if (IsEqualIID(*pguidCmdGroup, CGID_MenuDeskBar))
111 {
112 switch (nCmdID)
113 {
114 case 2: // refresh
115 return S_OK;
116 case 3: // load complete
117 return S_OK;
118 case 4: // set font metrics
119 return S_OK;
120 }
121 }
122 if (IsEqualIID(*pguidCmdGroup, CGID_Explorer))
123 {
124 }
125 else if (IsEqualIID(*pguidCmdGroup, IID_IDeskBarClient))
126 {
127 switch (nCmdID)
128 {
129 case 0:
130 // hide current band
131 break;
132 case 2:
133 break;
134 case 3:
135 break;
136 }
137 }
138 return E_NOTIMPL;
139 }
140
141 HRESULT STDMETHODCALLTYPE CMenuDeskBar::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
142 {
143 HRESULT hr;
144
145 if (IsEqualGUID(guidService, SID_SMenuPopup) ||
146 IsEqualGUID(guidService, SID_SMenuBandParent) ||
147 IsEqualGUID(guidService, SID_STopLevelBrowser))
148 {
149 hr = this->QueryInterface(riid, ppvObject);
150 if (SUCCEEDED(hr))
151 return hr;
152 }
153
154 if (IsEqualGUID(guidService, SID_SMenuBandBottom) ||
155 IsEqualGUID(guidService, SID_SMenuBandBottomSelected) ||
156 IsEqualGUID(guidService, SID_SMenuBandChild))
157 {
158 if (m_Client == NULL)
159 return E_NOINTERFACE;
160
161 hr = IUnknown_QueryService(m_Client, guidService, riid, ppvObject);
162 if (SUCCEEDED(hr))
163 return hr;
164 }
165
166
167 if (m_Site == NULL)
168 return E_NOINTERFACE;
169
170 return IUnknown_QueryService(m_Site, guidService, riid, ppvObject);
171 }
172
173 HRESULT STDMETHODCALLTYPE CMenuDeskBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
174 {
175 return IUnknown_UIActivateIO(m_Client, fActivate, lpMsg);
176 }
177
178 HRESULT STDMETHODCALLTYPE CMenuDeskBar::HasFocusIO()
179 {
180 CComPtr<IInputObject> io;
181
182 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObject, &io));
183 if (FAILED_UNEXPECTEDLY(hr))
184 return hr;
185
186 return io->HasFocusIO();
187 }
188
189 HRESULT STDMETHODCALLTYPE CMenuDeskBar::TranslateAcceleratorIO(LPMSG lpMsg)
190 {
191 CComPtr<IInputObject> io;
192
193 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IInputObject, &io));
194 if (FAILED_UNEXPECTEDLY(hr))
195 return hr;
196
197 return io->TranslateAcceleratorIO(lpMsg);
198 }
199
200 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
201 {
202 CComPtr<IDeskBarClient> pDeskBandClient;
203 HRESULT hr;
204
205 if (m_Client)
206 {
207 hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient));
208 if (FAILED_UNEXPECTEDLY(hr))
209 return hr;
210
211 pDeskBandClient->SetDeskBarSite(NULL);
212
213 pDeskBandClient = NULL;
214 m_Client = NULL;
215 }
216
217 if (punkClient == NULL)
218 return S_OK;
219
220 if (m_hWnd == NULL)
221 {
222 Create(NULL);
223 }
224
225 hr = punkClient->QueryInterface(IID_PPV_ARG(IUnknown, &m_Client));
226 if (FAILED_UNEXPECTEDLY(hr))
227 return hr;
228
229 hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient));
230 if (FAILED_UNEXPECTEDLY(hr))
231 return hr;
232
233 hr = pDeskBandClient->SetDeskBarSite(static_cast<IDeskBar*>(this));
234 if (FAILED_UNEXPECTEDLY(hr))
235 return hr;
236
237 return IUnknown_GetWindow(m_Client, &m_ClientWindow);
238 }
239
240 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetClient(IUnknown **ppunkClient)
241 {
242 if (ppunkClient == NULL)
243 return E_POINTER;
244
245 if (!m_Client)
246 return E_FAIL;
247
248 return m_Client->QueryInterface(IID_PPV_ARG(IUnknown, ppunkClient));
249 }
250
251 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnPosRectChangeDB(LPRECT prc)
252 {
253 if (prc == NULL)
254 return E_POINTER;
255
256 return S_OK;
257 }
258
259 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
260 {
261 // Windows closes the bar if this is called when the bar is shown
262
263 if (m_Shown)
264 _CloseBar();
265
266 m_SubMenuParent = NULL;
267
268 m_Site = pUnkSite;
269
270 if (m_Site)
271 {
272 IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent));
273 }
274 else
275 {
276 SetClient(NULL);
277 DestroyWindow();
278 }
279
280 return S_OK;
281 }
282
283 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetSite(REFIID riid, void **ppvSite)
284 {
285 if (m_Site == NULL)
286 return E_FAIL;
287
288 return m_Site->QueryInterface(riid, ppvSite);
289 }
290
291 HRESULT STDMETHODCALLTYPE CMenuDeskBar::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
292 {
293 HRESULT hr;
294 CComPtr<IOleCommandTarget> oct;
295 CComPtr<IInputObject> io;
296 CComPtr<IDeskBand> band;
297 CComPtr<IDeskBarClient> dbc;
298
299 if (m_hWnd == NULL)
300 return E_FAIL;
301
302 hr = IUnknown_QueryService(m_Client, SID_SMenuBandChild, IID_PPV_ARG(IOleCommandTarget, &oct));
303 if (FAILED_UNEXPECTEDLY(hr))
304 return hr;
305
306 hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
307 if (FAILED_UNEXPECTEDLY(hr))
308 return hr;
309
310 // Windows calls this, but it appears to be unimplemented?
311 hr = dbc->SetModeDBC(1);
312 // Allow it to fail with E_NOTIMPL.
313
314 // No clue about the arg, using anything != 0
315 hr = dbc->UIActivateDBC(TRUE);
316 if (FAILED_UNEXPECTEDLY(hr))
317 return hr;
318
319 RECT rc = { 0 };
320 hr = dbc->GetSize(0, &rc);
321 if (FAILED_UNEXPECTEDLY(hr))
322 return hr;
323
324 // Unknown meaning
325 const int CMD = 19;
326 const int CMD_EXEC_OPT = 0;
327
328 hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
329 if (FAILED_UNEXPECTEDLY(hr))
330 return hr;
331
332 ::AdjustWindowRect(&rc, ::GetWindowLong(m_hWnd, GWL_STYLE), FALSE);
333 ::OffsetRect(&rc, -rc.left, -rc.top);
334
335 if (m_Banner != NULL)
336 {
337 BITMAP bm;
338 ::GetObject(m_Banner, sizeof(bm), &bm);
339 rc.right += bm.bmWidth;
340 }
341
342 RECT rcWorkArea;
343 GetWindowRect(GetDesktopWindow(), &rcWorkArea);
344 int waHeight = rcWorkArea.bottom - rcWorkArea.top;
345
346 int x = ppt->x;
347 int y = ppt->y;
348 int cx = rc.right - rc.left;
349 int cy = rc.bottom - rc.top;
350
351 switch (dwFlags & 0xFF000000)
352 {
353 case MPPF_BOTTOM:
354 x = ppt->x;
355 y = ppt->y - rc.bottom;
356 break;
357 case MPPF_RIGHT:
358 x = ppt->x + rc.left;
359 y = ppt->y + rc.top;
360 break;
361 case MPPF_TOP | MPPF_ALIGN_LEFT:
362 x = ppt->x - rc.right;
363 y = ppt->y + rc.top;
364 break;
365 case MPPF_TOP | MPPF_ALIGN_RIGHT:
366 x = ppt->x;
367 y = ppt->y + rc.top;
368 break;
369 }
370
371 if (x + cx > rcWorkArea.right)
372 {
373 // FIXME: Works, but it's oversimplified.
374 x = prcExclude->left - cx;
375 dwFlags = (dwFlags & (~MPPF_TOP)) | MPPF_LEFT;
376 }
377
378 if (y < rcWorkArea.top)
379 {
380 y = rcWorkArea.top;
381 }
382
383 if (cy > waHeight)
384 {
385 cy = waHeight;
386 }
387
388 if (y + cy > rcWorkArea.bottom)
389 {
390 y = rcWorkArea.bottom - cy;
391 }
392
393 this->SetWindowPos(HWND_TOPMOST, x, y, cx, cy, SWP_SHOWWINDOW);
394
395 m_ShowFlags = dwFlags;
396 m_Shown = true;
397
398 // HACK: The bar needs to be notified of the size AFTER it is shown.
399 // Quick & dirty way of getting it done.
400 BOOL bHandled;
401 _OnSize(WM_SIZE, 0, 0, bHandled);
402
403 UIActivateIO(TRUE, NULL);
404
405 if (dwFlags & (MPPF_INITIALSELECT | MPPF_FINALSELECT))
406 {
407 const int CMD_SELECT = 5;
408 int CMD_SELECT_OPTS = dwFlags & MPPF_INITIALSELECT ? 0 : -2;
409 IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD_SELECT, CMD_SELECT_OPTS, NULL, NULL);
410 }
411
412 return S_OK;
413 }
414
415 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetIconSize(THIS_ DWORD iIcon)
416 {
417 HRESULT hr;
418 m_IconSize = iIcon;
419
420 // Unknown meaning (set flags? set icon size?)
421 const int CMD = 16;
422 const int CMD_EXEC_OPT = iIcon ? 0 : 2; // seems to work
423
424 hr = IUnknown_QueryServiceExec(m_Client, SID_SMenuBandChild, &CLSID_MenuBand, CMD, CMD_EXEC_OPT, NULL, NULL);
425 if (FAILED_UNEXPECTEDLY(hr))
426 return hr;
427
428 BOOL bHandled;
429 _OnSize(WM_SIZE, 0, 0, bHandled);
430
431 return hr;
432 }
433
434 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetIconSize(THIS_ DWORD* piIcon)
435 {
436 if (piIcon)
437 *piIcon = m_IconSize;
438 return S_OK;
439 }
440
441 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetBitmap(THIS_ HBITMAP hBitmap)
442 {
443 m_Banner = hBitmap;
444
445 BOOL bHandled;
446 _OnSize(WM_SIZE, 0, 0, bHandled);
447
448 return S_OK;
449 }
450
451 HRESULT STDMETHODCALLTYPE CMenuDeskBar::GetBitmap(THIS_ HBITMAP* phBitmap)
452 {
453 if (phBitmap)
454 *phBitmap = m_Banner;
455 return S_OK;
456 }
457
458 HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
459 {
460 // Called by the MenuBand to assign itself as the logical child of the DeskBar
461
462 if (fSet)
463 {
464 m_SubMenuChild = pmp;
465 }
466 else
467 {
468 if (m_SubMenuChild)
469 {
470 if (pmp == m_SubMenuChild)
471 {
472 m_SubMenuChild = NULL;
473 }
474 }
475 }
476 return S_OK;
477 }
478
479 HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
480 {
481 CComPtr<IDeskBar> safeThis = this;
482
483 /* As far as I can tell, the submenu hierarchy looks like this:
484 *
485 * The DeskBar's Child is the Band it contains.
486 * The DeskBar's Parent is the SID_SMenuPopup of the Site.
487 *
488 * The Band's Child is the IMenuPopup of the child submenu.
489 * The Band's Parent is the SID_SMenuPopup of the Site (the DeskBar).
490 *
491 * When the DeskBar receives a selection event:
492 * If it requires closing the window, it will notify the Child (Band) using CancelLevel.
493 * If it has to spread upwards (everything but CancelLevel), it will notify the Parent.
494 *
495 * When the Band receives a selection event, this is where it gets fuzzy:
496 * In which cases does it call the Parent? Probably not CancelLevel.
497 * In which cases does it call the Child?
498 * How does it react to calls?
499 *
500 */
501
502 CComPtr<IMenuPopup> oldParent = m_SubMenuParent;
503
504 switch (dwSelectType)
505 {
506 case MPOS_EXECUTE:
507 case MPOS_FULLCANCEL:
508 case MPOS_CANCELLEVEL:
509
510 _CloseBar();
511
512 if (dwSelectType == MPOS_CANCELLEVEL)
513 return S_OK;
514
515 case MPOS_SELECTLEFT:
516 case MPOS_SELECTRIGHT:
517 case MPOS_CHILDTRACKING:
518 if (oldParent)
519 return oldParent->OnSelect(dwSelectType);
520 break;
521 }
522
523 return S_OK;
524 }
525
526 HRESULT CMenuDeskBar::_CloseBar()
527 {
528 CComPtr<IDeskBar> safeThis = this;
529 CComPtr<IDeskBarClient> dbc;
530 HRESULT hr;
531
532 m_Shown = false;
533
534 if (m_SubMenuParent)
535 {
536 m_SubMenuParent->SetSubMenu(this, FALSE);
537 }
538
539 if (m_SubMenuChild)
540 {
541 hr = m_SubMenuChild->OnSelect(MPOS_CANCELLEVEL);
542 if (FAILED_UNEXPECTEDLY(hr))
543 return hr;
544 }
545
546 hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &dbc));
547 if (FAILED_UNEXPECTEDLY(hr))
548 return hr;
549
550 hr = dbc->UIActivateDBC(FALSE);
551 if (FAILED_UNEXPECTEDLY(hr))
552 return hr;
553
554 SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE);
555
556 return UIActivateIO(FALSE, NULL);
557 }
558
559 BOOL CMenuDeskBar::_IsSubMenuParent(HWND hwnd)
560 {
561 CComPtr<IMenuPopup> popup = m_SubMenuParent;
562
563 while (popup)
564 {
565 HRESULT hr;
566 CComPtr<IOleWindow> window;
567
568 hr = popup->QueryInterface(IID_PPV_ARG(IOleWindow, &window));
569 if (FAILED_UNEXPECTEDLY(hr))
570 return FALSE;
571
572 HWND parent;
573
574 hr = window->GetWindow(&parent);
575 if (SUCCEEDED(hr) && hwnd == parent)
576 return TRUE;
577
578 popup = NULL;
579 hr = IUnknown_GetSite(window, IID_PPV_ARG(IMenuPopup, &popup));
580 if (FAILED(hr))
581 return FALSE;
582 }
583
584 return FALSE;
585 }
586
587 LRESULT CMenuDeskBar::_OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
588 {
589 if (m_Client)
590 {
591 RECT rc;
592
593 GetClientRect(&rc);
594
595 if (m_Banner != NULL)
596 {
597 BITMAP bm;
598 ::GetObject(m_Banner, sizeof(bm), &bm);
599 rc.left += bm.bmWidth;
600 }
601
602 ::SetWindowPos(m_ClientWindow, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 0);
603 }
604
605 return 0;
606 }
607
608 LRESULT CMenuDeskBar::_OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
609 {
610 if (!m_Client)
611 return 0;
612
613 CComPtr<IWinEventHandler> winEventHandler;
614 HRESULT hr = m_Client->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
615 if (FAILED_UNEXPECTEDLY(hr))
616 return 0;
617
618 if (winEventHandler)
619 {
620 LRESULT result;
621 hr = winEventHandler->OnWinEvent(NULL, uMsg, wParam, lParam, &result);
622 if (FAILED_UNEXPECTEDLY(hr))
623 return 0;
624 return result;
625 }
626
627 return 0;
628 }
629
630 LRESULT CMenuDeskBar::_OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
631 {
632 bHandled = FALSE;
633
634 if (m_Banner && !m_IconSize)
635 {
636 BITMAP bm;
637 PAINTSTRUCT ps;
638 HDC hdc = BeginPaint(&ps);
639
640 HDC hdcMem = ::CreateCompatibleDC(hdc);
641 HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_Banner);
642
643 ::GetObject(m_Banner, sizeof(bm), &bm);
644
645 RECT rc;
646 if (!GetClientRect(&rc))
647 WARN("GetClientRect failed\n");
648
649 const int bx = bm.bmWidth;
650 const int by = bm.bmHeight;
651 const int cy = rc.bottom;
652
653 TRACE("Painting banner: %d by %d\n", bm.bmWidth, bm.bmHeight);
654
655 if (!::StretchBlt(hdc, 0, 0, bx, cy - by, hdcMem, 0, 0, bx, 1, SRCCOPY))
656 WARN("StretchBlt failed\n");
657
658 if (!::BitBlt(hdc, 0, cy - by, bx, by, hdcMem, 0, 0, SRCCOPY))
659 WARN("BitBlt failed\n");
660
661 ::SelectObject(hdcMem, hbmOld);
662 ::DeleteDC(hdcMem);
663
664 EndPaint(&ps);
665 }
666
667 return TRUE;
668 }
669
670 LRESULT CMenuDeskBar::_OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
671 {
672 // BUG in ReactOS: WM_ACTIVATE/WA_INACTIVE makes no sense with lParam==hWnd
673 if (LOWORD(wParam) != 0 || reinterpret_cast<HWND>(lParam) == m_hWnd)
674 {
675 return 0;
676 }
677
678 // HACK! I just want it to work !!!
679 CComPtr<IDeskBar> db;
680 HRESULT hr = IUnknown_QueryService(m_Client, SID_SMenuBandChild, IID_PPV_ARG(IDeskBar, &db));
681 if (FAILED_UNEXPECTEDLY(hr))
682 return 0;
683
684 CComPtr<IUnknown> punk;
685
686 hr = db->GetClient(&punk);
687 if (FAILED_UNEXPECTEDLY(hr))
688 return 0;
689
690 if (!punk && m_Shown)
691 {
692 if (!_IsSubMenuParent(reinterpret_cast<HWND>(lParam)))
693 {
694 OnSelect(MPOS_FULLCANCEL);
695 }
696 }
697
698 return 0;
699 }
700
701 LRESULT CMenuDeskBar::_OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
702 {
703 return MA_NOACTIVATE;
704 }
705
706 LRESULT CMenuDeskBar::_OnAppActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
707 {
708 if (wParam == 0 && m_Shown)
709 {
710 OnSelect(MPOS_FULLCANCEL);
711 }
712 return 0;
713 }