[SHELL32]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Tue, 24 Jan 2017 16:35:36 +0000 (16:35 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Tue, 24 Jan 2017 16:35:36 +0000 (16:35 +0000)
- CDefaultContextMenu: Fix the implementation of the QueryContextMenu to respect how IContextMenu should function. Don't ignore idCmdFirst and idCmdLast parameters. Return a correct HRESULT. For now I'm not sure how 0 cmd ids should be handled and if the standard menu items should also be affected by these parameters.

svn path=/trunk/; revision=73591

reactos/dll/win32/shell32/CDefaultContextMenu.cpp
reactos/dll/win32/shell32/folders/CDrivesFolder.cpp

index 6518372..851beb9 100644 (file)
@@ -76,6 +76,8 @@ class CDefaultContextMenu :
         PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
         UINT m_iIdSCMFirst; /* first static used id */
         UINT m_iIdSCMLast; /* last static used id */
+        UINT m_iIdCBFirst; /* first callback used id */
+        UINT m_iIdCBLast;  /* last callback used id */
 
         HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
         void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
@@ -84,8 +86,7 @@ class CDefaultContextMenu :
         HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
         BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
         UINT InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast);
-        UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu);
-        UINT BuildShellItemContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
+        UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
         HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
         HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
         HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
@@ -146,7 +147,9 @@ CDefaultContextMenu::CDefaultContextMenu() :
     m_iIdSHELast(0),
     m_pStaticEntries(NULL),
     m_iIdSCMFirst(0),
-    m_iIdSCMLast(0)
+    m_iIdSCMLast(0),
+    m_iIdCBFirst(0),
+    m_iIdCBLast(0)
 {
 }
 
@@ -470,8 +473,6 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
     }
 
     PDynamicShellEntry pEntry = m_pDynamicEntries;
-    idCmdFirst = 0x5000;
-    idCmdLast =  0x6000;
     m_iIdSHEFirst = idCmdFirst;
     do
     {
@@ -482,6 +483,13 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
             pEntry->NumIds = LOWORD(hr);
             IndexMenu += pEntry->NumIds;
             idCmdFirst += pEntry->NumIds + 0x10;
+
+            if(idCmdFirst >= idCmdLast)
+            {
+                /* There is no more room for items */
+                idCmdFirst = idCmdLast;
+                break;
+            }
         }
         TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
         pEntry = pEntry->pNext;
@@ -495,7 +503,9 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
 UINT
 CDefaultContextMenu::AddStaticContextMenusToMenu(
     HMENU hMenu,
-    UINT IndexMenu)
+    UINT IndexMenu,
+    UINT iIdCmdFirst, 
+    UINT iIdCmdLast)
 {
     MENUITEMINFOW mii;
     UINT idResource;
@@ -505,7 +515,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
     mii.cbSize = sizeof(mii);
     mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
     mii.fType = MFT_STRING;
-    mii.wID = 0x4000;
+    mii.wID = iIdCmdFirst;
     mii.dwTypeData = NULL;
     m_iIdSCMFirst = mii.wID;
 
@@ -590,6 +600,9 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
 
         mii.wID++;
         pEntry = pEntry->pNext;
+
+        if (mii.wID >= iIdCmdLast)
+            break;
     }
 
     m_iIdSCMLast = mii.wID - 1;
@@ -645,6 +658,11 @@ CDefaultContextMenu::QueryContextMenu(
     UINT uFlags)
 {
     HRESULT hr;
+    UINT idCmdNext = idCmdFirst;
+
+    /* Add a tiny hack to make all the shell happy until we understand how we should handle 0 ids */
+    if (!idCmdNext)
+        idCmdNext = 1;
 
     TRACE("BuildShellItemContextMenu entered\n");
 
@@ -656,35 +674,40 @@ CDefaultContextMenu::QueryContextMenu(
     }
 
     /* Add static context menu handlers */
-    IndexMenu = AddStaticContextMenusToMenu(hMenu, IndexMenu);
+    IndexMenu = AddStaticContextMenusToMenu(hMenu, IndexMenu, idCmdNext, idCmdLast);
+    if (m_iIdSCMLast && m_iIdSCMFirst != m_iIdSCMLast) 
+        idCmdNext = m_iIdSCMLast + 1;
 
     /* Add dynamic context menu handlers */
     BOOL bAddSep = FALSE;
-    IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, idCmdFirst, idCmdLast);
-    TRACE("IndexMenu %d\n", IndexMenu);
+    IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, idCmdNext, idCmdLast);
+    if (m_iIdSHELast && m_iIdSHELast != m_iIdSHEFirst)
+        idCmdNext = m_iIdSHELast + 1;
 
     /* Now let the callback add its own items */
