[SHELL32]

- CDefaultContextMenu: Add rudimentary support for callbacks so as to let folders have item specific commands and remove all item specific code from this class.
- Implement context menu callbacks for CFSFolder, CRegFolder, CDrivesFolder in order to let them handle the properties item and let the CDrivesFolder add and handle the Format item itself.

svn path=/trunk/; revision=73243
This commit is contained in:
Giannis Adamopoulos 2016-11-17 14:35:19 +00:00
parent bdf445d754
commit 1d4fcbf920
13 changed files with 276 additions and 156 deletions

View file

@ -61,6 +61,8 @@ class CDefaultContextMenu :
private:
CComPtr<IUnknown> m_site;
CComPtr<IShellFolder> m_psf;
CComPtr<IContextMenuCB> m_pmcb;
LPFNDFMCALLBACK m_pfnmcb;
UINT m_cidl;
PCUITEMID_CHILD_ARRAY m_apidl;
CComPtr<IDataObject> m_pDataObj;
@ -75,6 +77,7 @@ class CDefaultContextMenu :
UINT m_iIdSCMFirst; /* first static used id */
UINT m_iIdSCMLast; /* last static used id */
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
void AddStaticEntriesForKey(HKEY hKey);
BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid);
@ -93,7 +96,6 @@ class CDefaultContextMenu :
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy);
HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoProperties(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoFormat(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
HRESULT DoDynamicShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoStaticShellExtensions(LPCMINVOKECOMMANDINFO lpcmi);
@ -106,7 +108,7 @@ class CDefaultContextMenu :
public:
CDefaultContextMenu();
~CDefaultContextMenu();
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm);
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn);
// IContextMenu
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
@ -133,6 +135,8 @@ class CDefaultContextMenu :
CDefaultContextMenu::CDefaultContextMenu() :
m_psf(NULL),
m_pmcb(NULL),
m_pfnmcb(NULL),
m_cidl(0),
m_apidl(NULL),
m_pDataObj(NULL),
@ -180,7 +184,7 @@ CDefaultContextMenu::~CDefaultContextMenu()
_ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
}
HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm)
HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn)
{
TRACE("cidl %u\n", pdcm->cidl);
@ -189,6 +193,8 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm)
if (m_cidl && !m_apidl)
return E_OUTOFMEMORY;
m_psf = pdcm->psf;
m_pmcb = pdcm->pcmcb;
m_pfnmcb = lpfn;
m_cKeys = pdcm->cKeys;
if (pdcm->cKeys)
@ -219,6 +225,20 @@ HRESULT WINAPI CDefaultContextMenu::Initialize(const DEFCONTEXTMENU *pdcm)
return S_OK;
}
HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
{
if (m_pmcb)
{
return m_pmcb->CallBack(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
}
else if(m_pfnmcb)
{
return m_pfnmcb(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
}
return S_OK;
}
void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
{
PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL;
@ -712,23 +732,15 @@ CDefaultContextMenu::BuildShellItemContextMenu(
IndexMenu = InsertMenuItemsOfDynamicContextMenuExtension(hMenu, IndexMenu, iIdCmdFirst, iIdCmdLast);
TRACE("IndexMenu %d\n", IndexMenu);
if (_ILIsDrive(m_apidl[0]))
{
char szDrive[8] = {0};
DWORD dwFlags;
_ILGetDrive(m_apidl[0], szDrive, sizeof(szDrive));
if (GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0))
{
/* Disable format if read only */
if (!(dwFlags & FILE_READ_ONLY_VOLUME))
{
_InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
_InsertMenuItemW(hMenu, IndexMenu++, TRUE, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED);
bAddSep = TRUE;
}
}
}
/* Now let the callback add its own items */
QCMINFO qcminfo;
qcminfo.hmenu = hMenu;
qcminfo.indexMenu = IndexMenu;
qcminfo.idCmdFirst = iIdCmdFirst;
qcminfo.idCmdLast = iIdCmdLast;
qcminfo.pIdMap = NULL;
_DoCallback(DFM_MERGECONTEXTMENU, uFlags, &qcminfo);
IndexMenu = GetMenuItemCount(hMenu);
BOOL bClipboardData = (HasClipboardData() && (rfg & SFGAO_FILESYSTEM));
if (rfg & (SFGAO_CANCOPY | SFGAO_CANMOVE) || bClipboardData)
@ -971,105 +983,8 @@ HRESULT
CDefaultContextMenu::DoProperties(
LPCMINVOKECOMMANDINFO lpcmi)
{
HRESULT hr = S_OK;
const ITEMIDLIST *pidlParent = m_pidlFolder, *pidlChild;
_DoCallback(DFM_INVOKECOMMAND, DFM_CMD_PROPERTIES, NULL);
if (!pidlParent)
{
CComPtr<IPersistFolder2> pf;
/* pidlFolder is optional */
if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
{
pf->GetCurFolder((_ITEMIDLIST**)&pidlParent);
}
}
if (m_cidl > 0)
pidlChild = m_apidl[0];
else
{
/* Set pidlChild to last pidl of current folder */
if (pidlParent == m_pidlFolder)
pidlParent = (ITEMIDLIST*)ILClone(pidlParent);
pidlChild = (ITEMIDLIST*)ILClone(ILFindLastID(pidlParent));
ILRemoveLastID((ITEMIDLIST*)pidlParent);
}
if (_ILIsMyComputer(pidlChild))
{
if (32 >= (UINT)ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL))
hr = E_FAIL;
}
else if (_ILIsDesktop(pidlChild))
{
if (32 >= (UINT)ShellExecuteW(lpcmi->hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL))
hr = E_FAIL;
}
else if (_ILIsDrive(pidlChild))
{
WCHAR wszBuf[MAX_PATH];
ILGetDisplayName(pidlChild, wszBuf);
if (!SH_ShowDriveProperties(wszBuf, pidlParent, &pidlChild))
hr = E_FAIL;
}
else if (_ILIsNetHood(pidlChild))
{
// FIXME path!
if (32 >= (UINT)ShellExecuteW(NULL, L"open", L"explorer.exe",
L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}",
NULL, SW_SHOWDEFAULT))
hr = E_FAIL;
}
else if (_ILIsBitBucket(pidlChild))
{
/* FIXME: detect the drive path of bitbucket if appropiate */
if (!SH_ShowRecycleBinProperties(L'C'))
hr = E_FAIL;
}
else
{
if (m_cidl > 1)
WARN("SHMultiFileProperties is not yet implemented\n");
STRRET strFile;
hr = m_psf->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strFile);
if (SUCCEEDED(hr))
{
WCHAR wszBuf[MAX_PATH];
hr = StrRetToBufW(&strFile, pidlChild, wszBuf, _countof(wszBuf));
if (SUCCEEDED(hr))
hr = SH_ShowPropertiesDialog(wszBuf, pidlParent, &pidlChild);
else
ERR("StrRetToBufW failed\n");
}
else
ERR("IShellFolder_GetDisplayNameOf failed for apidl\n");
}
/* Free allocated PIDLs */
if (pidlParent != m_pidlFolder)
ILFree((ITEMIDLIST*)pidlParent);
if (m_cidl < 1 || pidlChild != m_apidl[0])
ILFree((ITEMIDLIST*)pidlChild);
return hr;
}
HRESULT
CDefaultContextMenu::DoFormat(
LPCMINVOKECOMMANDINFO lpcmi)
{
char szDrive[8] = {0};
if (!_ILGetDrive(m_apidl[0], szDrive, sizeof(szDrive)))
{
ERR("pidl is not a drive\n");
return E_FAIL;
}
SHFormatDrive(lpcmi->hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
return S_OK;
}
@ -1411,13 +1326,13 @@ CDefaultContextMenu::InvokeCommand(
case FCIDM_SHVIEW_PROPERTIES:
Result = DoProperties(&LocalInvokeInfo);
break;
case 0x7ABC:
Result = DoFormat(&LocalInvokeInfo);
break;
case FCIDM_SHVIEW_NEWFOLDER:
Result = DoCreateNewFolder(&LocalInvokeInfo);
break;
default:
_DoCallback(DFM_INVOKECOMMAND, LOWORD(LocalInvokeInfo.lpVerb), NULL);
Result = E_UNEXPECTED;
break;
}
@ -1561,9 +1476,9 @@ CDefaultContextMenu::GetSite(REFIID riid, void **ppvSite)
static
HRESULT
CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn, REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, riid, ppv);
return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
}
/*************************************************************************
@ -1575,7 +1490,7 @@ HRESULT
WINAPI
SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
{
HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, riid, ppv);
HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, NULL, riid, ppv);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -1600,18 +1515,18 @@ CDefFolderMenu_Create2(
const HKEY *ahkeyClsKeys,
IContextMenu **ppcm)
{
DEFCONTEXTMENU pdcm;
pdcm.hwnd = hwnd;
pdcm.pcmcb = NULL;
pdcm.pidlFolder = pidlFolder;
pdcm.psf = psf;
pdcm.cidl = cidl;
pdcm.apidl = apidl;
pdcm.punkAssociationInfo = NULL;
pdcm.cKeys = nKeys;
pdcm.aKeys = ahkeyClsKeys;
DEFCONTEXTMENU dcm;
dcm.hwnd = hwnd;
dcm.pcmcb = NULL;
dcm.pidlFolder = pidlFolder;
dcm.psf = psf;
dcm.cidl = cidl;
dcm.apidl = apidl;
dcm.punkAssociationInfo = NULL;
dcm.cKeys = nKeys;
dcm.aKeys = ahkeyClsKeys;
HRESULT hr = SHCreateDefaultContextMenu(&pdcm, IID_PPV_ARG(IContextMenu, ppcm));
HRESULT hr = CDefaultContextMenu_CreateInstance(&dcm, lpfn, IID_PPV_ARG(IContextMenu, ppcm));
if (FAILED_UNEXPECTEDLY(hr))
return hr;

View file

@ -123,7 +123,7 @@ typedef struct _DRIVE_PROP_PAGE
} DRIVE_PROP_PAGE;
BOOL
SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
{
HPSXA hpsx = NULL;
HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];

View file

@ -95,7 +95,7 @@ LoadPropSheetHandlers(LPCWSTR pwszPath, PROPSHEETHEADERW *pHeader, UINT cMaxPage
*/
BOOL
SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
{
HPSXA hpsxa[3] = {NULL, NULL, NULL};
CComObject<CFileDefExt> *pFileDefExt = NULL;

View file

@ -133,8 +133,8 @@ HRESULT CCPLExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, R
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
if (FAILED(hr))
return NULL;
if (FAILED_UNEXPECTEDLY(hr))
return hr;
initIcon->SetNormalIcon(pData->szName, (int)pData->iconIdx != -1 ? pData->iconIdx : 0);

View file

@ -39,6 +39,69 @@ CDrivesFolderEnum is only responsible for returning the physical items.
* IShellFolder implementation
*/
HRESULT CALLBACK DrivesContextMenuCallback(IShellFolder *psf,
HWND hwnd,
IDataObject *pdtobj,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
return S_OK;
PIDLIST_ABSOLUTE pidlFolder;
PUITEMID_CHILD *apidl;
UINT cidl;
HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
char szDrive[8] = {0};
if (!_ILGetDrive(apidl[0], szDrive, sizeof(szDrive)))
{
ERR("pidl is not a drive\n");
SHFree(pidlFolder);
_ILFreeaPidl(apidl, cidl);
return E_FAIL;
}
if (uMsg == DFM_MERGECONTEXTMENU)
{
QCMINFO *pqcminfo = (QCMINFO *)lParam;
DWORD dwFlags;
if (GetVolumeInformationA(szDrive, NULL, 0, NULL, NULL, &dwFlags, NULL, 0))
{
/* Disable format if read only */
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, 0x7ABC, MFT_STRING, MAKEINTRESOURCEW(IDS_FORMATDRIVE), MFS_ENABLED);
}
}
}
else if (uMsg == DFM_INVOKECOMMAND)
{
if(wParam == 0x7ABC)
{
SHFormatDrive(hwnd, szDrive[0] - 'A', SHFMT_ID_DEFAULT, 0);
}
else if (wParam == DFM_CMD_PROPERTIES)
{
WCHAR wszBuf[4];
wcscpy(wszBuf, L"A:\\");
wszBuf[0] = (WCHAR)szDrive[0];
if (!SH_ShowDriveProperties(wszBuf, pidlFolder, apidl))
hr = E_FAIL;
}
}
SHFree(pidlFolder);
_ILFreeaPidl(apidl, cidl);
return hr;
}
HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
HWND hwnd,
UINT cidl,
@ -51,16 +114,15 @@ HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
AddClassKeyToArray(L"Drive", hKeys, &cKeys);
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
/* TODO: also pass a callback here */
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm);
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, DrivesContextMenuCallback, cKeys, hKeys, ppcm);
}
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
if (FAILED(hr))
return NULL;
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CHAR* pszDrive = _ILGetDataPointer(pidl)->u.drive.szDriveName;
WCHAR wTemp[MAX_PATH];

