[EXPLORER-NEW]

* Use IContextMenu for the context menus, instead of a struct with function pointers.

svn path=/branches/shell-experiments/; revision=65279
This commit is contained in:
David Quintana 2014-11-06 03:05:33 +00:00
parent fb929febc6
commit 7d0ca528ce
3 changed files with 400 additions and 369 deletions

View file

@ -155,20 +155,6 @@ _CStartMenu_Constructor(REFIID riid, void **ppv);
#define TWM_OPENSTARTMENU (WM_USER + 260) #define TWM_OPENSTARTMENU (WM_USER + 260)
typedef HMENU(*PCREATECTXMENU)(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL);
typedef VOID(*PCTXMENUCOMMAND)(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL);
typedef struct _TRAYWINDOW_CTXMENU
{
PCREATECTXMENU CreateCtxMenu;
PCTXMENUCOMMAND CtxMenuCommand;
} TRAYWINDOW_CTXMENU, *PTRAYWINDOW_CTXMENU;
extern const GUID IID_IShellDesktopTray; extern const GUID IID_IShellDesktopTray;
#define INTERFACE ITrayWindow #define INTERFACE ITrayWindow
@ -343,7 +329,7 @@ OUT HWND *phWndTaskSwitch);
* startmnu.cpp * startmnu.cpp
*/ */
extern const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu; HRESULT StartMenuBtnCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
#define INTERFACE IStartMenuSite #define INTERFACE IStartMenuSite
DECLARE_INTERFACE_(IStartMenuSite, IUnknown) DECLARE_INTERFACE_(IStartMenuSite, IUnknown)

View file

