mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[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:
parent
fb929febc6
commit
7d0ca528ce
3 changed files with 400 additions and 369 deletions
|
@ -155,20 +155,6 @@ _CStartMenu_Constructor(REFIID riid, void **ppv);
|
|||
|
||||
#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;
|
||||
|
||||
#define INTERFACE ITrayWindow
|
||||
|
@ -343,7 +329,7 @@ OUT HWND *phWndTaskSwitch);
|
|||
* startmnu.cpp
|
||||
*/
|
||||
|
||||
extern const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu;
|
||||
HRESULT StartMenuBtnCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
|
||||
|
||||
#define INTERFACE IStartMenuSite
|
||||
DECLARE_INTERFACE_(IStartMenuSite, IUnknown)
|
||||
|
|
|
@ -24,240 +24,222 @@
|
|||
* Start menu button context menu
|
||||
*/
|
||||
|
||||
// TODO: Convert into an IContextMenu
|
||||
|
||||
typedef struct _STARTMNU_CTMENU_CTX
|
||||
class CStartMenuBtnCtxMenu :
|
||||
public CComCoClass<CStartMenuBtnCtxMenu>,
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IContextMenu
|
||||
{
|
||||
IContextMenu *pcm;
|
||||
HWND hWndOwner;
|
||||
CComPtr<ITrayWindow> TrayWnd;
|
||||
CComPtr<IContextMenu> pcm;
|
||||
CComPtr<IShellFolder> psf;
|
||||
LPITEMIDLIST pidl;
|
||||
} STARTMNU_CTMENU_CTX, *PSTARTMNU_CTMENU_CTX;
|
||||
|
||||
static HMENU
|
||||
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))
|
||||
HRESULT CreateContextMenuFromShellFolderPidl(HMENU hPopup)
|
||||
{
|
||||
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(
|
||||
hPopup,
|
||||
0,
|
||||
ID_SHELL_CMD_FIRST,
|
||||
ID_SHELL_CMD_LAST,
|
||||
CMF_VERBSONLY);
|
||||
|
||||
if (SUCCEEDED(hRet))
|
||||
if (hPopup != NULL)
|
||||
{
|
||||
*ppcm = pcm;
|
||||
return hPopup;
|
||||
}
|
||||
hRet = pcm->QueryContextMenu(
|
||||
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))
|
||||
{
|
||||
hPopup = CreateContextMenuFromShellFolderPidl(hWndOwner,
|
||||
psfStart,
|
||||
pidlLast,
|
||||
&pcm);
|
||||
return hRet;
|
||||
}
|
||||
|
||||
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));
|
||||
if (psmcmc != NULL)
|
||||
{
|
||||
psmcmc->pcm = pcm;
|
||||
psmcmc->pidl = pidlLast;
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddStartContextMenuItems(hWndOwner,
|
||||
hPopup);
|
||||
public:
|
||||
HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner)
|
||||
{
|
||||
this->TrayWnd = pTrayWnd;
|
||||
this->hWndOwner = hWndOwner;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*ppcmContext = psmcmc;
|
||||
return hPopup;
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyMenu(hPopup);
|
||||
hPopup = NULL;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
QueryContextMenu(HMENU hPopup,
|
||||
UINT indexMenu,
|
||||
UINT idCmdFirst,
|
||||
UINT idCmdLast,
|
||||
UINT uFlags)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
extern HRESULT InitShellServices(HDPA * phdpa);
|
||||
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)
|
||||
|
||||
|
@ -70,7 +70,6 @@ class CTrayWindow :
|
|||
HFONT hStartBtnFont;
|
||||
HFONT hCaptionFont;
|
||||
|
||||
CComPtr<ITrayBandSite> TrayBandSite;
|
||||
HWND hwndRebar;
|
||||
HWND hwndTaskSwitch;
|
||||
HWND hwndTrayNotify;
|
||||
|
@ -84,23 +83,6 @@ class CTrayWindow :
|
|||
RECT rcTrayWnd[4];
|
||||
RECT rcNewPosSize;
|
||||
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;
|
||||
HFONT hFont;
|
||||
|
@ -118,6 +100,26 @@ class CTrayWindow :
|
|||
|
||||
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:
|
||||
CTrayWindow() :
|
||||
StartButton(this, 1),
|
||||
|
@ -134,13 +136,13 @@ public:
|
|||
PreviousMonitor(NULL),
|
||||
DraggingPosition(0),
|
||||
DraggingMonitor(NULL),
|
||||
Flags(0),
|
||||
hFont(NULL),
|
||||
hbmStartMenu(NULL),
|
||||
hwndTrayPropertiesOwner(NULL),
|
||||
hwndRunFileDlgOwner(NULL),
|
||||
AutoHideState(NULL),
|
||||
hdpaShellServices(NULL)
|
||||
hdpaShellServices(NULL),
|
||||
Flags(0)
|
||||
{
|
||||
ZeroMemory(&StartBtnSize, sizeof(StartBtnSize));
|
||||
ZeroMemory(&rcTrayWnd, sizeof(rcTrayWnd));
|
||||
|
@ -1017,38 +1019,51 @@ ChangePos:
|
|||
return cmdId;
|
||||
}
|
||||
|
||||
UINT TrackCtxMenu(
|
||||
IN const TRAYWINDOW_CTXMENU *pMenu,
|
||||
HRESULT TrackCtxMenu(
|
||||
IN IContextMenu * contextMenu,
|
||||
IN POINT *ppt OPTIONAL,
|
||||
IN HWND hwndExclude OPTIONAL,
|
||||
IN BOOL TrackUp,
|
||||
IN PVOID Context OPTIONAL)
|
||||
{
|
||||
HMENU hPopup;
|
||||
UINT cmdId = 0;
|
||||
PVOID pcmContext = NULL;
|
||||
INT x = ppt->x;
|
||||
INT y = ppt->y;
|
||||
HRESULT hr;
|
||||
UINT uCommand;
|
||||
HMENU popup = CreatePopupMenu();
|
||||
|
||||
hPopup = pMenu->CreateCtxMenu(m_hWnd,
|
||||
&pcmContext,
|
||||
Context);
|
||||
if (hPopup != NULL)
|
||||
if (popup == NULL)
|
||||
return E_FAIL;
|
||||
|
||||
TRACE("Before Query\n");
|
||||
hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
cmdId = TrackMenu(
|
||||
hPopup,
|
||||
ppt,
|
||||
hwndExclude,
|
||||
TrackUp,
|
||||
TRUE);
|
||||
TRACE("Query failed\n");
|
||||
DestroyMenu(popup);
|
||||
return hr;
|
||||
}
|
||||
|
||||
TRACE("Before Tracking\n");
|
||||
uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL);
|
||||
|
||||
pMenu->CtxMenuCommand(m_hWnd,
|
||||
cmdId,
|
||||
pcmContext,
|
||||
Context);
|
||||
|
||||
DestroyMenu(hPopup);
|
||||
if (uCommand != 0)
|
||||
{
|
||||
TRACE("Before InvokeCommand\n");
|
||||
CMINVOKECOMMANDINFO cmi = { 0 };
|
||||
cmi.cbSize = sizeof(cmi);
|
||||
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 */
|
||||
if (!(StartButton.SendMessage(BM_GETSTATE, 0, 0) & BST_PUSHED))
|
||||
{
|
||||
TrackCtxMenu(
|
||||
&StartMenuBtnCtxMenu,
|
||||
ppt,
|
||||
hWndExclude,
|
||||
Position == ABE_BOTTOM,
|
||||
this);
|
||||
CComPtr<IContextMenu> ctxMenu;
|
||||
StartMenuBtnCtxMenuCreator(this, m_hWnd, &ctxMenu);
|
||||
TrackCtxMenu(ctxMenu, ppt, hWndExclude, Position == ABE_BOTTOM, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2522,12 +2534,9 @@ SetStartBtnImage:
|
|||
{
|
||||
HandleTrayContextMenu:
|
||||
/* Tray the default tray window context menu */
|
||||
TrackCtxMenu(
|
||||
&TrayWindowCtxMenu,
|
||||
ppt,
|
||||
NULL,
|
||||
FALSE,
|
||||
this);
|
||||
CComPtr<IContextMenu> ctxMenu;
|
||||
TrayWindowCtxMenuCreator(this, m_hWnd, &ctxMenu);
|
||||
TrackCtxMenu(ctxMenu, ppt, NULL, FALSE, this);
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
|
@ -2816,89 +2825,6 @@ HandleTrayContextMenu:
|
|||
ALT_MSG_MAP(1)
|
||||
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()
|
||||
|
@ -3017,11 +2943,148 @@ HandleTrayContextMenu:
|
|||
END_COM_MAP()
|
||||
};
|
||||
|
||||
const TRAYWINDOW_CTXMENU TrayWindowCtxMenu = {
|
||||
CTrayWindow::CreateTrayWindowContextMenu,
|
||||
CTrayWindow::OnTrayWindowContextMenuCommand
|
||||
class CTrayWindowCtxMenu :
|
||||
public CComCoClass<CTrayWindowCtxMenu>,
|
||||
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;
|
||||
|
||||
HRESULT
|
||||
|
|
Loading…
Reference in a new issue