-    QCMINFO qcminfo;
-    qcminfo.hmenu = hMenu;
-    qcminfo.indexMenu = IndexMenu;
-    qcminfo.idCmdFirst = idCmdFirst;
-    qcminfo.idCmdLast = idCmdLast;
-    qcminfo.pIdMap = NULL;
-    _DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo);
+    QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
+    if (SUCCEEDED(_DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo)))
+    {
+        m_iIdCBFirst = idCmdNext;
+        m_iIdCBLast = qcminfo.idCmdFirst;
+        idCmdNext = m_iIdCBLast + 1;
+    }
+
+    /* The rest of the items will be added in the end of the menu */
     IndexMenu = GetMenuItemCount(hMenu);
 
     if (uFlags & CMF_VERBSONLY)
-        return S_OK;
+        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdNext - idCmdFirst);
 
     /* If this is a background context menu we are done */
     if (!m_cidl)
-        return S_OK;
+        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdNext - idCmdFirst);
 
     /* Get the attributes of the items */
     SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
     hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
     if (FAILED_UNEXPECTEDLY(hr))
-        return S_OK;
+        return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdNext - idCmdFirst);
 
     /* Add the standard menu entries based on the attributes of the items */
     BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM));
@@ -1206,9 +1229,6 @@ CDefaultContextMenu::InvokeCommand(
         Result = DoCreateNewFolder(&LocalInvokeInfo);
         break;
     default:
-
-        _DoCallback(DFM_INVOKECOMMAND, LOWORD(LocalInvokeInfo.lpVerb), NULL);
-
         Result = E_UNEXPECTED;
         break;
     }
@@ -1216,21 +1236,27 @@ CDefaultContextMenu::InvokeCommand(
     /* Check for ID's we didn't find a handler for */
     if (Result == E_UNEXPECTED)
     {
-        if (m_iIdSHEFirst && m_iIdSHELast)
+        if (m_pDynamicEntries)
         {
             if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSHEFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSHELast)
                 Result = DoDynamicShellExtensions(&LocalInvokeInfo);
         }
 
-        if (m_iIdSCMFirst && m_iIdSCMLast)
+        if (m_pStaticEntries)
         {
             if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSCMFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSCMLast)
                 Result = DoStaticShellExtensions(&LocalInvokeInfo);
         }
+
+        if (m_iIdCBFirst != m_iIdCBLast)
+        {
+            if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdCBFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdCBLast)
+                Result = _DoCallback(DFM_INVOKECOMMAND, LOWORD(LocalInvokeInfo.lpVerb), NULL);
+        }
     }
 
     if (Result == E_UNEXPECTED)
-        FIXME("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
+        ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
 
     return Result;
 }
index 9262f5f..cfbaa90 100644 (file)
@@ -76,17 +76,13 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
             if (!(dwFlags & FILE_READ_ONLY_VOLUME) && GetDriveTypeA(szDrive) != DRIVE_REMOTE)
             {
                 _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
-                _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED);
+                _InsertMenuItemW(pqcminfo->hmenu, pqcminfo->indexMenu++, TRUE, pqcminfo->idCmdFirst++, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED);
             }
         }
     }
     else if (uMsg == DFM_INVOKECOMMAND)
     {
-        if(wParam == 0x7ABC)
-        {
-            SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
-        }
-        else if (wParam == DFM_CMD_PROPERTIES)
+        if (wParam == DFM_CMD_PROPERTIES)
         {
             WCHAR wszBuf[4];
             wcscpy(wszBuf, L"A:\\");
@@ -94,6 +90,10 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
             if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl))
                 hr = E_FAIL;
         }
+        else
+        {
+            SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
+        }
     }
 
     SHFree(pidlFolder);