From 7d0ca528cef5e468c26d43007be1ee0fb9f4c792 Mon Sep 17 00:00:00 2001 From: David Quintana Date: Thu, 6 Nov 2014 03:05:33 +0000 Subject: [PATCH] [EXPLORER-NEW] * Use IContextMenu for the context menus, instead of a struct with function pointers. svn path=/branches/shell-experiments/; revision=65279 --- base/shell/explorer-new/precomp.h | 16 +- base/shell/explorer-new/startctxmnu.cpp | 408 +++++++++++------------- base/shell/explorer-new/traywnd.cpp | 345 ++++++++++++-------- 3 files changed, 400 insertions(+), 369 deletions(-) diff --git a/base/shell/explorer-new/precomp.h b/base/shell/explorer-new/precomp.h index 1c63685fe85..8ade10ec104 100644 --- a/base/shell/explorer-new/precomp.h +++ b/base/shell/explorer-new/precomp.h @@ -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) diff --git a/base/shell/explorer-new/startctxmnu.cpp b/base/shell/explorer-new/startctxmnu.cpp index 831a597a349..4e625f1d190 100644 --- a/base/shell/explorer-new/startctxmnu.cpp +++ b/base/shell/explorer-new/startctxmnu.cpp @@ -24,240 +24,222 @@ * Start menu button context menu */ -// TODO: Convert into an IContextMenu - -typedef struct _STARTMNU_CTMENU_CTX +class CStartMenuBtnCtxMenu : + public CComCoClass, + public CComObjectRootEx, + public IContextMenu { - IContextMenu *pcm; + HWND hWndOwner; + CComPtr TrayWnd; + CComPtr pcm; + CComPtr 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 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 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 psfStart; - CComPtr psfDesktop; - CComPtr 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 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(); + mnu->Initialize(TrayWnd, hWndOwner); + *ppCtxMenu = mnu; + return S_OK; } diff --git a/base/shell/explorer-new/traywnd.cpp b/base/shell/explorer-new/traywnd.cpp index 147abb8874e..1c143fb0ac6 100644 --- a/base/shell/explorer-new/traywnd.cpp +++ b/base/shell/explorer-new/traywnd.cpp @@ -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 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 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 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 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, + public CComObjectRootEx, + public IContextMenu +{ + HWND hWndOwner; + CComPtr TrayWnd; + CComPtr 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(); + mnu->Initialize(TrayWnd, hWndOwner); + *ppCtxMenu = mnu; + return S_OK; +} + CTrayWindow * g_TrayWindow; HRESULT