mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33:31 +08:00
[SHLWAPI] SHInvokeCommandOnContextMenu[Ex] and SHInvokeCommandWithFlagsAndSite (#7228)
This commit is contained in:
parent
e83ec236fa
commit
53e930e97f
@ -61,7 +61,11 @@ extern HINSTANCE shlwapi_hInstance;
|
|||||||
extern DWORD SHLWAPI_ThreadRef_index;
|
extern DWORD SHLWAPI_ThreadRef_index;
|
||||||
|
|
||||||
HRESULT WINAPI IUnknown_QueryService(IUnknown*,REFGUID,REFIID,LPVOID*);
|
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);
|
HRESULT WINAPI SHInvokeCommand(HWND,IShellFolder*,LPCITEMIDLIST,DWORD);
|
||||||
|
#endif
|
||||||
BOOL WINAPI SHAboutInfoW(LPWSTR,DWORD);
|
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)
|
HRESULT WINAPI SHInvokeDefaultCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl)
|
||||||
{
|
{
|
||||||
TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl);
|
TRACE("%p %p %p\n", hWnd, lpFolder, lpApidl);
|
||||||
|
#ifdef __REACTOS__
|
||||||
|
return SHInvokeCommand(hWnd, lpFolder, lpApidl, NULL);
|
||||||
|
#else
|
||||||
return SHInvokeCommand(hWnd, lpFolder, lpApidl, 0);
|
return SHInvokeCommand(hWnd, lpFolder, lpApidl, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -3615,6 +3623,13 @@ UINT WINAPI SHDefExtractIconWrapW(LPCWSTR pszIconFile, int iIndex, UINT uFlags,
|
|||||||
* executed.
|
* executed.
|
||||||
* Failure: An HRESULT error code indicating the error.
|
* 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)
|
HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST lpApidl, DWORD dwCommandId)
|
||||||
{
|
{
|
||||||
IContextMenu *iContext;
|
IContextMenu *iContext;
|
||||||
@ -3667,6 +3682,7 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST
|
|||||||
}
|
}
|
||||||
return hRet;
|
return hRet;
|
||||||
}
|
}
|
||||||
|
#endif /* __REACTOS__ */
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* @ [SHLWAPI.370]
|
* @ [SHLWAPI.370]
|
||||||
|
@ -360,7 +360,7 @@
|
|||||||
360 stdcall -noname RemoveDirectoryWrapW(wstr) kernel32.RemoveDirectoryW
|
360 stdcall -noname RemoveDirectoryWrapW(wstr) kernel32.RemoveDirectoryW
|
||||||
361 stdcall -noname GetShortPathNameWrapW(wstr ptr long) kernel32.GetShortPathNameW
|
361 stdcall -noname GetShortPathNameWrapW(wstr ptr long) kernel32.GetShortPathNameW
|
||||||
362 stdcall -noname GetUserNameWrapW(ptr ptr) advapi32.GetUserNameW
|
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)
|
364 stdcall -noname DoesStringRoundTripA(str ptr long)
|
||||||
365 stdcall -noname DoesStringRoundTripW(wstr ptr long)
|
365 stdcall -noname DoesStringRoundTripW(wstr ptr long)
|
||||||
366 stdcall -noname RegEnumValueWrapW(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW
|
366 stdcall -noname RegEnumValueWrapW(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW
|
||||||
@ -537,8 +537,8 @@
|
|||||||
537 stub -noname SHBoolSystemParametersInfo
|
537 stub -noname SHBoolSystemParametersInfo
|
||||||
538 stdcall -noname IUnknown_QueryServiceForWebBrowserApp(ptr ptr ptr)
|
538 stdcall -noname IUnknown_QueryServiceForWebBrowserApp(ptr ptr ptr)
|
||||||
539 stub -noname IUnknown_ShowBrowserBar
|
539 stub -noname IUnknown_ShowBrowserBar
|
||||||
540 stub -noname SHInvokeCommandOnContextMenu
|
540 stdcall -noname SHInvokeCommandOnContextMenu(ptr ptr ptr long str)
|
||||||
541 stub -noname SHInvokeCommandsOnContextMen
|
541 stub -noname SHInvokeCommandsOnContextMenu
|
||||||
542 stdcall -noname GetUIVersion()
|
542 stdcall -noname GetUIVersion()
|
||||||
543 stdcall -noname CreateColorSpaceWrapW(ptr) gdi32.CreateColorSpaceW
|
543 stdcall -noname CreateColorSpaceWrapW(ptr) gdi32.CreateColorSpaceW
|
||||||
544 stub -noname QuerySourceCreateFromKey
|
544 stub -noname QuerySourceCreateFromKey
|
||||||
@ -568,7 +568,8 @@
|
|||||||
568 stdcall AssocQueryStringW(long long wstr wstr ptr ptr)
|
568 stdcall AssocQueryStringW(long long wstr wstr ptr ptr)
|
||||||
569 stdcall ChrCmpIA(long long)
|
569 stdcall ChrCmpIA(long long)
|
||||||
570 stdcall ChrCmpIW(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)
|
572 stdcall ColorHLSToRGB(long long long)
|
||||||
573 stdcall ColorRGBToHLS(long ptr ptr ptr)
|
573 stdcall ColorRGBToHLS(long ptr ptr ptr)
|
||||||
@ stdcall -private DllGetVersion(ptr)
|
@ stdcall -private DllGetVersion(ptr)
|
||||||
@ -636,7 +637,8 @@
|
|||||||
636 stdcall PathIsSameRootA(str str)
|
636 stdcall PathIsSameRootA(str str)
|
||||||
637 stdcall PathIsSameRootW(wstr wstr)
|
637 stdcall PathIsSameRootW(wstr wstr)
|
||||||
638 stdcall PathIsSystemFolderA(str long)
|
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)
|
640 stdcall PathIsUNCA(str)
|
||||||
641 stdcall PathIsUNCServerA(str)
|
641 stdcall PathIsUNCServerA(str)
|
||||||
642 stdcall PathIsUNCServerShareA(str)
|
642 stdcall PathIsUNCServerShareA(str)
|
||||||
|
@ -33,8 +33,164 @@
|
|||||||
|
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#ifndef FAILED_UNEXPECTEDLY
|
||||||
|
#define FAILED_UNEXPECTEDLY FAILED /* FIXME: Make shellutils.h usable without ATL */
|
||||||
|
#endif
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
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]
|
* IContextMenu_Invoke [SHLWAPI.207]
|
||||||
*
|
*
|
||||||
@ -48,52 +204,10 @@ IContextMenu_Invoke(
|
|||||||
_In_ LPCSTR lpVerb,
|
_In_ LPCSTR lpVerb,
|
||||||
_In_ UINT uFlags)
|
_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);
|
TRACE("(%p, %p, %s, %u)\n", pContextMenu, hwnd, debugstr_a(lpVerb), uFlags);
|
||||||
|
HRESULT hr = SHInvokeCommandOnContextMenuInternal(hwnd, NULL, pContextMenu, 0,
|
||||||
if (!pContextMenu)
|
uFlags, lpVerb, NULL, false);
|
||||||
return FALSE;
|
return !FAILED_UNEXPECTEDLY(hr);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -93,6 +93,23 @@ HRESULT WINAPI SHILCreateFromPathW (
|
|||||||
LPITEMIDLIST * ppidl,
|
LPITEMIDLIST * ppidl,
|
||||||
DWORD *attributes);
|
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
|
string functions
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user