mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[SHLWAPI] SHInvokeCommandOnContextMenu[Ex] and SHInvokeCommandWithFlagsAndSite (#7228)
This commit is contained in:
parent
e83ec236fa
commit
53e930e97f
4 changed files with 199 additions and 50 deletions
|
@ -61,7 +61,11 @@ extern HINSTANCE shlwapi_hInstance;
|
|||
extern DWORD SHLWAPI_ThreadRef_index;
|
||||
|
||||
HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
|
||||
#ifdef __REACTOS__
|
||||
HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, LPCSTR lpVerb);
|
||||
#else
|
||||
HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD);
|
||||
#endif
|
||||
BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
|
||||
|
||||
/*
|
||||
|
@ -3056,7 +3060,11 @@ HWND WINAPI SHCreateWorkerWindowW(WNDPROC wndProc, HWND hWndParent, DWORD dwExSt
|
|||
HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
|
||||
{
|
||||
TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl);
|
||||
#ifdef __REACTOS__
|
||||
return SHInvokeCommand(hWnd, lpFolder, lpApidl, NULL);
|
||||
#else
|
||||
return SHInvokeCommand(hWnd, lpFolder, lpApidl, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -3615,6 +3623,13 @@ UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
|
|||
* executed.
|
||||
* Failure: An HRESULT error code indicating the error.
|
||||
*/
|
||||
#ifdef __REACTOS__
|
||||
EXTERN_C HRESULT WINAPI SHInvokeCommandWithFlagsAndSite(HWND, IUnknown*, IShellFolder*, LPCITEMIDLIST, UINT, LPCSTR);
|
||||
HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, LPCSTR lpVerb)
|
||||
{
|
||||
return SHInvokeCommandWithFlagsAndSite(hWnd, NULL, lpFolder, lpApidl, 0, lpVerb);
|
||||
}
|
||||
#else
|
||||
HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, DWORD dwCommandId)
|
||||
{
|
||||
IContextMenu *iContext;
|
||||
|
@ -3667,6 +3682,7 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST
|
|||
}
|
||||
return hRet;
|
||||
}
|
||||
#endif /* __REACTOS__ */
|
||||
|
||||
/*************************************************************************
|
||||
* @ [SHLWAPI.370]
|
||||
|
|
|
@ -360,7 +360,7 @@
|
|||
360 stdcall -noname RemoveDirectoryWrapW(wstr) kernel32.RemoveDirectoryW
|
||||
361 stdcall -noname GetShortPathNameWrapW(wstr ptr long) kernel32.GetShortPathNameW
|
||||
362 stdcall -noname GetUserNameWrapW(ptr ptr) advapi32.GetUserNameW
|
||||
363 stdcall -noname SHInvokeCommand(ptr ptr ptr long)
|
||||
363 stdcall -noname SHInvokeCommand(ptr ptr ptr str)
|
||||
364 stdcall -noname DoesStringRoundTripA(str ptr long)
|
||||
365 stdcall -noname DoesStringRoundTripW(wstr ptr long)
|
||||
366 stdcall -noname RegEnumValueWrapW(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW
|
||||
|
@ -537,8 +537,8 @@
|
|||
537 stub -noname SHBoolSystemParametersInfo
|
||||
538 stdcall -noname IUnknown_QueryServiceForWebBrowserApp(ptr ptr ptr)
|
||||
539 stub -noname IUnknown_ShowBrowserBar
|
||||
540 stub -noname SHInvokeCommandOnContextMenu
|
||||
541 stub -noname SHInvokeCommandsOnContextMen
|
||||
540 stdcall -noname SHInvokeCommandOnContextMenu(ptr ptr ptr long str)
|
||||
541 stub -noname SHInvokeCommandsOnContextMenu
|
||||
542 stdcall -noname GetUIVersion()
|
||||
543 stdcall -noname CreateColorSpaceWrapW(ptr) gdi32.CreateColorSpaceW
|
||||
544 stub -noname QuerySourceCreateFromKey
|
||||
|
@ -568,7 +568,8 @@
|
|||
568 stdcall AssocQueryStringW(long long wstr wstr ptr ptr)
|
||||
569 stdcall ChrCmpIA(long long)
|
||||
570 stdcall ChrCmpIW(long long)
|
||||
571 stdcall ColorAdjustLuma(long long long)
|
||||
571 stdcall -noname -version=0x600+ SHInvokeCommandWithFlagsAndSite(ptr ptr ptr ptr long str)
|
||||
@ stdcall ColorAdjustLuma(long long long)
|
||||
572 stdcall ColorHLSToRGB(long long long)
|
||||
573 stdcall ColorRGBToHLS(long ptr ptr ptr)
|
||||
@ stdcall -private DllGetVersion(ptr)
|
||||
|
@ -636,7 +637,8 @@
|
|||
636 stdcall PathIsSameRootA(str str)
|
||||
637 stdcall PathIsSameRootW(wstr wstr)
|
||||
638 stdcall PathIsSystemFolderA(str long)
|
||||
639 stdcall PathIsSystemFolderW(wstr long)
|
||||
639 stdcall -noname -version=0x600+ SHInvokeCommandOnContextMenuEx(ptr ptr ptr long long str wstr)
|
||||
@ stdcall PathIsSystemFolderW(wstr long)
|
||||
640 stdcall PathIsUNCA(str)
|
||||
641 stdcall PathIsUNCServerA(str)
|
||||
642 stdcall PathIsUNCServerShareA(str)
|
||||
|
|
|
@ -33,8 +33,164 @@
|
|||
|
||||
#include <strsafe.h>
|
||||
|
||||
#ifndef FAILED_UNEXPECTEDLY
|
||||
#define FAILED_UNEXPECTEDLY FAILED /* FIXME: Make shellutils.h usable without ATL */
|
||||
#endif
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
static inline WORD
|
||||
GetVersionMajorMinor()
|
||||
{
|
||||
DWORD version = GetVersion();
|
||||
return MAKEWORD(HIBYTE(version), LOBYTE(version));
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
SHInvokeCommandOnContextMenuInternal(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ IUnknown* pUnk,
|
||||
_In_ IContextMenu* pCM,
|
||||
_In_ UINT fCMIC,
|
||||
_In_ UINT fCMF,
|
||||
_In_opt_ LPCSTR pszVerb,
|
||||
_In_opt_ LPCWSTR pwszDir,
|
||||
_In_ bool ForceQCM)
|
||||
{
|
||||
CMINVOKECOMMANDINFOEX info = { sizeof(info), fCMIC, hWnd, pszVerb };
|
||||
INT iDefItem = 0;
|
||||
HMENU hMenu = NULL;
|
||||
HCURSOR hOldCursor;
|
||||
HRESULT hr = S_OK;
|
||||
WCHAR wideverb[MAX_PATH];
|
||||
|
||||
if (!pCM)
|
||||
return E_INVALIDARG;
|
||||
|
||||
hOldCursor = SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_WAIT));
|
||||
info.nShow = SW_NORMAL;
|
||||
if (pUnk)
|
||||
IUnknown_SetSite(pCM, pUnk);
|
||||
|
||||
if (IS_INTRESOURCE(pszVerb))
|
||||
{
|
||||
hMenu = CreatePopupMenu();
|
||||
if (hMenu)
|
||||
{
|
||||
hr = pCM->QueryContextMenu(hMenu, 0, 1, MAXSHORT, fCMF | CMF_DEFAULTONLY);
|
||||
iDefItem = GetMenuDefaultItem(hMenu, 0, 0);
|
||||
if (iDefItem != -1)
|
||||
info.lpVerb = MAKEINTRESOURCEA(iDefItem - 1);
|
||||
}
|
||||
info.lpVerbW = MAKEINTRESOURCEW(info.lpVerb);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetVersionMajorMinor() >= _WIN32_WINNT_WIN7)
|
||||
{
|
||||
info.fMask |= CMF_OPTIMIZEFORINVOKE;
|
||||
}
|
||||
if (pszVerb && SHAnsiToUnicode(pszVerb, wideverb, _countof(wideverb)))
|
||||
{
|
||||
info.fMask |= CMIC_MASK_UNICODE;
|
||||
info.lpVerbW = wideverb;
|
||||
}
|
||||
if (ForceQCM)
|
||||
{
|
||||
hMenu = CreatePopupMenu();
|
||||
hr = pCM->QueryContextMenu(hMenu, 0, 1, MAXSHORT, fCMF);
|
||||
}
|
||||
}
|
||||
|
||||
SetCursor(hOldCursor);
|
||||
|
||||
if (!FAILED_UNEXPECTEDLY(hr) && (iDefItem != -1 || info.lpVerb))
|
||||
{
|
||||
if (!hWnd)
|
||||
info.fMask |= CMIC_MASK_FLAG_NO_UI;
|
||||
|
||||
CHAR dir[MAX_PATH];
|
||||
if (pwszDir)
|
||||
{
|
||||
info.fMask |= CMIC_MASK_UNICODE;
|
||||
info.lpDirectoryW = pwszDir;
|
||||
if (SHUnicodeToAnsi(pwszDir, dir, _countof(dir)))
|
||||
info.lpDirectory = dir;
|
||||
}
|
||||
|
||||
hr = pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
|
||||
if (FAILED_UNEXPECTEDLY(hr)) { /* Diagnostic message */ }
|
||||
}
|
||||
|
||||
if (pUnk)
|
||||
IUnknown_SetSite(pCM, NULL);
|
||||
if (hMenu)
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHInvokeCommandOnContextMenuEx [SHLWAPI.639]
|
||||
*/
|
||||
EXTERN_C
|
||||
HRESULT WINAPI
|
||||
SHInvokeCommandOnContextMenuEx(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ IUnknown* pUnk,
|
||||
_In_ IContextMenu* pCM,
|
||||
_In_ UINT fCMIC,
|
||||
_In_ UINT fCMF,
|
||||
_In_opt_ LPCSTR pszVerb,
|
||||
_In_opt_ LPCWSTR pwszDir)
|
||||
{
|
||||
return SHInvokeCommandOnContextMenuInternal(hWnd, pUnk, pCM, fCMIC, fCMF, pszVerb, pwszDir, true);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHInvokeCommandOnContextMenu [SHLWAPI.540]
|
||||
*/
|
||||
EXTERN_C
|
||||
HRESULT WINAPI
|
||||
SHInvokeCommandOnContextMenu(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ IUnknown* pUnk,
|
||||
_In_ IContextMenu* pCM,
|
||||
_In_ UINT fCMIC,
|
||||
_In_opt_ LPCSTR pszVerb)
|
||||
{
|
||||
return SHInvokeCommandOnContextMenuEx(hWnd, pUnk, pCM, fCMIC, CMF_EXTENDEDVERBS, pszVerb, NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHInvokeCommandWithFlagsAndSite [SHLWAPI.571]
|
||||
*/
|
||||
EXTERN_C
|
||||
HRESULT WINAPI
|
||||
SHInvokeCommandWithFlagsAndSite(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ IUnknown* pUnk,
|
||||
_In_ IShellFolder* pShellFolder,
|
||||
_In_ LPCITEMIDLIST pidl,
|
||||
_In_ UINT fCMIC,
|
||||
_In_opt_ LPCSTR pszVerb)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (pShellFolder)
|
||||
{
|
||||
IContextMenu *pCM;
|
||||
hr = pShellFolder->GetUIObjectOf(hWnd, 1, &pidl, IID_IContextMenu, NULL, (void**)&pCM);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
fCMIC |= CMIC_MASK_FLAG_LOG_USAGE;
|
||||
hr = SHInvokeCommandOnContextMenuEx(hWnd, pUnk, pCM, fCMIC, 0, pszVerb, NULL);
|
||||
pCM->Release();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* IContextMenu_Invoke [SHLWAPI.207]
|
||||
*
|
||||
|
@ -48,52 +204,10 @@ IContextMenu_Invoke(
|
|||
_In_ LPCSTR lpVerb,
|
||||
_In_ UINT uFlags)
|
||||
{
|
||||
CMINVOKECOMMANDINFO info;
|
||||
BOOL ret = FALSE;
|
||||
INT iDefItem = 0;
|
||||
HMENU hMenu = NULL;
|
||||
HCURSOR hOldCursor;
|
||||
|
||||
TRACE("(%p, %p, %s, %u)\n", pContextMenu, hwnd, debugstr_a(lpVerb), uFlags);
|
||||
|
||||
if (!pContextMenu)
|
||||
return FALSE;
|
||||
|
||||
hOldCursor = SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_WAIT));
|
||||
|
||||
ZeroMemory(&info, sizeof(info));
|
||||
info.cbSize = sizeof(info);
|
||||
info.hwnd = hwnd;
|
||||
info.nShow = SW_NORMAL;
|
||||
info.lpVerb = lpVerb;
|
||||
|
||||
if (IS_INTRESOURCE(lpVerb))
|
||||
{
|
||||
hMenu = CreatePopupMenu();
|
||||
if (hMenu)
|
||||
{
|
||||
pContextMenu->QueryContextMenu(hMenu, 0, 1, MAXSHORT, uFlags | CMF_DEFAULTONLY);
|
||||
iDefItem = GetMenuDefaultItem(hMenu, 0, 0);
|
||||
if (iDefItem != -1)
|
||||
info.lpVerb = MAKEINTRESOURCEA(iDefItem - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (iDefItem != -1 || info.lpVerb)
|
||||
{
|
||||
if (!hwnd)
|
||||
info.fMask |= CMIC_MASK_FLAG_NO_UI;
|
||||
ret = SUCCEEDED(pContextMenu->InvokeCommand(&info));
|
||||
}
|
||||
|
||||
/* Invoking itself doesn't need the menu object, but getting the command info
|
||||
needs the menu. */
|
||||
if (hMenu)
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
SetCursor(hOldCursor);
|
||||
|
||||
return ret;
|
||||
HRESULT hr = SHInvokeCommandOnContextMenuInternal(hwnd, NULL, pContextMenu, 0,
|
||||
uFlags, lpVerb, NULL, false);
|
||||
return !FAILED_UNEXPECTEDLY(hr);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -93,6 +93,23 @@ HRESULT WINAPI SHILCreateFromPathW (
|
|||
LPITEMIDLIST * ppidl,
|
||||
DWORD *attributes);
|
||||
|
||||
HRESULT WINAPI SHInvokeCommand(
|
||||
HWND hWnd,
|
||||
IShellFolder* lpFolder,
|
||||
LPCITEMIDLIST lpApidl,
|
||||
LPCSTR lpVerb);
|
||||
HRESULT WINAPI SHInvokeCommandOnContextMenu(
|
||||
_In_opt_ HWND hWnd,
|
||||
_In_opt_ IUnknown* pUnk,
|
||||
_In_ IContextMenu* pCM,
|
||||
_In_ UINT fCMIC,
|
||||
_In_opt_ LPCSTR pszVerb);
|
||||
BOOL WINAPI IContextMenu_Invoke(
|
||||
_In_ IContextMenu *pContextMenu,
|
||||
_In_ HWND hwnd,
|
||||
_In_ LPCSTR lpVerb,
|
||||
_In_ UINT uFlags);
|
||||
|
||||
/*
|
||||
string functions
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue