mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +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)
|
#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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue