[SHELL32] Use common default DFM callback message handler (#6779)

Moves default processing of all DFM_ callback messages in SHELL32 to a single function.

CORE-18585
This commit is contained in:
Whindmar Saksit 2024-05-09 19:52:05 +02:00 committed by GitHub
parent 9e8214fa13
commit daf806802a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 58 additions and 87 deletions

View file

@ -700,9 +700,8 @@ void
CDefaultContextMenu::TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags) CDefaultContextMenu::TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags)
{ {
// Are we allowed to pick a default? // Are we allowed to pick a default?
UINT ntver = RosGetProcessEffectiveVersion(); if ((uFlags & CMF_NODEFAULT) ||
if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) || ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
{ {
return; return;
} }
@ -713,7 +712,7 @@ CDefaultContextMenu::TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffse
// Does the view want to pick one? // Does the view want to pick one?
INT_PTR forceDfm = 0; INT_PTR forceDfm = 0;
if (_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm) == S_OK && forceDfm) if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
{ {
for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i) for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
{ {
@ -974,7 +973,7 @@ CDefaultContextMenu::DoProperties(
// We are asked to run the default property sheet // We are asked to run the default property sheet
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
return Shell_DefaultContextMenuCallBack(m_psf, m_pDataObj); return SHELL32_ShowPropertiesDialog(m_pDataObj);
} }
return hr; return hr;

View file

@ -1074,37 +1074,25 @@ HRESULT WINAPI CDesktopFolder::GetCurFolder(PIDLIST_ABSOLUTE * pidl)
HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) enum { IDC_PROPERTIES };
return S_OK;
/* no data object means no selection */ /* no data object means no selection */
if (!pdtobj) if (!pdtobj)
{ {
if (uMsg == DFM_INVOKECOMMAND && wParam == 0) if (uMsg == DFM_INVOKECOMMAND && wParam == IDC_PROPERTIES)
{ {
if (32 >= (UINT_PTR)ShellExecuteW(hwndOwner, L"open", L"rundll32.exe", return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL;
L"shell32.dll,Control_RunDLL desk.cpl", NULL, SW_SHOWNORMAL))
{
return E_FAIL;
}
return S_OK;
} }
else if (uMsg == DFM_MERGECONTEXTMENU) else if (uMsg == DFM_MERGECONTEXTMENU)
{ {
QCMINFO *pqcminfo = (QCMINFO *)lParam; QCMINFO *pqcminfo = (QCMINFO *)lParam;
HMENU hpopup = CreatePopupMenu(); HMENU hpopup = CreatePopupMenu();
_InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst++, pqcminfo->idCmdLast, MM_ADDSEPARATOR); pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
DestroyMenu(hpopup); DestroyMenu(hpopup);
return S_OK;
} }
return S_OK;
} }
return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;
return Shell_DefaultContextMenuCallBack(this, pdtobj);
} }
/************************************************************************* /*************************************************************************

View file

@ -274,7 +274,7 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
LPARAM lParam) LPARAM lParam)
{ {
if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
return S_OK; return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
PIDLIST_ABSOLUTE pidlFolder; PIDLIST_ABSOLUTE pidlFolder;
PUITEMID_CHILD *apidl; PUITEMID_CHILD *apidl;
@ -343,6 +343,7 @@ HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
#else #else
pqcminfo->idCmdFirst = (idCmd + 2); pqcminfo->idCmdFirst = (idCmd + 2);
#endif #endif
hr = S_OK;
} }
else if (uMsg == DFM_INVOKECOMMAND) else if (uMsg == DFM_INVOKECOMMAND)
{ {
@ -1306,37 +1307,24 @@ HRESULT WINAPI CDrivesFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
HRESULT WINAPI CDrivesFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) HRESULT WINAPI CDrivesFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) enum { IDC_PROPERTIES };
return S_OK;
/* no data object means no selection */ /* no data object means no selection */
if (!pdtobj) if (!pdtobj)
{ {
if (uMsg == DFM_INVOKECOMMAND && wParam == 1) // #1 if (uMsg == DFM_INVOKECOMMAND && wParam == IDC_PROPERTIES)
{ {
// "System" properties // "System" properties
ShellExecuteW(hwndOwner, return SHELL_ExecuteControlPanelCPL(hwndOwner, L"sysdm.cpl") ? S_OK : E_FAIL;
NULL,
L"rundll32.exe",
L"shell32.dll,Control_RunDLL sysdm.cpl",
NULL,
SW_SHOWNORMAL);
} }
else if (uMsg == DFM_MERGECONTEXTMENU) else if (uMsg == DFM_MERGECONTEXTMENU)
{ {
QCMINFO *pqcminfo = (QCMINFO *)lParam; QCMINFO *pqcminfo = (QCMINFO *)lParam;
HMENU hpopup = CreatePopupMenu(); HMENU hpopup = CreatePopupMenu();
_InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED); // #0 _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
_InsertMenuItemW(hpopup, 1, TRUE, 1, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); // #1 pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
DestroyMenu(hpopup); DestroyMenu(hpopup);
return S_OK;
} }
return S_OK;
} }
return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;
return Shell_DefaultContextMenuCallBack(this, pdtobj);
} }

View file

