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/explorer-new/precomp.h?rev=65279&r1=65278&r2=65279&view=diff
==============================================================================
--- 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/explorer-new/startctxmnu.cpp?rev=65279&r1=65278&r2=65279&view=diff
==============================================================================
--- 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/explorer-new/traywnd.cpp?rev=65279&r1=65278&r2=65279&view=diff
==============================================================================
--- 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;
 


Reply via email to