mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[SHELL32]
- 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
This commit is contained in:
parent
b40958162a
commit
2e07736507
2 changed files with 58 additions and 32 deletions
|
@ -76,6 +76,8 @@ class CDefaultContextMenu :
|
||||||
PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
|
PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
|
||||||
UINT m_iIdSCMFirst; /* first static used id */
|
UINT m_iIdSCMFirst; /* first static used id */
|
||||||
UINT m_iIdSCMLast; /* last 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);
|
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
|
||||||
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
|
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
|
||||||
|
@ -84,8 +86,7 @@ class CDefaultContextMenu :
|
||||||
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
|
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
|
||||||
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
|
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
|
||||||
UINT InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast);
|
UINT InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, UINT IndexMenu, UINT idCmdFirst, UINT idCmdLast);
|
||||||
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu);
|
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
|
||||||
UINT BuildShellItemContextMenu(HMENU hMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
|
|
||||||
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
|
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
|
||||||
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
|
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
|
||||||
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
|
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
|
||||||
|
@ -146,7 +147,9 @@ CDefaultContextMenu::CDefaultContextMenu() :
|
||||||
m_iIdSHELast(0),
|
m_iIdSHELast(0),
|
||||||
m_pStaticEntries(NULL),
|
m_pStaticEntries(NULL),
|
||||||
m_iIdSCMFirst(0),
|
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;
|
PDynamicShellEntry pEntry = m_pDynamicEntries;
|
||||||
idCmdFirst = 0x5000;
|
|
||||||
idCmdLast = 0x6000;
|
|
||||||
m_iIdSHEFirst = idCmdFirst;
|
m_iIdSHEFirst = idCmdFirst;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -482,6 +483,13 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
|
||||||
pEntry->NumIds = LOWORD(hr);
|
pEntry->NumIds = LOWORD(hr);
|
||||||
IndexMenu += pEntry->NumIds;
|
IndexMenu += pEntry->NumIds;
|
||||||
idCmdFirst += pEntry->NumIds + 0x10;
|
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);
|
TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
|
||||||
pEntry = pEntry->pNext;
|
pEntry = pEntry->pNext;
|
||||||
|
@ -495,7 +503,9 @@ CDefaultContextMenu::InsertMenuItemsOfDynamicContextMenuExtension(HMENU hMenu, U
|
||||||
UINT
|
UINT
|
||||||
CDefaultContextMenu::AddStaticContextMenusToMenu(
|
CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
HMENU hMenu,
|
HMENU hMenu,
|
||||||
UINT IndexMenu)
|
UINT IndexMenu,
|
||||||
|
UINT iIdCmdFirst,
|
||||||
|
UINT iIdCmdLast)
|
||||||
{
|
{
|
||||||
MENUITEMINFOW mii;
|
MENUITEMINFOW mii;
|
||||||
UINT idResource;
|
UINT idResource;
|
||||||
|
@ -505,7 +515,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
mii.cbSize = sizeof(mii);
|
mii.cbSize = sizeof(mii);
|
||||||
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
|
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
|
||||||
mii.fType = MFT_STRING;
|
mii.fType = MFT_STRING;
|
||||||
mii.wID = 0x4000;
|
mii.wID = iIdCmdFirst;
|
||||||
mii.dwTypeData = NULL;
|
mii.dwTypeData = NULL;
|
||||||
m_iIdSCMFirst = mii.wID;
|
m_iIdSCMFirst = mii.wID;
|
||||||
|
|
||||||
|
@ -590,6 +600,9 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
|
|
||||||
mii.wID++;
|
mii.wID++;
|
||||||
pEntry = pEntry->pNext;
|
pEntry = pEntry->pNext;
|
||||||
|
|
||||||
|
if (mii.wID >= iIdCmdLast)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_iIdSCMLast = mii.wID - 1;
|
m_iIdSCMLast = mii.wID - 1;
|
||||||
|
@ -645,6 +658,11 @@ CDefaultContextMenu::QueryContextMenu(
|
||||||
UINT uFlags)
|
UINT uFlags)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
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");
|
TRACE("BuildShellItemContextMenu entered\n");
|
||||||
|
|
||||||
|
@ -656,35 +674,40 @@ CDefaultContextMenu::QueryContextMenu(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add static context menu handlers */
|
/* 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 */
|
/* Add dynamic context menu handlers */
|
||||||
BOOL bAddSep = FALSE;
|
BOOL bAddSep = FALSE;
|
||||||
IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, idCmdFirst, idCmdLast);
|
IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, idCmdNext, idCmdLast);
|
||||||
TRACE("IndexMenu %d\n", IndexMenu);
|
if (m_iIdSHELast && m_iIdSHELast != m_iIdSHEFirst)
|
||||||
|
idCmdNext = m_iIdSHELast + 1;
|
||||||
|
|
||||||
/* Now let the callback add its own items */
|
/* Now let the callback add its own items */
|
||||||
QCMINFO qcminfo;
|
QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
|
||||||
qcminfo.hmenu = hMenu;
|
if (SUCCEEDED(_DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo)))
|
||||||
qcminfo.indexMenu = IndexMenu;
|
{
|
||||||
qcminfo.idCmdFirst = idCmdFirst;
|
m_iIdCBFirst = idCmdNext;
|
||||||
qcminfo.idCmdLast = idCmdLast;
|
m_iIdCBLast = qcminfo.idCmdFirst;
|
||||||
qcminfo.pIdMap = NULL;
|
idCmdNext = m_iIdCBLast + 1;
|
||||||
_DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo);
|
}
|
||||||
|
|
||||||
|
/* The rest of the items will be added in the end of the menu */
|
||||||
IndexMenu = GetMenuItemCount(hMenu);
|
IndexMenu = GetMenuItemCount(hMenu);
|
||||||
|
|
||||||
if (uFlags & CMF_VERBSONLY)
|
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 this is a background context menu we are done */
|
||||||
if (!m_cidl)
|
if (!m_cidl)
|
||||||
return S_OK;
|
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdNext - idCmdFirst);
|
||||||
|
|
||||||
/* Get the attributes of the items */
|
/* 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;
|
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);
|
hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
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 */
|
/* Add the standard menu entries based on the attributes of the items */
|
||||||
BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM));
|
BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM));
|
||||||
|
@ -1206,9 +1229,6 @@ CDefaultContextMenu::InvokeCommand(
|
||||||
Result = DoCreateNewFolder(&LocalInvokeInfo);
|
Result = DoCreateNewFolder(&LocalInvokeInfo);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
_DoCallback(DFM_INVOKECOMMAND, LOWORD(LocalInvokeInfo.lpVerb), NULL);
|
|
||||||
|
|
||||||
Result = E_UNEXPECTED;
|
Result = E_UNEXPECTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1216,21 +1236,27 @@ CDefaultContextMenu::InvokeCommand(
|
||||||
/* Check for ID's we didn't find a handler for */
|
/* Check for ID's we didn't find a handler for */
|
||||||
if (Result == E_UNEXPECTED)
|
if (Result == E_UNEXPECTED)
|
||||||
{
|
{
|
||||||
if (m_iIdSHEFirst && m_iIdSHELast)
|
if (m_pDynamicEntries)
|
||||||
{
|
{
|
||||||
if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSHEFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSHELast)
|
if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSHEFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSHELast)
|
||||||
Result = DoDynamicShellExtensions(&LocalInvokeInfo);
|
Result = DoDynamicShellExtensions(&LocalInvokeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_iIdSCMFirst && m_iIdSCMLast)
|
if (m_pStaticEntries)
|
||||||
{
|
{
|
||||||
if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSCMFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSCMLast)
|
if (LOWORD(LocalInvokeInfo.lpVerb) >= m_iIdSCMFirst && LOWORD(LocalInvokeInfo.lpVerb) <= m_iIdSCMLast)
|
||||||
Result = DoStaticShellExtensions(&LocalInvokeInfo);
|
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)
|
if (Result == E_UNEXPECTED)
|
||||||
FIXME("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
|
ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,17 +76,13 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
|
||||||
if (!(dwFlags & FILE_READ_ONLY_VOLUME) && GetDriveTypeA(szDrive) != DRIVE_REMOTE)
|
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, 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)
|
else if (uMsg == DFM_INVOKECOMMAND)
|
||||||
{
|
{
|
||||||
if(wParam == 0x7ABC)
|
if (wParam == DFM_CMD_PROPERTIES)
|
||||||
{
|
|
||||||
SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
|
|
||||||
}
|
|
||||||
else if (wParam == DFM_CMD_PROPERTIES)
|
|
||||||
{
|
{
|
||||||
WCHAR wszBuf[4];
|
WCHAR wszBuf[4];
|
||||||
wcscpy(wszBuf, L"A:\\");
|
wcscpy(wszBuf, L"A:\\");
|
||||||
|
@ -94,6 +90,10 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
|
||||||
if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl))
|
if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl))
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHFree(pidlFolder);
|
SHFree(pidlFolder);
|
||||||
|
|
Loading…
Reference in a new issue