@ -24,240 +24,222 @@
* Start menu button context menu * Start menu button context menu
*/ */
// TODO: Convert into an IContextMenu class CStartMenuBtnCtxMenu :
public CComCoClass<CStartMenuBtnCtxMenu>,
typedef struct _STARTMNU_CTMENU_CTX public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IContextMenu
{ {
IContextMenu *pcm; HWND hWndOwner;
CComPtr<ITrayWindow> TrayWnd;
CComPtr<IContextMenu> pcm;
CComPtr<IShellFolder> psf;
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
} STARTMNU_CTMENU_CTX, *PSTARTMNU_CTMENU_CTX;
static HMENU HRESULT CreateContextMenuFromShellFolderPidl(HMENU hPopup)
CreateStartContextMenu(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL);
static VOID
OnStartContextMenuCommand(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL);
const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu = {
CreateStartContextMenu,
OnStartContextMenuCommand
};
static HMENU
CreateContextMenuFromShellFolderPidl(IN HWND hWndOwner,
IN OUT IShellFolder *psf,
IN OUT LPITEMIDLIST pidl,
OUT IContextMenu **ppcm)
{
CComPtr<IContextMenu> pcm;
HRESULT hRet;
HMENU hPopup;
hRet = psf->GetUIObjectOf(hWndOwner, 1, (LPCITEMIDLIST *) &pidl, IID_NULL_PPV_ARG(IContextMenu, &pcm));
if (SUCCEEDED(hRet))
{ {
hPopup = CreatePopupMenu(); CComPtr<IContextMenu> pcm;
HRESULT hRet;
if (hPopup != NULL) hRet = psf->GetUIObjectOf(hWndOwner, 1, (LPCITEMIDLIST *) &pidl, IID_NULL_PPV_ARG(IContextMenu, &pcm));
if (SUCCEEDED(hRet))
{ {
hRet = pcm->QueryContextMenu( if (hPopup != NULL)
hPopup,
0,
ID_SHELL_CMD_FIRST,
ID_SHELL_CMD_LAST,
CMF_VERBSONLY);
if (SUCCEEDED(hRet))
{ {
*ppcm = pcm; hRet = pcm->QueryContextMenu(
return hPopup; hPopup,
} 0,
ID_SHELL_CMD_FIRST,
ID_SHELL_CMD_LAST,
CMF_VERBSONLY);
DestroyMenu(hPopup);
}
}
return NULL;
}
static VOID
OnStartContextMenuCommand(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL)
{
PSTARTMNU_CTMENU_CTX psmcmc = (PSTARTMNU_CTMENU_CTX) pcmContext;
if (uiCmdId != 0)
{
if ((uiCmdId >= ID_SHELL_CMD_FIRST) && (uiCmdId <= ID_SHELL_CMD_LAST))
{
CMINVOKECOMMANDINFO cmici = { 0 };
CHAR szDir[MAX_PATH];
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
cmici.lpVerb = (LPCSTR) MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
/* FIXME: Support Unicode!!! */
if (SHGetPathFromIDListA(psmcmc->pidl,
szDir))
{
cmici.lpDirectory = szDir;
}
psmcmc->pcm->InvokeCommand(&cmici);
}
else
{
ITrayWindow * TrayWnd = (ITrayWindow *) Context;
TrayWnd->ExecContextMenuCmd(uiCmdId);
}
}
psmcmc->pcm->Release();
HeapFree(hProcessHeap, 0, psmcmc);
}
static VOID
AddStartContextMenuItems(IN HWND hWndOwner, IN HMENU hPopup)
{
WCHAR szBuf[MAX_PATH];
HRESULT hRet;
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_PROPERTIES,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_PROPERTIES,
szBuf);
}
if (!SHRestricted(REST_NOCOMMONGROUPS))
{
/* Check if we should add menu items for the common start menu */
hRet = SHGetFolderPath(hWndOwner,
CSIDL_COMMON_STARTMENU,
NULL,
SHGFP_TYPE_CURRENT,
szBuf);
if (SUCCEEDED(hRet) && hRet != S_FALSE)
{
/* The directory exists, but only show the items if the
user can actually make any changes to the common start
menu. This is most likely only the case if the user
has administrative rights! */
if (IsUserAnAdmin())
{
AppendMenu(hPopup,
MF_SEPARATOR,
0,
NULL);
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_OPEN_ALL_USERS,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_OPEN_ALL_USERS,
szBuf);
}
/* Add the "Explore All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_EXPLORE_ALL_USERS,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_EXPLORE_ALL_USERS,
szBuf);
}
}
}
}
}
static HMENU
CreateStartContextMenu(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL)
{
LPITEMIDLIST pidlStart, pidlLast;
CComPtr<IShellFolder> psfStart;
CComPtr<IShellFolder> psfDesktop;
CComPtr<IContextMenu> pcm;
HRESULT hRet;
HMENU hPopup;
pidlStart = SHCloneSpecialIDList(hWndOwner,
CSIDL_STARTMENU,
TRUE);
if (pidlStart != NULL)
{
pidlLast = ILClone(ILFindLastID(pidlStart));
ILRemoveLastID(pidlStart);
if (pidlLast != NULL)
{
hRet = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hRet))
{
hRet = psfDesktop->BindToObject(pidlStart, NULL, IID_PPV_ARG(IShellFolder, &psfStart));
if (SUCCEEDED(hRet)) if (SUCCEEDED(hRet))
{ {
hPopup = CreateContextMenuFromShellFolderPidl(hWndOwner, return hRet;
psfStart, }
pidlLast,
&pcm);
if (hPopup != NULL) DestroyMenu(hPopup);
}
}
return E_FAIL;
}
VOID AddStartContextMenuItems(IN HMENU hPopup)
{
WCHAR szBuf[MAX_PATH];
HRESULT hRet;
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_PROPERTIES,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_PROPERTIES,
szBuf);
}
if (!SHRestricted(REST_NOCOMMONGROUPS))
{
/* Check if we should add menu items for the common start menu */
hRet = SHGetFolderPath(hWndOwner,
CSIDL_COMMON_STARTMENU,
NULL,
SHGFP_TYPE_CURRENT,
szBuf);
if (SUCCEEDED(hRet) && hRet != S_FALSE)
{
/* The directory exists, but only show the items if the
user can actually make any changes to the common start
menu. This is most likely only the case if the user
has administrative rights! */
if (IsUserAnAdmin())
{
AppendMenu(hPopup,
MF_SEPARATOR,
0,
NULL);
/* Add the "Open All Users" menu item */
if (LoadString(hExplorerInstance,
IDS_OPEN_ALL_USERS,
szBuf,
sizeof(szBuf) / sizeof(szBuf[0])))
{ {
PSTARTMNU_CTMENU_CTX psmcmc; AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_OPEN_ALL_USERS,
szBuf);
}
psmcmc = (PSTARTMNU_CTMENU_CTX) HeapAlloc(hProcessHeap, 0, sizeof(*psmcmc)); /* Add the "Explore All Users" menu item */
if (psmcmc != NULL) if (LoadString(hExplorerInstance,
{ IDS_EXPLORE_ALL_USERS,
psmcmc->pcm = pcm; szBuf,
psmcmc->pidl = pidlLast; sizeof(szBuf) / sizeof(szBuf[0])))
{
AppendMenu(hPopup,
MF_STRING,
ID_SHELL_CMD_EXPLORE_ALL_USERS,
szBuf);
}
}
}
}
}
AddStartContextMenuItems(hWndOwner, public:
hPopup); HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
{
this->TrayWnd = pTrayWnd;
this->hWndOwner = hWndOwner;
return S_OK;
}
*ppcmContext = psmcmc; virtual HRESULT STDMETHODCALLTYPE
return hPopup; QueryContextMenu(HMENU hPopup,
} UINT indexMenu,
else UINT idCmdFirst,
{ UINT idCmdLast,
DestroyMenu(hPopup); UINT uFlags)
hPopup = NULL; {
} LPITEMIDLIST pidlStart;
CComPtr<IShellFolder> psfDesktop;
HRESULT hRet;
psfDesktop = NULL;
pcm = NULL;
pidlStart = SHCloneSpecialIDList(hWndOwner, CSIDL_STARTMENU, TRUE);
if (pidlStart != NULL)
{
pidl = ILClone(ILFindLastID(pidlStart));
ILRemoveLastID(pidlStart);
if (pidl != NULL)
{
hRet = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hRet))
{
hRet = psfDesktop->BindToObject(pidlStart, NULL, IID_PPV_ARG(IShellFolder, &psf));
if (SUCCEEDED(hRet))
{
CreateContextMenuFromShellFolderPidl(hPopup);
AddStartContextMenuItems(hPopup);
} }
} }
} }
ILFree(pidlLast); ILFree(pidlStart);
} }
ILFree(pidlStart); return NULL;
} }
return NULL; virtual HRESULT STDMETHODCALLTYPE
InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
UINT uiCmdId = (UINT)lpici->lpVerb;
if (uiCmdId != 0)
{
if ((uiCmdId >= ID_SHELL_CMD_FIRST) && (uiCmdId <= ID_SHELL_CMD_LAST))
{
CMINVOKECOMMANDINFO cmici = { 0 };
CHAR szDir[MAX_PATH];
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
cmici.lpVerb = MAKEINTRESOURCEA(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
/* FIXME: Support Unicode!!! */
if (SHGetPathFromIDListA(pidl, szDir))
{
cmici.lpDirectory = szDir;
}
pcm->InvokeCommand(&cmici);
}
else
{
TrayWnd->ExecContextMenuCmd(uiCmdId);
}
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE
GetCommandString(UINT_PTR idCmd,
UINT uType,
UINT *pwReserved,
LPSTR pszName,
UINT cchMax)
{
return E_NOTIMPL;
}
CStartMenuBtnCtxMenu()
{
}
virtual ~CStartMenuBtnCtxMenu()
{
if (pidl)
ILFree(pidl);
}
BEGIN_COM_MAP(CStartMenuBtnCtxMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
END_COM_MAP()
};
HRESULT StartMenuBtnCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu)
{
CStartMenuBtnCtxMenu * mnu = new CComObject<CStartMenuBtnCtxMenu>();
mnu->Initialize(TrayWnd, hWndOwner);
*ppCtxMenu = mnu;
return S_OK;
} }

