mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 21:21:33 +00:00
[SHELL32] Invoke the ItemIDList of shortcuts (#7152)
Invoking the IDList as if the target was double-clicked in Explorer fixes shortcuts to control panel items (both .cpl and ShellFolder types). CORE-19690
This commit is contained in:
parent
a45d375f60
commit
f6a25d48d5
4 changed files with 52 additions and 24 deletions
|
@ -110,6 +110,21 @@ static int FindVerbInDefaultVerbList(LPCWSTR List, LPCWSTR Verb)
|
|||
return -1;
|
||||
}
|
||||
|
||||
EXTERN_C HRESULT SHELL32_EnumDefaultVerbList(LPCWSTR List, UINT Index, LPWSTR Verb, SIZE_T cchMax)
|
||||
{
|
||||
for (UINT i = 0; *List; ++i)
|
||||
{
|
||||
while (IsVerbListSeparator(*List))
|
||||
List++;
|
||||
LPCWSTR Start = List;
|
||||
while (*List && !IsVerbListSeparator(*List))
|
||||
List++;
|
||||
if (List > Start && i == Index)
|
||||
return StringCchCopyNW(Verb, cchMax, Start, List - Start);
|
||||
}
|
||||
return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
|
||||
}
|
||||
|
||||
class CDefaultContextMenu :
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IContextMenu3,
|
||||
|
|
|
@ -2569,7 +2569,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
|
|||
// as the parent window handle... ?
|
||||
/* FIXME: get using interface set from IObjectWithSite?? */
|
||||
// NOTE: We might need an extended version of Resolve that provides us with paths...
|
||||
HRESULT hr = Resolve(lpici->hwnd, 0);
|
||||
HRESULT hr = Resolve(lpici->hwnd, (lpici->fMask & CMIC_MASK_FLAG_NO_UI) ? SLR_NO_UI : 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
TRACE("failed to resolve component error 0x%08x\n", hr);
|
||||
|
@ -2624,7 +2624,7 @@ HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici)
|
|||
if (m_pPidl)
|
||||
{
|
||||
sei.lpIDList = m_pPidl;
|
||||
sei.fMask |= SEE_MASK_IDLIST;
|
||||
sei.fMask |= SEE_MASK_INVOKEIDLIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2633,12 +2633,9 @@ HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici)
|
|||
sei.lpParameters = args;
|
||||
sei.lpClass = m_sLinkPath;
|
||||
sei.nShow = m_Header.nShowCommand;
|
||||
if (lpici->nShow != SW_SHOWNORMAL && lpici->nShow != SW_SHOW)
|
||||
sei.nShow = lpici->nShow; // Allow invoker to override .lnk show mode
|
||||
sei.lpDirectory = m_sWorkDir;
|
||||
sei.lpVerb = L"open";
|
||||
|
||||
// HACK for ShellExecuteExW: Change the default verb if this is a Control Panel applet
|
||||
if (m_sPath && lstrcmpiW(PathFindExtensionW(m_sPath), L".cpl") == 0)
|
||||
sei.lpVerb = L"cplopen";
|
||||
|
||||
return (ShellExecuteExW(&sei) ? S_OK : E_FAIL);
|
||||
}
|
||||
|
|
|
@ -1557,16 +1557,25 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||
__SHCloneStrWtoA(&verb, sei->lpVerb);
|
||||
__SHCloneStrWtoA(¶meters, sei->lpParameters);
|
||||
|
||||
CMINVOKECOMMANDINFOEX ici = {};
|
||||
ici.cbSize = sizeof ici;
|
||||
ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
|
||||
BOOL fDefault = !sei->lpVerb || !sei->lpVerb[0];
|
||||
CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
|
||||
ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)) | CMIC_MASK_UNICODE;
|
||||
ici.nShow = sei->nShow;
|
||||
ici.lpVerb = verb;
|
||||
if (!fDefault)
|
||||
{
|
||||
ici.lpVerb = verb;
|
||||
ici.lpVerbW = sei->lpVerb;
|
||||
}
|
||||
ici.hwnd = sei->hwnd;
|
||||
ici.lpParameters = parameters;
|
||||
ici.lpParametersW = sei->lpParameters;
|
||||
if ((sei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_CLASSNAME)) == SEE_MASK_HASLINKNAME)
|
||||
{
|
||||
ici.fMask |= CMIC_MASK_HASLINKNAME;
|
||||
ici.lpTitleW = sei->lpClass;
|
||||
}
|
||||
|
||||
HMENU hMenu = CreatePopupMenu();
|
||||
BOOL fDefault = !ici.lpVerb || !ici.lpVerb[0];
|
||||
hr = cm->QueryContextMenu(hMenu, 0, 1, 0x7fff, fDefault ? CMF_DEFAULTONLY : 0);
|
||||
if (!FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
|
@ -1575,6 +1584,7 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||
INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
|
||||
uDefault = (uDefault != -1) ? uDefault - 1 : 0;
|
||||
ici.lpVerb = MAKEINTRESOURCEA(uDefault);
|
||||
ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
|
||||
}
|
||||
|
||||
hr = cm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
|
||||
|
|
|
@ -130,9 +130,11 @@ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bP
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
EXTERN_C HRESULT SHELL32_EnumDefaultVerbList(LPCWSTR List, UINT Index, LPWSTR Verb, SIZE_T cchMax);
|
||||
|
||||
BOOL HCR_GetDefaultVerbW( HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD len )
|
||||
{
|
||||
WCHAR sTemp[MAX_PATH];
|
||||
WCHAR sTemp[MAX_PATH], verbs[MAX_PATH];
|
||||
LONG size;
|
||||
HKEY hkey;
|
||||
|
||||
|
@ -144,21 +146,25 @@ BOOL HCR_GetDefaultVerbW( HKEY hkeyClass, LPCWSTR szVerb, LPWSTR szDest, DWORD l
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
size=len;
|
||||
*szDest='\0';
|
||||
if (!RegQueryValueW(hkeyClass, L"shell\\", szDest, &size) && *szDest)
|
||||
/* MSDN says to first try the default verb */
|
||||
size = _countof(verbs);
|
||||
if (!RegQueryValueW(hkeyClass, L"shell", verbs, &size) && *verbs)
|
||||
{
|
||||
/* The MSDN says to first try the default verb */
|
||||
lstrcpyW(sTemp, L"shell\\");
|
||||
lstrcatW(sTemp, szDest);
|
||||
lstrcatW(sTemp, L"\\command");
|
||||
if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey))
|
||||
for (UINT i = 0;; ++i)
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
TRACE("default verb=%s\n", debugstr_w(szDest));
|
||||
return TRUE;
|
||||
if (FAILED(SHELL32_EnumDefaultVerbList(verbs, i, szDest, len)))
|
||||
break;
|
||||
if (FAILED(StringCchPrintfW(sTemp, _countof(sTemp), L"shell\\%s\\command", szDest)))
|
||||
break;
|
||||
if (!RegOpenKeyExW(hkeyClass, sTemp, 0, KEY_READ, &hkey))
|
||||
{
|
||||
RegCloseKey(hkey);
|
||||
TRACE("default verb=%s\n", debugstr_w(szDest));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*szDest = UNICODE_NULL;
|
||||
|
||||
/* then fallback to 'open' */
|
||||
lstrcpyW(sTemp, L"shell\\open\\command");
|
||||
|
|
Loading…
Reference in a new issue