Author: dquintana Date: Thu Nov 6 03:05:33 2014 New Revision: 65279
URL: http://svn.reactos.org/svn/reactos?rev=65279&view=rev Log: [EXPLORER-NEW] * Use IContextMenu for the context menus, instead of a struct with function pointers.
Modified: branches/shell-experiments/base/shell/explorer-new/precomp.h branches/shell-experiments/base/shell/explorer-new/startctxmnu.cpp branches/shell-experiments/base/shell/explorer-new/traywnd.cpp
Modified: branches/shell-experiments/base/shell/explorer-new/precomp.h URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/exp... ============================================================================== --- branches/shell-experiments/base/shell/explorer-new/precomp.h [iso-8859-1] (original) +++ branches/shell-experiments/base/shell/explorer-new/precomp.h [iso-8859-1] Thu Nov 6 03:05:33 2014 @@ -155,20 +155,6 @@
#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 @@ * startmnu.cpp */
-extern const TRAYWINDOW_CTXMENU StartMenuBtnCtxMenu; +HRESULT StartMenuBtnCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu);
#define INTERFACE IStartMenuSite DECLARE_INTERFACE_(IStartMenuSite, IUnknown)
Modified: branches/shell-experiments/base/shell/explorer-new/startctxmnu.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/exp... ============================================================================== --- branches/shell-experiments/base/shell/explorer-new/startctxmnu.cpp [iso-8859-1] (original) +++ branches/shell-experiments/base/shell/explorer-new/startctxmnu.cpp [iso-8859-1] Thu Nov 6 03:05:33 2014 @@ -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 + + HRESULT CreateContextMenuFromShellFolderPidl(HMENU hPopup) + { + CComPtr<IContextMenu> pcm; + HRESULT hRet; + + hRet = psf->GetUIObjectOf(hWndOwner, 1, (LPCITEMIDLIST *) &pidl, IID_NULL_PPV_ARG(IContextMenu, &pcm)); + if (SUCCEEDED(hRet)) + { + if (hPopup != NULL) + { + hRet = pcm->QueryContextMenu( + hPopup, + 0, + ID_SHELL_CMD_FIRST, + ID_SHELL_CMD_LAST, + CMF_VERBSONLY); + + if (SUCCEEDED(hRet)) + { + return hRet; + } + + 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]))) + { + 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); + } + } + } + } + } + +public: + HRESULT Initialize(ITrayWindow * pTrayWnd, IN HWND hWndOwner) + { + this->TrayWnd = pTrayWnd; + this->hWndOwner = hWndOwner; + return S_OK; + } + + 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(pidlStart); + } + + 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() }; - -static HMENU -CreateContextMenuFromShellFolderPidl(IN HWND hWndOwner, - IN OUT IShellFolder *psf, - IN OUT LPITEMIDLIST pidl, - OUT IContextMenu **ppcm) +HRESULT StartMenuBtnCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu) { - 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(); - - if (hPopup != NULL) - { - hRet = pcm->QueryContextMenu( - hPopup, - 0, - ID_SHELL_CMD_FIRST, - ID_SHELL_CMD_LAST, - CMF_VERBSONLY); - - if (SUCCEEDED(hRet)) - { - *ppcm = pcm; - return hPopup; - } - - DestroyMenu(hPopup); - } - } - - return NULL; + CStartMenuBtnCtxMenu * mnu = new CComObject<CStartMenuBtnCtxMenu>(); + mnu->Initialize(TrayWnd, hWndOwner); + *ppCtxMenu = mnu; + return S_OK; } - -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); - - if (hPopup != NULL) - { - PSTARTMNU_CTMENU_CTX psmcmc; - - psmcmc = (PSTARTMNU_CTMENU_CTX) HeapAlloc(hProcessHeap, 0, sizeof(*psmcmc)); - if (psmcmc != NULL) - { - psmcmc->pcm = pcm; - psmcmc->pidl = pidlLast; - - AddStartContextMenuItems(hWndOwner, - hPopup); - - *ppcmContext = psmcmc; - return hPopup; - } - else - { - DestroyMenu(hPopup); - hPopup = NULL; - } - } - } - } - - ILFree(pidlLast); - } - - ILFree(pidlStart); - } - - return NULL; -}
Modified: branches/shell-experiments/base/shell/explorer-new/traywnd.cpp URL: http://svn.reactos.org/svn/reactos/branches/shell-experiments/base/shell/exp... ============================================================================== --- branches/shell-experiments/base/shell/explorer-new/traywnd.cpp [iso-8859-1] (original) +++ branches/shell-experiments/base/shell/explorer-new/traywnd.cpp [iso-8859-1] Thu Nov 6 03:05:33 2014 @@ -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 @@ HFONT hStartBtnFont; HFONT hCaptionFont;
- CComPtr<ITrayBandSite> TrayBandSite; HWND hwndRebar; HWND hwndTaskSwitch; HWND hwndTrayNotify; @@ -84,6 +83,25 @@ RECT rcTrayWnd[4]; RECT rcNewPosSize; SIZE TraySize; + + NONCLIENTMETRICS ncm; + HFONT hFont; + + CComPtr<IMenuBand> StartMenuBand; + CComPtr<IMenuPopup> StartMenuPopup; + HBITMAP hbmStartMenu; + + HWND hwndTrayPropertiesOwner; + HWND hwndRunFileDlgOwner; + + UINT AutoHideState; + SIZE AutoHideOffset; + TRACKMOUSEEVENT MouseTrackingInfo; + + HDPA hdpaShellServices; + +public: + CComPtr<ITrayBandSite> TrayBandSite; union { DWORD Flags; @@ -101,22 +119,6 @@ DWORD NewPosSize : 1; }; }; - - NONCLIENTMETRICS ncm; - HFONT hFont; - - CComPtr<IMenuBand> StartMenuBand; - CComPtr<IMenuPopup> StartMenuPopup; - HBITMAP hbmStartMenu; - - HWND hwndTrayPropertiesOwner; - HWND hwndRunFileDlgOwner; - - UINT AutoHideState; - SIZE AutoHideOffset; - TRACKMOUSEEVENT MouseTrackingInfo; - - HDPA hdpaShellServices;
public: CTrayWindow() : @@ -134,13 +136,13 @@ 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 @@ 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; - - hPopup = pMenu->CreateCtxMenu(m_hWnd, - &pcmContext, - Context); - if (hPopup != NULL) - { - cmdId = TrackMenu( - hPopup, - ppt, - hwndExclude, - TrackUp, - TRUE); - - pMenu->CtxMenuCommand(m_hWnd, - cmdId, - pcmContext, - Context); - - DestroyMenu(hPopup); - } - - return cmdId; + INT x = ppt->x; + INT y = ppt->y; + HRESULT hr; + UINT uCommand; + HMENU popup = CreatePopupMenu(); + + if (popup == NULL) + return E_FAIL; + + TRACE("Before Query\n"); + hr = contextMenu->QueryContextMenu(popup, 0, 0, UINT_MAX, CMF_NORMAL); + if (FAILED_UNEXPECTEDLY(hr)) + { + TRACE("Query failed\n"); + DestroyMenu(popup); + return hr; + } + + TRACE("Before Tracking\n"); + uCommand = ::TrackPopupMenuEx(popup, TPM_RETURNCMD, x, y, m_hWnd, NULL); + + 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; + } + + DestroyMenu(popup); + return hr; }
@@ -2480,12 +2495,9 @@ 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 @@ { 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 @@ 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,10 +2943,147 @@ 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;