View file

@ -24,7 +24,7 @@
extern HRESULT InitShellServices(HDPA * phdpa); extern HRESULT InitShellServices(HDPA * phdpa);
extern HRESULT ShutdownShellServices(HDPA hdpa); extern HRESULT ShutdownShellServices(HDPA hdpa);
extern const TRAYWINDOW_CTXMENU TrayWindowCtxMenu; HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
#define WM_APP_TRAYDESTROY (WM_APP + 0x100) #define WM_APP_TRAYDESTROY (WM_APP + 0x100)
@ -70,7 +70,6 @@ class CTrayWindow :
HFONT hStartBtnFont; HFONT hStartBtnFont;
HFONT hCaptionFont; HFONT hCaptionFont;
CComPtr<ITrayBandSite> TrayBandSite;
HWND hwndRebar; HWND hwndRebar;
HWND hwndTaskSwitch; HWND hwndTaskSwitch;
HWND hwndTrayNotify; HWND hwndTrayNotify;
@ -84,23 +83,6 @@ class CTrayWindow :
RECT rcTrayWnd[4]; RECT rcTrayWnd[4];
RECT rcNewPosSize; RECT rcNewPosSize;
SIZE TraySize; SIZE TraySize;
union
{
DWORD Flags;
struct
{
DWORD AutoHide : 1;
DWORD AlwaysOnTop : 1;
DWORD SmSmallIcons : 1;
DWORD HideClock : 1;
DWORD Locked : 1;
/* UI Status */
DWORD InSizeMove : 1;
DWORD IsDragging : 1;
DWORD NewPosSize : 1;
};
};
NONCLIENTMETRICS ncm; NONCLIENTMETRICS ncm;
HFONT hFont; HFONT hFont;
@ -118,6 +100,26 @@ class CTrayWindow :
HDPA hdpaShellServices; HDPA hdpaShellServices;
public:
CComPtr<ITrayBandSite> TrayBandSite;
union
{
DWORD Flags;
struct
{
DWORD AutoHide : 1;
DWORD AlwaysOnTop : 1;
DWORD SmSmallIcons : 1;
DWORD HideClock : 1;
DWORD Locked : 1;
/* UI Status */
DWORD InSizeMove : 1;
DWORD IsDragging : 1;
DWORD NewPosSize : 1;
};
};
public: public:
CTrayWindow() : CTrayWindow() :
StartButton(this, 1), StartButton(this, 1),
@ -134,13 +136,13 @@ public:
PreviousMonitor(NULL), PreviousMonitor(NULL),
DraggingPosition(0), DraggingPosition(0),
DraggingMonitor(NULL), DraggingMonitor(NULL),
Flags(0),
hFont(NULL), hFont(NULL),
hbmStartMenu(NULL), hbmStartMenu(NULL),
hwndTrayPropertiesOwner(NULL), hwndTrayPropertiesOwner(NULL),
hwndRunFileDlgOwner(NULL), hwndRunFileDlgOwner(NULL),
AutoHideState(NULL), AutoHideState(NULL),
hdpaShellServices(NULL) hdpaShellServices(NULL),
Flags(0)
{ {
ZeroMemory(&StartBtnSize, sizeof(StartBtnSize)); ZeroMemory(&StartBtnSize, sizeof(StartBtnSize));
ZeroMemory(&rcTrayWnd, sizeof(rcTrayWnd)); ZeroMemory(&rcTrayWnd, sizeof(rcTrayWnd));
@ -1017,38 +1019,51 @@ ChangePos:
return cmdId; return cmdId;
} }
UINT TrackCtxMenu( HRESULT TrackCtxMenu(
IN const TRAYWINDOW_CTXMENU *pMenu, IN IContextMenu * contextMenu,
IN POINT *ppt OPTIONAL, IN POINT *ppt OPTIONAL,
IN HWND hwndExclude OPTIONAL, IN HWND hwndExclude OPTIONAL,
IN BOOL TrackUp, IN BOOL TrackUp,
IN PVOID Context OPTIONAL) IN PVOID Context OPTIONAL)
{ {
HMENU hPopup; INT x = ppt->x;
UINT cmdId = 0; INT y = ppt->y;
PVOID pcmContext = NULL; HRESULT hr;
UINT uCommand;
HMENU popup = CreatePopupMenu();
hPopup = pMenu->CreateCtxMenu(m_hWnd, if (popup == NULL)
&pcmContext, return E_FAIL;
Context);
if (hPopup != NULL) TRACE("Before Query\n");
hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
if (FAILED_UNEXPECTEDLY(hr))
{ {
cmdId = TrackMenu( TRACE("Query failed\n");
hPopup, DestroyMenu(popup);
ppt, return hr;
hwndExclude, }
TrackUp,
TRUE); TRACE("Before Tracking\n");
uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL);
pMenu->CtxMenuCommand(m_hWnd, if (uCommand != 0)
cmdId, {
pcmContext, TRACE("Before InvokeCommand\n");
Context); CMINVOKECOMMANDINFO cmi = { 0 };
cmi.cbSize = sizeof(cmi);
DestroyMenu(hPopup); cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
cmi.hwnd = m_hWnd;
hr = contextMenu->InvokeCommand(&cmi);
}
else
{
TRACE("TrackPopupMenu failed. Code=%d, LastError=%d\n", uCommand, GetLastError());
hr = S_FALSE;
} }
return cmdId; DestroyMenu(popup);
return hr;
} }
@ -2480,12 +2495,9 @@ SetStartBtnImage:
menu is currently being shown */ menu is currently being shown */
if (!(StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED)) if (!(StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
{ {
TrackCtxMenu( CComPtr<IContextMenu> ctxMenu;
&StartMenuBtnCtxMenu, StartMenuBtnCtxMenuCreator(this, m_hWnd, &ctxMenu);
ppt, TrackCtxMenu(ctxMenu, ppt, hWndExclude, Position == ABE_BOTTOM, this);
hWndExclude,
Position == ABE_BOTTOM,
this);
} }
} }
else else
@ -2522,12 +2534,9 @@ SetStartBtnImage:
{ {
HandleTrayContextMenu: HandleTrayContextMenu:
/* Tray the default tray window context menu */ /* Tray the default tray window context menu */
TrackCtxMenu( CComPtr<IContextMenu> ctxMenu;
&TrayWindowCtxMenu, TrayWindowCtxMenuCreator(this, m_hWnd, &ctxMenu);
ppt, TrackCtxMenu(ctxMenu, ppt, NULL, FALSE, this);
NULL,
FALSE,
this);
} }
} }
return Ret; return Ret;
@ -2816,89 +2825,6 @@ HandleTrayContextMenu:
ALT_MSG_MAP(1) ALT_MSG_MAP(1)
END_MSG_MAP() END_MSG_MAP()
/*
* Tray Window Context Menu
*/
static HMENU CreateTrayWindowContextMenu(IN HWND hWndOwner,
IN PVOID *ppcmContext,
IN PVOID Context OPTIONAL)
{
CTrayWindow *This = (CTrayWindow *) Context;
IContextMenu *pcm = NULL;
HMENU hPopup;
hPopup = LoadPopupMenu(hExplorerInstance,
MAKEINTRESOURCE(IDM_TRAYWND));
if (hPopup != NULL)
{
if (SHRestricted(REST_CLASSICSHELL) != 0)
{
DeleteMenu(hPopup,
ID_LOCKTASKBAR,
MF_BYCOMMAND);
}
CheckMenuItem(hPopup,
ID_LOCKTASKBAR,
MF_BYCOMMAND | (This->Locked ? MF_CHECKED : MF_UNCHECKED));
if (This->TrayBandSite != NULL)
{
if (SUCCEEDED(This->TrayBandSite->AddContextMenus(
hPopup,
0,
ID_SHELL_CMD_FIRST,
ID_SHELL_CMD_LAST,
CMF_NORMAL,
&pcm)))
{
TRACE("ITrayBandSite::AddContextMenus succeeded!\n");
*(IContextMenu **) ppcmContext = pcm;
}
}
}
return hPopup;
}
static VOID OnTrayWindowContextMenuCommand(IN HWND hWndOwner,
IN UINT uiCmdId,
IN PVOID pcmContext OPTIONAL,
IN PVOID Context OPTIONAL)
{
CTrayWindow *This = (CTrayWindow *) Context;
IContextMenu *pcm = (IContextMenu *) pcmContext;
if (uiCmdId != 0)
{
if (uiCmdId >= ID_SHELL_CMD_FIRST && uiCmdId <= ID_SHELL_CMD_LAST)
{
CMINVOKECOMMANDINFO cmici = { 0 };
if (pcm != NULL)
{
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
cmici.lpVerb = (LPCSTR) MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
pcm->InvokeCommand(
&cmici);
}
}
else
{
This->ExecContextMenuCmd(uiCmdId);
}
}
if (pcm != NULL)
pcm->Release();
}
/*****************************************************************************/ /*****************************************************************************/
VOID TrayProcessMessages() VOID TrayProcessMessages()
@ -3017,11 +2943,148 @@ HandleTrayContextMenu:
END_COM_MAP() END_COM_MAP()
}; };
const TRAYWINDOW_CTXMENU TrayWindowCtxMenu = { class CTrayWindowCtxMenu :
CTrayWindow::CreateTrayWindowContextMenu, public CComCoClass<CTrayWindowCtxMenu>,
CTrayWindow::OnTrayWindowContextMenuCommand public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IContextMenu
{
HWND hWndOwner;
CComPtr<CTrayWindow> TrayWnd;
CComPtr<IContextMenu> pcm;
public:
HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
{
this->TrayWnd = (CTrayWindow *) pTrayWnd;
this->hWndOwner = hWndOwner;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE
QueryContextMenu(HMENU hPopup,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
HMENU menubase = LoadPopupMenu(hExplorerInstance, MAKEINTRESOURCE(IDM_TRAYWND));
if (menubase)
{
int count = ::GetMenuItemCount(menubase);
for (int i = 0; i < count; i++)
{
WCHAR label[128];
MENUITEMINFOW mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS
| MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
mii.dwTypeData = label;
mii.cch = _countof(label);
::GetMenuItemInfoW(menubase, i, TRUE, &mii);
TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
mii.fType |= MFT_RADIOCHECK;
::InsertMenuItemW(hPopup, i + 1, TRUE, &mii);
}
::DestroyMenu(menubase);
if (SHRestricted(REST_CLASSICSHELL) != 0)
{
DeleteMenu(hPopup,
ID_LOCKTASKBAR,
MF_BYCOMMAND);
}
CheckMenuItem(hPopup,
ID_LOCKTASKBAR,
MF_BYCOMMAND | (TrayWnd->Locked ? MF_CHECKED : MF_UNCHECKED));
if (TrayWnd->TrayBandSite != NULL)
{
if (SUCCEEDED(TrayWnd->TrayBandSite->AddContextMenus(
hPopup,
0,
ID_SHELL_CMD_FIRST,
ID_SHELL_CMD_LAST,
CMF_NORMAL,
&pcm)))
{
return S_OK;
}
}
}
return E_FAIL;
}
virtual HRESULT STDMETHODCALLTYPE
InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
UINT uiCmdId = (UINT) lpici->lpVerb;
if (uiCmdId != 0)
{
if (uiCmdId >= ID_SHELL_CMD_FIRST && uiCmdId <= ID_SHELL_CMD_LAST)
{
CMINVOKECOMMANDINFO cmici = { 0 };
if (pcm != NULL)
{
/* Setup and invoke the shell command */
cmici.cbSize = sizeof(cmici);
cmici.hwnd = hWndOwner;
cmici.lpVerb = (LPCSTR) MAKEINTRESOURCE(uiCmdId - ID_SHELL_CMD_FIRST);
cmici.nShow = SW_NORMAL;
pcm->InvokeCommand(&cmici);
}
}
else
{
TrayWnd->ExecContextMenuCmd(uiCmdId);
}
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE
GetCommandString(UINT_PTR idCmd,
UINT uType,
UINT *pwReserved,
LPSTR pszName,
UINT cchMax)
{
return E_NOTIMPL;
}
CTrayWindowCtxMenu()
{
}
virtual ~CTrayWindowCtxMenu()
{
}
BEGIN_COM_MAP(CTrayWindowCtxMenu)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
END_COM_MAP()
}; };
HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu)
{
CTrayWindowCtxMenu * mnu = new CComObject<CTrayWindowCtxMenu>();
mnu->Initialize(TrayWnd, hWndOwner);
*ppCtxMenu = mnu;
return S_OK;
}
CTrayWindow * g_TrayWindow; CTrayWindow * g_TrayWindow;
HRESULT HRESULT