@ -1887,13 +1887,11 @@ HRESULT CFSFolder::_CreateShellExtInstance(const CLSID *pclsid, LPCITEMIDLIST pi
HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND) enum { IDC_PROPERTIES };
return S_OK;
/* no data object means no selection */ /* no data object means no selection */
if (!pdtobj) if (!pdtobj)
{ {
if (uMsg == DFM_INVOKECOMMAND && wParam == 0) if (uMsg == DFM_INVOKECOMMAND && wParam == IDC_PROPERTIES)
{ {
// Create an data object // Create an data object
CComHeapPtr<ITEMID_CHILD> pidlChild(ILClone(ILFindLastID(m_pidlRoot))); CComHeapPtr<ITEMID_CHILD> pidlChild(ILClone(ILFindLastID(m_pidlRoot)));
@ -1901,7 +1899,7 @@ HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObjec
ILRemoveLastID(pidlParent); ILRemoveLastID(pidlParent);
CComPtr<IDataObject> pDataObj; CComPtr<IDataObject> pDataObj;
HRESULT hr = SHCreateDataObject(pidlParent, 1, &pidlChild, NULL, IID_PPV_ARG(IDataObject, &pDataObj)); HRESULT hr = SHCreateDataObject(pidlParent, 1, &pidlChild.m_pData, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
if (!FAILED_UNEXPECTEDLY(hr)) if (!FAILED_UNEXPECTEDLY(hr))
{ {
// Ask for a title to display // Ask for a title to display
@ -1913,23 +1911,19 @@ HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObjec
ERR("SH_ShowPropertiesDialog failed\n"); ERR("SH_ShowPropertiesDialog failed\n");
} }
} }
return hr;
} }
else if (uMsg == DFM_MERGECONTEXTMENU) else if (uMsg == DFM_MERGECONTEXTMENU)
{ {
QCMINFO *pqcminfo = (QCMINFO *)lParam; QCMINFO *pqcminfo = (QCMINFO *)lParam;
HMENU hpopup = CreatePopupMenu(); HMENU hpopup = CreatePopupMenu();
_InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR); pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
DestroyMenu(hpopup); DestroyMenu(hpopup);
return S_OK;
} }
return S_OK;
} }
return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;
return Shell_DefaultContextMenuCallBack(this, pdtobj);
} }
static HBITMAP DoLoadPicture(LPCWSTR pszFileName) static HBITMAP DoLoadPicture(LPCWSTR pszFileName)

View file

@ -66,16 +66,7 @@ HRESULT CALLBACK NetFolderMenuCallback(IShellFolder *psf,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
switch (uMsg) return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
{
case DFM_MERGECONTEXTMENU:
return S_OK;
case DFM_INVOKECOMMAND:
case DFM_INVOKECOMMANDEX:
case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
return S_FALSE;
}
return E_NOTIMPL;
} }
class CNetFolderEnum : class CNetFolderEnum :

View file

@ -30,7 +30,7 @@ HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf,
LPARAM lParam) LPARAM lParam)
{ {
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK; return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
PIDLIST_ABSOLUTE pidlFolder; PIDLIST_ABSOLUTE pidlFolder;
PUITEMID_CHILD *apidl; PUITEMID_CHILD *apidl;
@ -41,24 +41,14 @@ HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf,
if (_ILIsMyComputer(apidl[0])) if (_ILIsMyComputer(apidl[0]))
{ {
if (32 >= (UINT_PTR)ShellExecuteW(hwnd, if (!SHELL_ExecuteControlPanelCPL(hwnd, L"sysdm.cpl"))
L"open",
L"rundll32.exe",
L"shell32.dll,Control_RunDLL sysdm.cpl",
NULL,
SW_SHOWNORMAL))
{ {
hr = E_FAIL; hr = E_FAIL;
} }
} }
else if (_ILIsDesktop(apidl[0])) else if (_ILIsDesktop(apidl[0]))
{ {
if (32 >= (UINT_PTR)ShellExecuteW(hwnd, if (!SHELL_ExecuteControlPanelCPL(hwnd, L"desk.cpl"))
L"open",
L"rundll32.exe",
L"shell32.dll,Control_RunDLL desk.cpl",
NULL,
SW_SHOWNORMAL))
{ {
hr = E_FAIL; hr = E_FAIL;
} }

View file

@ -140,8 +140,11 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
return FALSE; return FALSE;
} }
HRESULT WINAPI HRESULT
Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj); SHELL32_ShowPropertiesDialog(IDataObject *pdtobj);
HRESULT
SHELL32_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdo, UINT msg);
#define SHELL_ExecuteControlPanelCPL(hwnd, cpl) SHRunControlPanel((cpl), (hwnd))
// CStubWindow32 --- The owner window of file property sheets. // CStubWindow32 --- The owner window of file property sheets.
// This window hides taskbar button of property sheet. // This window hides taskbar button of property sheet.

View file

@ -493,17 +493,35 @@ _ShowPropertiesDialogThread(LPVOID lpParameter)
/* /*
* for internal use * for internal use
*/ */
HRESULT WINAPI HRESULT
Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj) SHELL32_ShowPropertiesDialog(IDataObject *pdtobj)
{ {
if (!pdtobj)
return E_INVALIDARG;
pdtobj->AddRef(); pdtobj->AddRef();
if (!SHCreateThread(_ShowPropertiesDialogThread, pdtobj, CTF_INSIST | CTF_COINIT, NULL)) if (!SHCreateThread(_ShowPropertiesDialogThread, pdtobj, CTF_INSIST | CTF_COINIT, NULL))
{ {
pdtobj->Release(); pdtobj->Release();
return HRESULT_FROM_WIN32(GetLastError()); return HResultFromWin32(GetLastError());
} }
else else
{ {
return S_OK; return S_OK;
} }
} }
HRESULT
SHELL32_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdo, UINT msg)
{
switch (msg)
{
case DFM_MERGECONTEXTMENU:
return S_OK; // Yes, I want verbs
case DFM_INVOKECOMMAND:
return S_FALSE; // Do it for me please
case DFM_GETDEFSTATICID:
return S_FALSE; // Supposedly "required for Windows 7 to pick a default"
}
return E_NOTIMPL;
}