View file

@ -489,12 +489,21 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
{
IContextMenu * pCm = NULL;
HKEY hKeys[16];
UINT cKeys = 0;
AddFSClassKeysToArray(apidl[0], hKeys, &cKeys);
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, cKeys, hKeys, &pCm);
pObj = pCm;
DEFCONTEXTMENU dcm;
dcm.hwnd = hwndOwner;
dcm.pcmcb = this;
dcm.pidlFolder = pidlRoot;
dcm.psf = this;
dcm.cidl = cidl;
dcm.apidl = apidl;
dcm.cKeys = cKeys;
dcm.aKeys = hKeys;
dcm.punkAssociationInfo = NULL;
hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
}
else if (IsEqualIID (riid, IID_IDataObject))
{
@ -1088,4 +1097,38 @@ HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandler(const CLSID *pclsid, LPC
return hr;
}
return hr;
}
}
HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;
PIDLIST_ABSOLUTE pidlFolder;
PUITEMID_CHILD *apidl;
UINT cidl;
HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (cidl > 1)
ERR("SHMultiFileProperties is not yet implemented\n");
STRRET strFile;
hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
if (SUCCEEDED(hr))
{
hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
if (FAILED(hr))
ERR("SH_ShowPropertiesDialog failed\n");
}
else
{
ERR("Failed to get display name\n");
}
SHFree(pidlFolder);
_ILFreeaPidl(apidl, cidl);
return hr;
}

