mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 17:00:31 +00:00
[SHELL32]
- Implement filling in needed keys passed to CDefFolderMenu_Create2. - CDefaultContextMenu: Remove the code that filled the array of keys as this is now moved to the implementation of the shell folder. svn path=/trunk/; revision=73237
This commit is contained in:
parent
46512f3a37
commit
6cf2a9fc0e
8 changed files with 149 additions and 102 deletions
|
@ -1571,96 +1571,10 @@ CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, REFIID riid, void
|
|||
*
|
||||
*/
|
||||
|
||||
static void AddClassKey(const WCHAR * szClass, HKEY* buffer, UINT* cKeys)
|
||||
{
|
||||
LSTATUS result;
|
||||
HKEY hkey;
|
||||
result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szClass, 0, KEY_READ | KEY_QUERY_VALUE, &hkey);
|
||||
if (result != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
buffer[*cKeys] = hkey;
|
||||
*cKeys +=1;
|
||||
}
|
||||
|
||||
void HackFillKeys(DEFCONTEXTMENU *pdcm, HKEY* buffer)
|
||||
{
|
||||
PCUITEMID_CHILD pidl = pdcm->apidl[0];
|
||||
pdcm->cKeys = 0;
|
||||
pdcm->aKeys = buffer;
|
||||
|
||||
if (_ILIsValue(pidl))
|
||||
{
|
||||
FileStructW* pFileData = _ILGetFileStructW(pidl);
|
||||
LPWSTR extension = PathFindExtension(pFileData->wszName);
|
||||
|
||||
if (extension)
|
||||
{
|
||||
AddClassKey(extension, buffer, &pdcm->cKeys);
|
||||
|
||||
WCHAR wszClass[40], wszClass2[40];
|
||||
DWORD dwSize = sizeof(wszClass);
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, extension, NULL, RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
swprintf(wszClass2, L"%s//%s", extension, wszClass);
|
||||
|
||||
AddClassKey(wszClass, buffer, &pdcm->cKeys);
|
||||
AddClassKey(wszClass2, buffer, &pdcm->cKeys);
|
||||
}
|
||||
|
||||
swprintf(wszClass2, L"SystemFileAssociations//%s", extension);
|
||||
AddClassKey(wszClass2, buffer, &pdcm->cKeys);
|
||||
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, extension, L"PerceivedType ", RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
swprintf(wszClass2, L"SystemFileAssociations//%s", wszClass);
|
||||
AddClassKey(wszClass2, buffer, &pdcm->cKeys);
|
||||
}
|
||||
}
|
||||
|
||||
AddClassKey(L"AllFilesystemObjects", buffer, &pdcm->cKeys);
|
||||
AddClassKey(L"*", buffer, &pdcm->cKeys);
|
||||
}
|
||||
else if (_ILIsSpecialFolder(pidl))
|
||||
{
|
||||
GUID *pGuid = _ILGetGUIDPointer(pidl);
|
||||
if (pGuid)
|
||||
{
|
||||
LPOLESTR pwszCLSID;
|
||||
WCHAR key[60];
|
||||
|
||||
wcscpy(key, L"CLSID\\");
|
||||
HRESULT hr = StringFromCLSID(*pGuid, &pwszCLSID);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
wcscpy(&key[6], pwszCLSID);
|
||||
AddClassKey(key, buffer, &pdcm->cKeys);
|
||||
}
|
||||
}
|
||||
AddClassKey(L"Folder", buffer, &pdcm->cKeys);
|
||||
}
|
||||
else if (_ILIsFolder(pidl))
|
||||
{
|
||||
AddClassKey(L"AllFilesystemObjects", buffer, &pdcm->cKeys);
|
||||
AddClassKey(L"Directory", buffer, &pdcm->cKeys);
|
||||
AddClassKey(L"Folder", buffer, &pdcm->cKeys);
|
||||
}
|
||||
else if (_ILIsDrive(pidl))
|
||||
{
|
||||
AddClassKey(L"Drive", buffer, &pdcm->cKeys);
|
||||
AddClassKey(L"Folder", buffer, &pdcm->cKeys);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
|
||||
{
|
||||
/* HACK: move to the shell folders implementation */
|
||||
HKEY hkeyHack[16];
|
||||
if (!pdcm->aKeys && pdcm->cidl)
|
||||
HackFillKeys((DEFCONTEXTMENU *)pdcm, hkeyHack);
|
||||
|
||||
HRESULT hr = CDefaultContextMenu_CreateInstance(pdcm, riid, ppv);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
|
|
@ -486,7 +486,7 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
|
|||
if (bHasCpl)
|
||||
hr = ShellObjectCreatorInit<CCPLItemMenu>(cidl, apidl, riid, &pObj);
|
||||
else
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj);
|
||||
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
|
||||
} else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) {
|
||||
hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
|
||||
} else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) {
|
||||
|
|
|
@ -639,7 +639,21 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
|
|||
|
||||
if (IsEqualIID (riid, IID_IContextMenu))
|
||||
{
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu **)&pObj);
|
||||
if (_ILIsSpecialFolder(apidl[0]))
|
||||
{
|
||||
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do not use the context menu of the CFSFolder here. */
|
||||
/* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
|
||||
/* Otherwise operations like that involve items from both user and shared desktop will not work */
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
|
||||
{
|
||||
|
@ -817,14 +831,15 @@ HRESULT WINAPI CDesktopFolder::Initialize(LPCITEMIDLIST pidl)
|
|||
{
|
||||
TRACE ("(%p)->(%p)\n", this, pidl);
|
||||
|
||||
return E_NOTIMPL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDesktopFolder::GetCurFolder(LPITEMIDLIST * pidl)
|
||||
{
|
||||
TRACE ("(%p)->(%p)\n", this, pidl);
|
||||
|
||||
if (!pidl) return E_POINTER;
|
||||
if (!pidl)
|
||||
return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
|
||||
*pidl = ILClone (pidlRoot);
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,22 @@ CDrivesFolderEnum is only responsible for returning the physical items.
|
|||
* IShellFolder implementation
|
||||
*/
|
||||
|
||||
HRESULT CDrivesContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
|
||||
HWND hwnd,
|
||||
UINT cidl,
|
||||
PCUITEMID_CHILD_ARRAY apidl,
|
||||
IShellFolder *psf,
|
||||
IContextMenu **ppcm)
|
||||
{
|
||||
HKEY hKeys[2];
|
||||
UINT cKeys = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
|
||||
{
|
||||
CComPtr<IDefaultExtractIconInit> initIcon;
|
||||
|
@ -536,7 +552,10 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner,
|
|||
|
||||
if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
|
||||
{
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj);
|
||||
if (_ILIsDrive(apidl[0]))
|
||||
hr = CDrivesContextMenu_CreateInstance(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
|
||||
else
|
||||
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
|
||||
{
|
||||
|
@ -812,12 +831,6 @@ HRESULT WINAPI CDrivesFolder::GetClassID(CLSID *lpClassId)
|
|||
*/
|
||||
HRESULT WINAPI CDrivesFolder::Initialize(LPCITEMIDLIST pidl)
|
||||
{
|
||||
TRACE ("(%p)->(%p)\n", this, pidl);
|
||||
|
||||
if (pidlRoot)
|
||||
SHFree((LPVOID)pidlRoot);
|
||||
|
||||
pidlRoot = ILClone(pidl);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -829,7 +842,7 @@ HRESULT WINAPI CDrivesFolder::GetCurFolder(LPITEMIDLIST *pidl)
|
|||
TRACE("(%p)->(%p)\n", this, pidl);
|
||||
|
||||
if (!pidl)
|
||||
return E_POINTER;
|
||||
return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
|
||||
|
||||
*pidl = ILClone(pidlRoot);
|
||||
return S_OK;
|
||||
|
|
|
@ -490,7 +490,10 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
|
|||
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1))
|
||||
{
|
||||
IContextMenu * pCm = NULL;
|
||||
hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), NULL, 0, NULL, &pCm);
|
||||
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;
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IDataObject))
|
||||
|
|
|
@ -22,6 +22,35 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL (shell);
|
||||
|
||||
HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
|
||||
HWND hwnd,
|
||||
UINT cidl,
|
||||
PCUITEMID_CHILD_ARRAY apidl,
|
||||
IShellFolder *psf,
|
||||
IContextMenu **ppcm)
|
||||
{
|
||||
HKEY hKeys[10];
|
||||
UINT cKeys = 0;
|
||||
|
||||
GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
|
||||
if (pGuid)
|
||||
{
|
||||
LPOLESTR pwszCLSID;
|
||||
WCHAR key[60];
|
||||
|
||||
wcscpy(key, L"CLSID\\");
|
||||
HRESULT hr = StringFromCLSID(*pGuid, &pwszCLSID);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
wcscpy(&key[6], pwszCLSID);
|
||||
AddClassKeyToArray(key, hKeys, &cKeys);
|
||||
}
|
||||
}
|
||||
AddClassKeyToArray(L"Folder", hKeys, &cKeys);
|
||||
|
||||
return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, NULL, cKeys, hKeys, ppcm);
|
||||
}
|
||||
|
||||
HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut)
|
||||
{
|
||||
CComPtr<IDefaultExtractIconInit> initIcon;
|
||||
|
@ -175,13 +204,26 @@ HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot,
|
|||
|
||||
HRESULT CRegFolder::GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
|
||||
{
|
||||
DWORD dwAttributes = *pdwAttributes;
|
||||
|
||||
/* First try to get them from the registry */
|
||||
if (HCR_GetFolderAttributes(pidl, pdwAttributes) && *pdwAttributes)
|
||||
if (!HCR_GetFolderAttributes(pidl, pdwAttributes))
|
||||
{
|
||||
return S_OK;
|
||||
/* We couldn't get anything */
|
||||
*pdwAttributes = 0;
|
||||
}
|
||||
|
||||
*pdwAttributes &= SFGAO_CANLINK;
|
||||
/* Items have more attributes when on desktop */
|
||||
if (_ILIsDesktop(m_pidlRoot))
|
||||
{
|
||||
*pdwAttributes |= (dwAttributes & (SFGAO_CANLINK|SFGAO_CANDELETE|SFGAO_CANRENAME|SFGAO_HASPROPSHEET));
|
||||
}
|
||||
|
||||
/* In any case, links can be created */
|
||||
if (*pdwAttributes == NULL)
|
||||
{
|
||||
*pdwAttributes |= (dwAttributes & SFGAO_CANLINK);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -346,8 +388,20 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH
|
|||
{
|
||||
hr = CGuidItemExtractIcon_CreateInstance(apidl[0], riid, &pObj);
|
||||
}
|
||||
else if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
|
||||
{
|
||||
if (!_ILGetGUIDPointer (apidl[0]))
|
||||
{
|
||||
ERR("Got non guid item!\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = CGuidItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_NOINTERFACE;
|
||||
}
|
||||
|
||||
*ppvOut = pObj;
|
||||
return hr;
|
||||
|
|
|
@ -61,6 +61,8 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
|
|||
extern "C"
|
||||
BOOL HCR_RegOpenClassIDKey(REFIID riid, HKEY *hkey);
|
||||
|
||||
void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys);
|
||||
|
||||
static __inline int SHELL32_GUIDToStringA (REFGUID guid, LPSTR str)
|
||||
{
|
||||
return sprintf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
|
|
|
@ -501,6 +501,52 @@ void AddClassKeyToArray(const WCHAR * szClass, HKEY* array, UINT* cKeys)
|
|||
*cKeys += 1;
|
||||
}
|
||||
|
||||
void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys)
|
||||
{
|
||||
if (_ILIsValue(pidl))
|
||||
{
|
||||
FileStructW* pFileData = _ILGetFileStructW(pidl);
|
||||
LPWSTR extension = PathFindExtension(pFileData->wszName);
|
||||
|
||||
if (extension)
|
||||
{
|
||||
AddClassKeyToArray(extension, array, cKeys);
|
||||
|
||||
WCHAR wszClass[40], wszClass2[40];
|
||||
DWORD dwSize = sizeof(wszClass);
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, extension, NULL, RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
swprintf(wszClass2, L"%s//%s", extension, wszClass);
|
||||
|
||||
AddClassKeyToArray(wszClass, array, cKeys);
|
||||
AddClassKeyToArray(wszClass2, array, cKeys);
|
||||
}
|
||||
|
||||
swprintf(wszClass2, L"SystemFileAssociations//%s", extension);
|
||||
AddClassKeyToArray(wszClass2, array, cKeys);
|
||||
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, extension, L"PerceivedType ", RRF_RT_REG_SZ, NULL, wszClass, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
swprintf(wszClass2, L"SystemFileAssociations//%s", wszClass);
|
||||
AddClassKeyToArray(wszClass2, array, cKeys);
|
||||
}
|
||||
}
|
||||
|
||||
AddClassKeyToArray(L"AllFilesystemObjects", array, cKeys);
|
||||
AddClassKeyToArray(L"*", array, cKeys);
|
||||
}
|
||||
else if (_ILIsFolder(pidl))
|
||||
{
|
||||
AddClassKeyToArray(L"AllFilesystemObjects", array, cKeys);
|
||||
AddClassKeyToArray(L"Directory", array, cKeys);
|
||||
AddClassKeyToArray(L"Folder", array, cKeys);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Got non FS pidl\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SHCreateLinks
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue