mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 21:21:33 +00:00
[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:
parent
bdf445d754
commit
1d4fcbf920
13 changed files with 276 additions and 156 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}",
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue