mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 00:20:34 +00:00

CORE-18855 Add a call to _ChangeHotItem(NULL, -1, 0) in CMenuBand::OnSelect(MPOS_CANCELLEVEL) which causes to deselect currently selected item the moment the menu bands (including start menu) are closing. Start Menu is not destroyed when it's closed so its allocated resources can be re-used next time user wants to open it, so to keep this behavior and still not having an item selected every time you open the start menu, you have to deselect the currently selected item.
1326 lines
32 KiB
C++
1326 lines
32 KiB
C++
/*
|
|
* Shell Menu Band
|
|
*
|
|
* Copyright 2014 David Quintana
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
#include "shellmenu.h"
|
|
#include <windowsx.h>
|
|
#include <commoncontrols.h>
|
|
#include <shlwapi_undoc.h>
|
|
|
|
#include "CMenuBand.h"
|
|
#include "CMenuToolbars.h"
|
|
#include "CMenuFocusManager.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand);
|
|
|
|
#undef UNIMPLEMENTED
|
|
|
|
#define UNIMPLEMENTED TRACE("%s is UNIMPLEMENTED!\n", __FUNCTION__)
|
|
|
|
CMenuBand::CMenuBand() :
|
|
m_staticToolbar(NULL),
|
|
m_SFToolbar(NULL),
|
|
m_site(NULL),
|
|
m_psmc(NULL),
|
|
m_subMenuChild(NULL),
|
|
m_subMenuParent(NULL),
|
|
m_childBand(NULL),
|
|
m_parentBand(NULL),
|
|
m_hmenu(NULL),
|
|
m_menuOwner(NULL),
|
|
m_useBigIcons(FALSE),
|
|
m_topLevelWindow(NULL),
|
|
m_hotBar(NULL),
|
|
m_hotItem(-1),
|
|
m_popupBar(NULL),
|
|
m_popupItem(-1),
|
|
m_Show(FALSE),
|
|
m_shellBottom(FALSE),
|
|
m_trackedPopup(NULL),
|
|
m_trackedHwnd(NULL)
|
|
{
|
|
m_focusManager = CMenuFocusManager::AcquireManager();
|
|
}
|
|
|
|
CMenuBand::~CMenuBand()
|
|
{
|
|
CMenuFocusManager::ReleaseManager(m_focusManager);
|
|
|
|
delete m_staticToolbar;
|
|
delete m_SFToolbar;
|
|
|
|
if (m_hmenu)
|
|
DestroyMenu(m_hmenu);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(
|
|
IShellMenuCallback *psmc,
|
|
UINT uId,
|
|
UINT uIdAncestor,
|
|
DWORD dwFlags)
|
|
{
|
|
if (m_psmc != psmc)
|
|
m_psmc = psmc;
|
|
m_uId = uId;
|
|
m_uIdAncestor = uIdAncestor;
|
|
m_dwFlags = dwFlags;
|
|
|
|
if (m_psmc)
|
|
{
|
|
_CallCB(SMC_CREATE, 0, reinterpret_cast<LPARAM>(&m_UserData));
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
|
|
IShellMenuCallback **ppsmc,
|
|
UINT *puId,
|
|
UINT *puIdAncestor,
|
|
DWORD *pdwFlags)
|
|
{
|
|
if (!pdwFlags) // maybe?
|
|
return E_INVALIDARG;
|
|
|
|
if (ppsmc)
|
|
{
|
|
*ppsmc = m_psmc;
|
|
if (*ppsmc)
|
|
(*ppsmc)->AddRef();
|
|
}
|
|
|
|
if (puId)
|
|
*puId = m_uId;
|
|
|
|
if (puIdAncestor)
|
|
*puIdAncestor = m_uIdAncestor;
|
|
|
|
*pdwFlags = m_dwFlags;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(
|
|
HMENU hmenu,
|
|
HWND hwnd,
|
|
DWORD dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
|
|
TRACE("CMenuBand::SetMenu called, hmenu=%p; hwnd=%p, flags=%x\n", hmenu, hwnd, dwFlags);
|
|
|
|
BOOL created = FALSE;
|
|
|
|
if (m_hmenu && m_hmenu != hmenu)
|
|
{
|
|
DestroyMenu(m_hmenu);
|
|
m_hmenu = NULL;
|
|
}
|
|
|
|
m_hmenu = hmenu;
|
|
m_menuOwner = hwnd;
|
|
|
|
if (m_hmenu && m_staticToolbar == NULL)
|
|
{
|
|
m_staticToolbar = new CMenuStaticToolbar(this);
|
|
created = true;
|
|
}
|
|
|
|
if (m_staticToolbar)
|
|
{
|
|
hr = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (m_site)
|
|
{
|
|
HWND hwndParent;
|
|
|
|
hr = m_site->GetWindow(&hwndParent);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (created)
|
|
{
|
|
hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_staticToolbar->FillToolbar();
|
|
}
|
|
else
|
|
{
|
|
hr = m_staticToolbar->FillToolbar(TRUE);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(
|
|
HMENU *phmenu,
|
|
HWND *phwnd,
|
|
DWORD *pdwFlags)
|
|
{
|
|
if (m_staticToolbar == NULL)
|
|
return E_FAIL;
|
|
|
|
return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite)
|
|
{
|
|
HWND hwndParent;
|
|
HRESULT hr;
|
|
|
|
m_site = NULL;
|
|
|
|
if (pUnkSite == NULL)
|
|
return S_OK;
|
|
|
|
hwndParent = NULL;
|
|
hr = pUnkSite->QueryInterface(IID_PPV_ARG(IOleWindow, &m_site));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_site->GetWindow(&hwndParent);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (!::IsWindow(hwndParent))
|
|
return E_FAIL;
|
|
|
|
if (m_staticToolbar != NULL)
|
|
{
|
|
hr = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_staticToolbar->FillToolbar();
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (m_SFToolbar != NULL)
|
|
{
|
|
hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_SFToolbar->FillToolbar();
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_subMenuParent));
|
|
if (hr != E_NOINTERFACE && FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
CComPtr<IOleWindow> pTopLevelWindow;
|
|
hr = IUnknown_QueryService(m_site, SID_STopLevelBrowser, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
m_topLevelWindow = hwndParent;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite)
|
|
{
|
|
if (m_site == NULL)
|
|
return E_FAIL;
|
|
|
|
return m_site->QueryInterface(riid, ppvSite);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(HWND *phwnd)
|
|
{
|
|
if (m_SFToolbar != NULL)
|
|
return m_SFToolbar->GetWindow(phwnd);
|
|
|
|
if (m_staticToolbar != NULL)
|
|
return m_staticToolbar->GetWindow(phwnd);
|
|
|
|
if (phwnd) *phwnd = NULL;
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::OnPosRectChangeDB(RECT *prc)
|
|
{
|
|
SIZE maxStatic = { 0 };
|
|
SIZE maxShlFld = { 0 };
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_staticToolbar != NULL)
|
|
hr = m_staticToolbar->GetSizes(NULL, &maxStatic, NULL);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (m_SFToolbar != NULL)
|
|
hr = m_SFToolbar->GetSizes(NULL, &maxShlFld, NULL);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
|
return E_FAIL;
|
|
|
|
int sy = min(prc->bottom - prc->top, maxStatic.cy + maxShlFld.cy);
|
|
|
|
int syStatic = maxStatic.cy;
|
|
int syShlFld = sy - syStatic;
|
|
|
|
// TODO: Windows has a more complex system to decide ordering.
|
|
// Because we only support two toolbars at once, this is enough for us.
|
|
if (m_shellBottom)
|
|
{
|
|
// Static menu on top
|
|
if (m_SFToolbar)
|
|
{
|
|
m_SFToolbar->SetPosSize(
|
|
prc->left,
|
|
prc->top + syStatic,
|
|
prc->right - prc->left,
|
|
syShlFld);
|
|
}
|
|
if (m_staticToolbar)
|
|
{
|
|
m_staticToolbar->SetPosSize(
|
|
prc->left,
|
|
prc->top,
|
|
prc->right - prc->left,
|
|
syStatic);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Folder menu on top
|
|
if (m_SFToolbar)
|
|
{
|
|
m_SFToolbar->SetPosSize(
|
|
prc->left,
|
|
prc->top,
|
|
prc->right - prc->left,
|
|
syShlFld);
|
|
}
|
|
if (m_staticToolbar)
|
|
{
|
|
m_staticToolbar->SetPosSize(
|
|
prc->left,
|
|
prc->top + syShlFld,
|
|
prc->right - prc->left,
|
|
syStatic);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(
|
|
DWORD dwBandID,
|
|
DWORD dwViewMode,
|
|
DESKBANDINFO *pdbi)
|
|
{
|
|
SIZE minStatic = { 0 };
|
|
SIZE minShlFld = { 0 };
|
|
SIZE maxStatic = { 0 };
|
|
SIZE maxShlFld = { 0 };
|
|
SIZE intStatic = { 0 };
|
|
SIZE intShlFld = { 0 };
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_staticToolbar != NULL)
|
|
hr = m_staticToolbar->GetSizes(&minStatic, &maxStatic, &intStatic);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (m_SFToolbar != NULL)
|
|
hr = m_SFToolbar->GetSizes(&minShlFld, &maxShlFld, &intShlFld);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
if (m_staticToolbar == NULL && m_SFToolbar == NULL)
|
|
return E_FAIL;
|
|
|
|
if (m_dwFlags & SMINIT_VERTICAL)
|
|
{
|
|
pdbi->ptMinSize.x = max(minStatic.cx, minShlFld.cx) + 20;
|
|
pdbi->ptMinSize.y = minStatic.cy + minShlFld.cy;
|
|
pdbi->ptMaxSize.x = max(maxStatic.cx, maxShlFld.cx) + 20;
|
|
pdbi->ptMaxSize.y = maxStatic.cy + maxShlFld.cy;
|
|
pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
|
|
}
|
|
else
|
|
{
|
|
pdbi->ptMinSize.x = minStatic.cx + minShlFld.cx;
|
|
pdbi->ptMinSize.y = max(minStatic.cy, minShlFld.cy);
|
|
pdbi->ptMaxSize.x = maxStatic.cx + maxShlFld.cx;
|
|
pdbi->ptMaxSize.y = max(maxStatic.cy, maxShlFld.cy);
|
|
}
|
|
pdbi->ptIntegral.x = max(intStatic.cx, intShlFld.cx);
|
|
pdbi->ptIntegral.y = max(intStatic.cy, intShlFld.cy);
|
|
pdbi->ptActual = pdbi->ptMinSize;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_Show == fShow)
|
|
return S_OK;
|
|
|
|
m_Show = fShow;
|
|
|
|
if (m_staticToolbar != NULL)
|
|
{
|
|
hr = m_staticToolbar->ShowDW(fShow);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (m_SFToolbar != NULL)
|
|
{
|
|
hr = m_SFToolbar->ShowDW(fShow);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (fShow)
|
|
{
|
|
hr = _CallCB(SMC_INITMENU, 0, 0);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
else if (m_parentBand)
|
|
{
|
|
m_parentBand->SetClient(NULL);
|
|
}
|
|
|
|
if (_IsPopup() == S_OK)
|
|
{
|
|
if (fShow)
|
|
hr = m_focusManager->PushMenuPopup(this);
|
|
else
|
|
hr = m_focusManager->PopMenuPopup(this);
|
|
}
|
|
else
|
|
{
|
|
if (fShow)
|
|
hr = m_focusManager->PushMenuBar(this);
|
|
else
|
|
hr = m_focusManager->PopMenuBar(this);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
|
|
{
|
|
if (m_subMenuChild)
|
|
{
|
|
m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
|
|
}
|
|
|
|
if (m_subMenuChild)
|
|
{
|
|
TRACE("Child object should have removed itself.\n");
|
|
}
|
|
|
|
ShowDW(FALSE);
|
|
|
|
if (m_staticToolbar != NULL)
|
|
{
|
|
m_staticToolbar->Close();
|
|
}
|
|
|
|
if (m_SFToolbar != NULL)
|
|
{
|
|
m_SFToolbar->Close();
|
|
}
|
|
|
|
if (m_site) m_site.Release();
|
|
if (m_subMenuChild) m_subMenuChild.Release();
|
|
if (m_subMenuParent) m_subMenuParent.Release();
|
|
if (m_childBand) m_childBand.Release();
|
|
if (m_parentBand) m_parentBand.Release();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (m_subMenuParent)
|
|
{
|
|
hr = m_subMenuParent->SetSubMenu(this, fActivate);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (fActivate)
|
|
{
|
|
CComPtr<IOleWindow> pTopLevelWindow;
|
|
hr = IUnknown_QueryService(m_site, SID_SMenuPopup, IID_PPV_ARG(IOleWindow, &pTopLevelWindow));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = pTopLevelWindow->GetWindow(&m_topLevelWindow);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
}
|
|
else
|
|
{
|
|
m_topLevelWindow = NULL;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
|
{
|
|
if (!pguidCmdGroup)
|
|
return E_FAIL;
|
|
|
|
if (IsEqualGUID(*pguidCmdGroup, CLSID_MenuBand))
|
|
{
|
|
if (nCmdID == 16) // set (big) icon size
|
|
{
|
|
this->m_useBigIcons = nCmdexecopt == 2;
|
|
return S_OK;
|
|
}
|
|
else if (nCmdID == 19) // popup-related
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
else if (nCmdID == 5) // select an item
|
|
{
|
|
if (nCmdexecopt == 0) // first
|
|
{
|
|
_KeyboardItemChange(VK_HOME);
|
|
}
|
|
else // last
|
|
{
|
|
_KeyboardItemChange(VK_END);
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
|
|
{
|
|
if (IsEqualIID(guidService, SID_SMenuBandChild) ||
|
|
IsEqualIID(guidService, SID_SMenuBandBottom) ||
|
|
IsEqualIID(guidService, SID_SMenuBandBottomSelected))
|
|
return this->QueryInterface(riid, ppvObject);
|
|
WARN("Unknown service requested %s\n", wine_dbgstr_guid(&guidService));
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::Popup(POINTL *ppt, RECTL *prcExclude, MP_POPUPFLAGS dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::OnSelect(DWORD dwSelectType)
|
|
{
|
|
// When called from outside, this is straightforward:
|
|
// Things that a submenu needs to know, are spread down, and
|
|
// things that the parent needs to know, are spread up. No drama.
|
|
// The fun is in _MenuItemSelect (internal method).
|
|
switch (dwSelectType)
|
|
{
|
|
case MPOS_CHILDTRACKING:
|
|
if (!m_subMenuParent)
|
|
break;
|
|
// TODO: Cancel timers?
|
|
return m_subMenuParent->OnSelect(dwSelectType);
|
|
case MPOS_SELECTLEFT:
|
|
if (m_subMenuChild)
|
|
m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
|
|
if (!m_subMenuParent)
|
|
break;
|
|
return m_subMenuParent->OnSelect(dwSelectType);
|
|
case MPOS_SELECTRIGHT:
|
|
if (!m_subMenuParent)
|
|
break;
|
|
return m_subMenuParent->OnSelect(dwSelectType);
|
|
case MPOS_EXECUTE:
|
|
case MPOS_FULLCANCEL:
|
|
if (m_subMenuChild)
|
|
m_subMenuChild->OnSelect(dwSelectType);
|
|
if (!m_subMenuParent)
|
|
break;
|
|
return m_subMenuParent->OnSelect(dwSelectType);
|
|
case MPOS_CANCELLEVEL:
|
|
if (m_subMenuChild)
|
|
m_subMenuChild->OnSelect(dwSelectType);
|
|
// Deselect the currently selected item
|
|
_ChangeHotItem(NULL, -1, 0);
|
|
break;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
// Used by the focus manager to update the child band pointer
|
|
HRESULT CMenuBand::_SetChildBand(CMenuBand * child)
|
|
{
|
|
m_childBand = child;
|
|
if (!child)
|
|
{
|
|
_ChangePopupItem(NULL, -1);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
// User by the focus manager to update the parent band pointer
|
|
HRESULT CMenuBand::_SetParentBand(CMenuBand * parent)
|
|
{
|
|
m_parentBand = parent;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_IsPopup()
|
|
{
|
|
return !(m_dwFlags & SMINIT_VERTICAL);
|
|
}
|
|
|
|
HRESULT CMenuBand::_IsTracking()
|
|
{
|
|
return m_popupBar != NULL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
|
|
{
|
|
CComPtr<IMenuPopup> child = m_subMenuChild;
|
|
|
|
m_subMenuChild = NULL;
|
|
|
|
if (child)
|
|
{
|
|
IUnknown_SetSite(child, NULL);
|
|
child.Release();
|
|
}
|
|
|
|
if (!punkClient)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
return punkClient->QueryInterface(IID_PPV_ARG(IMenuPopup, &m_subMenuChild));
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetClient(IUnknown **ppunkClient)
|
|
{
|
|
if (!ppunkClient)
|
|
return E_POINTER;
|
|
*ppunkClient = NULL;
|
|
|
|
if (m_subMenuChild)
|
|
{
|
|
*ppunkClient = m_subMenuChild;
|
|
(*ppunkClient)->AddRef();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::IsMenuMessage(MSG *pmsg)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *plRet)
|
|
{
|
|
if (pmsg->message == WM_ACTIVATE && _IsPopup() == S_FALSE)
|
|
{
|
|
if (m_staticToolbar)
|
|
m_staticToolbar->Invalidate();
|
|
if (m_SFToolbar)
|
|
m_SFToolbar->Invalidate();
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags)
|
|
{
|
|
if (!psf)
|
|
return E_INVALIDARG;
|
|
|
|
if (m_SFToolbar == NULL)
|
|
{
|
|
m_SFToolbar = new CMenuSFToolbar(this);
|
|
}
|
|
|
|
HRESULT hr = m_SFToolbar->SetShellFolder(psf, pidlFolder, hKey, dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
m_shellBottom = (dwFlags & SMSET_BOTTOM) != 0;
|
|
|
|
if (m_site)
|
|
{
|
|
HWND hwndParent;
|
|
|
|
hr = m_site->GetWindow(&hwndParent);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_SFToolbar->CreateToolbar(hwndParent, m_dwFlags);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = m_SFToolbar->FillToolbar();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIST *ppidl, REFIID riid, void **ppv)
|
|
{
|
|
if (m_SFToolbar)
|
|
return m_SFToolbar->GetShellFolder(pdwFlags, ppidl, riid, ppv);
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
|
{
|
|
if (theResult)
|
|
*theResult = 0;
|
|
|
|
if (uMsg == WM_WININICHANGE && wParam == SPI_SETFLATMENU)
|
|
{
|
|
BOOL bFlatMenus;
|
|
SystemParametersInfo(SPI_GETFLATMENU, 0, &bFlatMenus, 0);
|
|
AdjustForTheme(bFlatMenus);
|
|
|
|
if (m_staticToolbar)
|
|
m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
|
|
|
|
if (m_SFToolbar)
|
|
m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
|
|
{
|
|
return m_staticToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
|
|
}
|
|
|
|
if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
|
|
{
|
|
return m_SFToolbar->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::IsWindowOwner(HWND hWnd)
|
|
{
|
|
if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hWnd) == S_OK)
|
|
return S_OK;
|
|
|
|
if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hWnd) == S_OK)
|
|
return S_OK;
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT CMenuBand::_CallCBWithItemId(UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return _CallCB(uMsg, wParam, lParam, id);
|
|
}
|
|
|
|
HRESULT CMenuBand::_CallCBWithItemPidl(LPITEMIDLIST pidl, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return _CallCB(uMsg, wParam, lParam, 0, pidl);
|
|
}
|
|
|
|
HRESULT CMenuBand::_CallCB(UINT uMsg, WPARAM wParam, LPARAM lParam, UINT id, LPITEMIDLIST pidl)
|
|
{
|
|
if (!m_psmc)
|
|
return S_FALSE;
|
|
|
|
SMDATA smData = { 0 };
|
|
smData.punk = static_cast<IShellMenu2*>(this);
|
|
smData.uId = id;
|
|
smData.uIdParent = m_uId;
|
|
smData.uIdAncestor = m_uIdAncestor;
|
|
smData.pidlItem = pidl;
|
|
smData.hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
|
|
smData.hmenu = m_hmenu;
|
|
if (m_SFToolbar)
|
|
m_SFToolbar->GetShellFolder(NULL, &smData.pidlFolder, IID_PPV_ARG(IShellFolder, &smData.psf));
|
|
HRESULT hr = m_psmc->CallbackSM(&smData, uMsg, wParam, lParam);
|
|
ILFree(smData.pidlFolder);
|
|
if (smData.psf)
|
|
smData.psf->Release();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMenuBand::_TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude)
|
|
{
|
|
TPMPARAMS params = { sizeof(TPMPARAMS), rcExclude };
|
|
UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN;
|
|
HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
|
|
|
|
m_trackedPopup = popup;
|
|
m_trackedHwnd = hwnd;
|
|
|
|
m_focusManager->PushTrackedPopup(popup);
|
|
::TrackPopupMenuEx(popup, flags, x, y, hwnd, ¶ms);
|
|
m_focusManager->PopTrackedPopup(popup);
|
|
|
|
m_trackedPopup = NULL;
|
|
m_trackedHwnd = NULL;
|
|
|
|
_DisableMouseTrack(FALSE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_TrackContextMenu(IContextMenu * contextMenu, INT x, INT y)
|
|
{
|
|
HRESULT hr;
|
|
UINT uCommand;
|
|
|
|
// Ensure that the menu doesn't disappear on us
|
|
CComPtr<IContextMenu> ctxMenu = contextMenu;
|
|
|
|
HMENU popup = CreatePopupMenu();
|
|
|
|
if (popup == NULL)
|
|
return E_FAIL;
|
|
|
|
TRACE("Before Query\n");
|
|
UINT cmf = CMF_NORMAL;
|
|
if (GetKeyState(VK_SHIFT) < 0)
|
|
cmf |= CMF_EXTENDEDVERBS;
|
|
|
|
const UINT idCmdFirst = 100, idCmdLast = 0xffff;
|
|
hr = contextMenu->QueryContextMenu(popup, 0, idCmdFirst, idCmdLast, cmf);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
{
|
|
TRACE("Query failed\n");
|
|
DestroyMenu(popup);
|
|
return hr;
|
|
}
|
|
|
|
HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow;
|
|
|
|
m_focusManager->PushTrackedPopup(popup);
|
|
|
|
TRACE("Before Tracking\n");
|
|
uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, hwnd, NULL);
|
|
|
|
m_focusManager->PopTrackedPopup(popup);
|
|
|
|
if (uCommand != 0)
|
|
{
|
|
_MenuItemSelect(MPOS_FULLCANCEL);
|
|
|
|
TRACE("Before InvokeCommand\n");
|
|
CMINVOKECOMMANDINFO cmi = { sizeof(cmi), 0, hwnd };
|
|
cmi.lpVerb = MAKEINTRESOURCEA(uCommand - idCmdFirst);
|
|
if (GetKeyState(VK_SHIFT) < 0)
|
|
cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
|
|
if (GetKeyState(VK_CONTROL) < 0)
|
|
cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
|
|
cmi.nShow = SW_SHOW;
|
|
hr = contextMenu->InvokeCommand(&cmi);
|
|
TRACE("InvokeCommand returned hr=%08x\n", hr);
|
|
}
|
|
else
|
|
{
|
|
TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
DestroyMenu(popup);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMenuBand::_GetTopLevelWindow(HWND*topLevel)
|
|
{
|
|
*topLevel = m_topLevelWindow;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_ChangeHotItem(CMenuToolbarBase * tb, INT id, DWORD dwFlags)
|
|
{
|
|
if (m_hotBar == tb && m_hotItem == id)
|
|
return S_FALSE;
|
|
|
|
TRACE("Hot item changed from %p %p, to %p %p\n", m_hotBar, m_hotItem, tb, id);
|
|
|
|
_KillPopupTimers();
|
|
|
|
m_hotBar = tb;
|
|
m_hotItem = id;
|
|
if (m_staticToolbar) m_staticToolbar->ChangeHotItem(tb, id, dwFlags);
|
|
if (m_SFToolbar) m_SFToolbar->ChangeHotItem(tb, id, dwFlags);
|
|
|
|
_MenuItemSelect(MPOS_CHILDTRACKING);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_ChangePopupItem(CMenuToolbarBase * tb, INT id)
|
|
{
|
|
TRACE("Popup item changed from %p %p, to %p %p\n", m_popupBar, m_popupItem, tb, id);
|
|
|
|
m_popupBar = tb;
|
|
m_popupItem = id;
|
|
if (m_staticToolbar) m_staticToolbar->ChangePopupItem(tb, id);
|
|
if (m_SFToolbar) m_SFToolbar->ChangePopupItem(tb, id);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_KeyboardItemChange(DWORD change)
|
|
{
|
|
HRESULT hr;
|
|
CMenuToolbarBase *tb = m_hotBar;
|
|
|
|
if (!tb)
|
|
{
|
|
// If no hot item was selected choose the appropriate toolbar
|
|
if (change == VK_UP || change == VK_END)
|
|
{
|
|
if (m_staticToolbar)
|
|
tb = m_staticToolbar;
|
|
else
|
|
tb = m_SFToolbar;
|
|
}
|
|
else if (change == VK_DOWN || change == VK_HOME)
|
|
{
|
|
if (m_SFToolbar)
|
|
tb = m_SFToolbar;
|
|
else
|
|
tb = m_staticToolbar;
|
|
}
|
|
}
|
|
|
|
// Ask the first toolbar to change
|
|
hr = tb->KeyboardItemChange(change);
|
|
|
|
if (hr != S_FALSE)
|
|
return hr;
|
|
|
|
// Select the second toolbar based on the first
|
|
if (tb == m_SFToolbar && m_staticToolbar)
|
|
tb = m_staticToolbar;
|
|
else if (m_SFToolbar)
|
|
tb = m_SFToolbar;
|
|
|
|
if (!tb)
|
|
return hr;
|
|
|
|
// Ask the second toolbar to change
|
|
return tb->KeyboardItemChange(change == VK_DOWN ? VK_HOME : VK_END);
|
|
}
|
|
|
|
HRESULT CMenuBand::_MenuItemSelect(DWORD changeType)
|
|
{
|
|
// Needed to prevent the this point from vanishing mid-function
|
|
CComPtr<CMenuBand> safeThis = this;
|
|
HRESULT hr;
|
|
|
|
if (m_dwFlags & SMINIT_VERTICAL)
|
|
{
|
|
switch (changeType)
|
|
{
|
|
case VK_UP:
|
|
case VK_DOWN:
|
|
return _KeyboardItemChange(changeType);
|
|
|
|
// TODO: Left/Right across multi-column menus, if they ever work.
|
|
case VK_LEFT:
|
|
changeType = MPOS_SELECTLEFT;
|
|
break;
|
|
case VK_RIGHT:
|
|
changeType = MPOS_SELECTRIGHT;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// In horizontal menubars, left/right are equivalent to vertical's up/down
|
|
switch (changeType)
|
|
{
|
|
case VK_LEFT:
|
|
hr = _KeyboardItemChange(VK_UP);
|
|
if (hr != S_FALSE)
|
|
return hr;
|
|
case VK_RIGHT:
|
|
hr = _KeyboardItemChange(VK_DOWN);
|
|
if (hr != S_FALSE)
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
// In this context, the parent is the CMenuDeskBar, so when it bubbles upward,
|
|
// it is notifying the deskbar, and not the the higher-level menu.
|
|
// Same for the child: since it points to a CMenuDeskBar, it's not just recursing.
|
|
switch (changeType)
|
|
{
|
|
case MPOS_EXECUTE:
|
|
{
|
|
CMenuToolbarBase * tb = m_hotBar;
|
|
int item = m_hotItem;
|
|
tb->PrepareExecuteItem(item);
|
|
if (m_subMenuParent)
|
|
{
|
|
m_subMenuParent->OnSelect(changeType);
|
|
}
|
|
TRACE("Menu closed, executing item...\n");
|
|
tb->ExecuteItem();
|
|
break;
|
|
}
|
|
case MPOS_SELECTLEFT:
|
|
if (m_parentBand && m_parentBand->_IsPopup()==S_FALSE)
|
|
return m_parentBand->_MenuItemSelect(VK_LEFT);
|
|
if (m_subMenuChild)
|
|
return m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
|
|
if (!m_subMenuParent)
|
|
return S_OK;
|
|
return m_subMenuParent->OnSelect(MPOS_CANCELLEVEL);
|
|
|
|
case MPOS_SELECTRIGHT:
|
|
if (m_hotBar && m_hotItem >= 0 && m_hotBar->PopupItem(m_hotItem, TRUE) == S_OK)
|
|
return S_FALSE;
|
|
if (m_parentBand)
|
|
return m_parentBand->_MenuItemSelect(VK_RIGHT);
|
|
if (!m_subMenuParent)
|
|
return S_OK;
|
|
return m_subMenuParent->OnSelect(MPOS_SELECTRIGHT);
|
|
|
|
default:
|
|
if (!m_subMenuParent)
|
|
return S_OK;
|
|
return m_subMenuParent->OnSelect(changeType);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_CancelCurrentPopup()
|
|
{
|
|
if (m_subMenuChild)
|
|
{
|
|
HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL);
|
|
return hr;
|
|
}
|
|
|
|
if (m_trackedPopup)
|
|
{
|
|
::SendMessage(m_trackedHwnd, WM_CANCELMODE, 0, 0);
|
|
return S_OK;
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude, BOOL keyInitiated)
|
|
{
|
|
HRESULT hr = 0;
|
|
CComPtr<IBandSite> pBandSite;
|
|
CComPtr<IDeskBar> pDeskBar;
|
|
|
|
// Create the necessary objects
|
|
hr = CMenuSite_CreateInstance(IID_PPV_ARG(IBandSite, &pBandSite));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = CMenuDeskBar_CreateInstance(IID_PPV_ARG(IDeskBar, &pDeskBar));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = pDeskBar->SetClient(pBandSite);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
hr = pBandSite->AddBand(childShellMenu);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
//
|
|
CComPtr<IMenuPopup> popup;
|
|
hr = pDeskBar->QueryInterface(IID_PPV_ARG(IMenuPopup, &popup));
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
return hr;
|
|
|
|
m_subMenuChild = popup;
|
|
|
|
if (m_subMenuParent)
|
|
IUnknown_SetSite(popup, m_subMenuParent);
|
|
else
|
|
IUnknown_SetSite(popup, m_site);
|
|
|
|
DWORD flags = MPPF_RIGHT;
|
|
|
|
if (keyInitiated && m_dwFlags & SMINIT_VERTICAL)
|
|
flags |= MPPF_INITIALSELECT;
|
|
|
|
popup->Popup(pAt, pExclude, flags);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_BeforeCancelPopup()
|
|
{
|
|
if (m_staticToolbar)
|
|
m_staticToolbar->BeforeCancelPopup();
|
|
if (m_SFToolbar)
|
|
m_SFToolbar->BeforeCancelPopup();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_DisableMouseTrack(BOOL bDisable)
|
|
{
|
|
if (m_staticToolbar)
|
|
m_staticToolbar->DisableMouseTrack(bDisable);
|
|
if (m_SFToolbar)
|
|
m_SFToolbar->DisableMouseTrack(bDisable);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_KillPopupTimers()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if (m_staticToolbar)
|
|
hr = m_staticToolbar->KillPopupTimer();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
if (m_SFToolbar)
|
|
hr = m_SFToolbar->KillPopupTimer();
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMenuBand::_MenuBarMouseDown(HWND hwnd, INT item, BOOL isLButton)
|
|
{
|
|
if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hwnd) == S_OK)
|
|
m_staticToolbar->MenuBarMouseDown(item, isLButton);
|
|
if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hwnd) == S_OK)
|
|
m_SFToolbar->MenuBarMouseDown(item, isLButton);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_MenuBarMouseUp(HWND hwnd, INT item, BOOL isLButton)
|
|
{
|
|
if (m_staticToolbar && m_staticToolbar->IsWindowOwner(hwnd) == S_OK)
|
|
m_staticToolbar->MenuBarMouseUp(item, isLButton);
|
|
if (m_SFToolbar && m_SFToolbar->IsWindowOwner(hwnd) == S_OK)
|
|
m_SFToolbar->MenuBarMouseUp(item, isLButton);
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CMenuBand::_HasSubMenu()
|
|
{
|
|
return m_popupBar ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT CMenuBand::AdjustForTheme(BOOL bFlatStyle)
|
|
{
|
|
return IUnknown_QueryServiceExec(m_site, SID_SMenuPopup, &CGID_MenuDeskBar, 4, bFlatStyle, NULL, NULL);
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetState(LPSMDATA psmd)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetMenuToolbar(IUnknown *punk, DWORD dwFlags)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetSubMenu(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetToolbar(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetMinWidth(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetNoBorder(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::SetTheme(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetTop(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetBottom(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetTracked(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetParentSite(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetState(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::DoDefaultAction(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::IsEmpty(THIS)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::HasFocusIO()
|
|
{
|
|
if (m_popupBar)
|
|
return S_OK;
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::TranslateAcceleratorIO(LPMSG lpMsg)
|
|
{
|
|
// TODO: Alt down -> toggle menu focus
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::IsDirty()
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::Load(IStream *pStm)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::Save(IStream *pStm, BOOL fClearDirty)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::GetClassID(CLSID *pClassID)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CMenuBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
|
|
{
|
|
UNIMPLEMENTED;
|
|
return S_OK;
|
|
}
|
|
|
|
extern "C"
|
|
HRESULT WINAPI RSHELL_CMenuBand_CreateInstance(REFIID riid, LPVOID *ppv)
|
|
{
|
|
return ShellObjectCreator<CMenuBand>(riid, ppv);
|
|
}
|