View file

@ -27,7 +27,8 @@ class CFSFolder :
public CComCoClass<CFSFolder, &CLSID_ShellFSFolder>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder3
public IPersistFolder3,
public IContextMenuCB
{
private:
CLSID *pclsid;
@ -80,6 +81,9 @@ class CFSFolder :
virtual HRESULT WINAPI InitializeEx(IBindCtx *pbc, LPCITEMIDLIST pidlRoot, const PERSIST_FOLDER_TARGET_INFO *ppfti);
virtual HRESULT WINAPI GetFolderTargetInfo(PERSIST_FOLDER_TARGET_INFO *ppfti);
// IContextMenuCB
virtual HRESULT WINAPI CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam);
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLFSFOLDER)
DECLARE_NOT_AGGREGATABLE(CFSFolder)

View file

@ -53,8 +53,8 @@ HRESULT CNetFolderExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID riid, LP
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
if (FAILED(hr))
return NULL;
if (FAILED_UNEXPECTEDLY(hr))
return hr;
initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_NETWORK_FOLDER);

View file

@ -67,8 +67,8 @@ HRESULT CRecyclerExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID riid, LPV
{
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
if (FAILED(hr))
return NULL;
if (FAILED_UNEXPECTEDLY(hr))
return hr;
/* FIXME: This is completely unimplemented */
initIcon->SetNormalIcon(swShell32Name, 0);

View file

@ -22,6 +22,54 @@
WINE_DEFAULT_DEBUG_CHANNEL (shell);
HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf,
HWND hwnd,
IDataObject *pdtobj,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK;
PIDLIST_ABSOLUTE pidlFolder;
PUITEMID_CHILD *apidl;
UINT cidl;
HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (_ILIsMyComputer(apidl[0]))
{
if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL sysdm.cpl", NULL, NULL, SW_SHOWNORMAL))
hr = E_FAIL;
}
else if (_ILIsDesktop(apidl[0]))
{
if (32 >= (UINT)ShellExecuteW(hwnd, L"open", L"rundll32.exe shell32.dll,Control_RunDLL desk.cpl", NULL, NULL, SW_SHOWNORMAL))
hr = E_FAIL;
}
else if (_ILIsNetHood(apidl[0]))
{
// FIXME path!
if (32 >= (UINT)ShellExecuteW(NULL, L"open", L"explorer.exe",
L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}",
NULL, SW_SHOWDEFAULT))
hr = E_FAIL;
}
else if (_ILIsBitBucket(apidl[0]))
{
/* FIXME: detect the drive path of bitbucket if appropiate */
if (!SH_ShowRecycleBinProperties(L'C'))
hr = E_FAIL;
}
SHFree(pidlFolder);
_ILFreeaPidl(apidl, cidl);
return hr;
}
HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
HWND hwnd,
UINT cidl,
@ -48,7 +96,7 @@ HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
}
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm);
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, RegFolderContextMenuCallback, cKeys, hKeys, ppcm);
}
HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
@ -398,6 +446,10 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
hr = CGuidItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
}
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
{
hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, (IDataObject **)&pObj);
}
else
{
hr = E_NOINTERFACE;

View file

@ -63,6 +63,8 @@ BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);
void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys);
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl);
static __inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
{
return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",

View file

@ -547,6 +547,49 @@ void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys)
}
}
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
{
UINT cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
if (!cfShellIDList)
return E_FAIL;
FORMATETC fmt;
InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
HRESULT hr = pDataObject->QueryGetData(&fmt);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
STGMEDIUM medium;
hr = pDataObject->GetData(&fmt, &medium);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
/* lock the handle */
LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
if (!lpcida)
{
ReleaseStgMedium(&medium);
return E_FAIL;
}
/* convert the data into pidl */
LPITEMIDLIST pidl;
LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
if (!apidl)
{
ReleaseStgMedium(&medium);
return E_OUTOFMEMORY;
}
*ppidlfolder = pidl;
*apidlItems = apidl;
*pcidl = lpcida->cidl;
ReleaseStgMedium(&medium);
return S_OK;
}
/***********************************************************************
* SHCreateLinks
*

View file

@ -189,10 +189,9 @@ BOOL SHELL_IsShortcut(LPCITEMIDLIST) DECLSPEC_HIDDEN;
INT_PTR CALLBACK SH_FileGeneralDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK SH_FileVersionDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
HPROPSHEETPAGE SH_CreatePropertySheetPage(WORD wDialogId, DLGPROC pfnDlgProc, LPARAM lParam, LPCWSTR pwszTitle);
BOOL SH_ShowDriveProperties(WCHAR *drive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl);
BOOL SH_ShowDriveProperties(WCHAR *drive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl);
BOOL SH_ShowRecycleBinProperties(WCHAR sDrive);
BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl);
BOOL SH_ShowFolderProperties(LPWSTR pwszFolder, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl);
BOOL SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl);
LPWSTR SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT cchBuf);
HRESULT WINAPI DoRegisterServer(void);