mirror of
https://github.com/reactos/reactos.git
synced 2025-07-23 04:23:53 +00:00
Simplify CDefaultContextMenu by using CAtlList (#3405)
This commit is contained in:
parent
c3a4309d0c
commit
db39a50c73
2 changed files with 97 additions and 148 deletions
|
@ -15,15 +15,13 @@ typedef struct _DynamicShellEntry_
|
||||||
UINT iIdCmdFirst;
|
UINT iIdCmdFirst;
|
||||||
UINT NumIds;
|
UINT NumIds;
|
||||||
CLSID ClassID;
|
CLSID ClassID;
|
||||||
IContextMenu *pCM;
|
CComPtr<IContextMenu> pCM;
|
||||||
struct _DynamicShellEntry_ *pNext;
|
|
||||||
} DynamicShellEntry, *PDynamicShellEntry;
|
} DynamicShellEntry, *PDynamicShellEntry;
|
||||||
|
|
||||||
typedef struct _StaticShellEntry_
|
typedef struct _StaticShellEntry_
|
||||||
{
|
{
|
||||||
LPWSTR szVerb;
|
CStringW Verb;
|
||||||
HKEY hkClass;
|
HKEY hkClass;
|
||||||
struct _StaticShellEntry_ *pNext;
|
|
||||||
} StaticShellEntry, *PStaticShellEntry;
|
} StaticShellEntry, *PStaticShellEntry;
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +67,10 @@ class CDefaultContextMenu :
|
||||||
UINT m_cKeys;
|
UINT m_cKeys;
|
||||||
PIDLIST_ABSOLUTE m_pidlFolder;
|
PIDLIST_ABSOLUTE m_pidlFolder;
|
||||||
DWORD m_bGroupPolicyActive;
|
DWORD m_bGroupPolicyActive;
|
||||||
PDynamicShellEntry m_pDynamicEntries; /* first dynamic shell extension entry */
|
CAtlList<DynamicShellEntry> m_DynamicEntries;
|
||||||
UINT m_iIdSHEFirst; /* first used id */
|
UINT m_iIdSHEFirst; /* first used id */
|
||||||
UINT m_iIdSHELast; /* last used id */
|
UINT m_iIdSHELast; /* last used id */
|
||||||
PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
|
CAtlList<StaticShellEntry> m_StaticEntries;
|
||||||
UINT m_iIdSCMFirst; /* first static used id */
|
UINT m_iIdSCMFirst; /* first static used id */
|
||||||
UINT m_iIdSCMLast; /* last static used id */
|
UINT m_iIdSCMLast; /* last static used id */
|
||||||
UINT m_iIdCBFirst; /* first callback used id */
|
UINT m_iIdCBFirst; /* first callback used id */
|
||||||
|
@ -83,8 +81,8 @@ class CDefaultContextMenu :
|
||||||
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
|
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam);
|
||||||
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
|
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
|
||||||
void AddStaticEntriesForKey(HKEY hKey);
|
void AddStaticEntriesForKey(HKEY hKey);
|
||||||
BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid);
|
BOOL IsShellExtensionAlreadyLoaded(REFCLSID clsid);
|
||||||
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
|
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid);
|
||||||
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
|
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey);
|
||||||
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast);
|
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast);
|
||||||
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
|
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
|
||||||
|
@ -145,41 +143,21 @@ CDefaultContextMenu::CDefaultContextMenu() :
|
||||||
m_cKeys(NULL),
|
m_cKeys(NULL),
|
||||||
m_pidlFolder(NULL),
|
m_pidlFolder(NULL),
|
||||||
m_bGroupPolicyActive(0),
|
m_bGroupPolicyActive(0),
|
||||||
m_pDynamicEntries(NULL),
|
|
||||||
m_iIdSHEFirst(0),
|
m_iIdSHEFirst(0),
|
||||||
m_iIdSHELast(0),
|
m_iIdSHELast(0),
|
||||||
m_pStaticEntries(NULL),
|
|
||||||
m_iIdSCMFirst(0),
|
m_iIdSCMFirst(0),
|
||||||
m_iIdSCMLast(0),
|
m_iIdSCMLast(0),
|
||||||
m_iIdCBFirst(0),
|
m_iIdCBFirst(0),
|
||||||
m_iIdCBLast(0),
|
m_iIdCBLast(0),
|
||||||
m_iIdDfltFirst(0),
|
m_iIdDfltFirst(0),
|
||||||
m_iIdDfltLast(0)
|
m_iIdDfltLast(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CDefaultContextMenu::~CDefaultContextMenu()
|
CDefaultContextMenu::~CDefaultContextMenu()
|
||||||
{
|
{
|
||||||
/* Free dynamic shell extension entries */
|
m_DynamicEntries.RemoveAll();
|
||||||
PDynamicShellEntry pDynamicEntry = m_pDynamicEntries, pNextDynamic;
|
m_StaticEntries.RemoveAll();
|
||||||
while (pDynamicEntry)
|
|
||||||
{
|
|
||||||
pNextDynamic = pDynamicEntry->pNext;
|
|
||||||
pDynamicEntry->pCM->Release();
|
|
||||||
HeapFree(GetProcessHeap(), 0, pDynamicEntry);
|
|
||||||
pDynamicEntry = pNextDynamic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free static shell extension entries */
|
|
||||||
PStaticShellEntry pStaticEntry = m_pStaticEntries, pNextStatic;
|
|
||||||
while (pStaticEntry)
|
|
||||||
{
|
|
||||||
pNextStatic = pStaticEntry->pNext;
|
|
||||||
HeapFree(GetProcessHeap(), 0, pStaticEntry->szVerb);
|
|
||||||
HeapFree(GetProcessHeap(), 0, pStaticEntry);
|
|
||||||
pStaticEntry = pNextStatic;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (UINT i = 0; i < m_cKeys; i++)
|
for (UINT i = 0; i < m_cKeys; i++)
|
||||||
RegCloseKey(m_aKeys[i]);
|
RegCloseKey(m_aKeys[i]);
|
||||||
|
@ -253,40 +231,28 @@ HRESULT CDefaultContextMenu::_DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam
|
||||||
|
|
||||||
void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
|
void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
|
||||||
{
|
{
|
||||||
PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL;
|
POSITION it = m_StaticEntries.GetHeadPosition();
|
||||||
while(pEntry)
|
while (it != NULL)
|
||||||
{
|
{
|
||||||
if (!wcsicmp(pEntry->szVerb, szVerb))
|
const StaticShellEntry& info = m_StaticEntries.GetNext(it);
|
||||||
|
if (info.Verb.CompareNoCase(szVerb) == 0)
|
||||||
{
|
{
|
||||||
/* entry already exists */
|
/* entry already exists */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pLastEntry = pEntry;
|
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("adding verb %s\n", debugstr_w(szVerb));
|
TRACE("adding verb %s\n", debugstr_w(szVerb));
|
||||||
|
|
||||||
pEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(StaticShellEntry));
|
|
||||||
if (pEntry)
|
|
||||||
{
|
|
||||||
pEntry->pNext = NULL;
|
|
||||||
pEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szVerb) + 1) * sizeof(WCHAR));
|
|
||||||
if (pEntry->szVerb)
|
|
||||||
wcscpy(pEntry->szVerb, szVerb);
|
|
||||||
pEntry->hkClass = hkeyClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wcsicmp(szVerb, L"open"))
|
if (!wcsicmp(szVerb, L"open"))
|
||||||
{
|
{
|
||||||
/* open verb is always inserted in front */
|
/* open verb is always inserted in front */
|
||||||
pEntry->pNext = m_pStaticEntries;
|
m_StaticEntries.AddHead({ szVerb, hkeyClass });
|
||||||
m_pStaticEntries = pEntry;
|
|
||||||
}
|
}
|
||||||
else if (pLastEntry)
|
|
||||||
pLastEntry->pNext = pEntry;
|
|
||||||
else
|
else
|
||||||
m_pStaticEntries = pEntry;
|
{
|
||||||
|
m_StaticEntries.AddTail({ szVerb, hkeyClass });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDefaultContextMenu::AddStaticEntriesForKey(HKEY hKey)
|
void CDefaultContextMenu::AddStaticEntriesForKey(HKEY hKey)
|
||||||
|
@ -333,35 +299,33 @@ HasClipboardData()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
CDefaultContextMenu::IsShellExtensionAlreadyLoaded(const CLSID *pclsid)
|
CDefaultContextMenu::IsShellExtensionAlreadyLoaded(REFCLSID clsid)
|
||||||
{
|
{
|
||||||
PDynamicShellEntry pEntry = m_pDynamicEntries;
|
POSITION it = m_DynamicEntries.GetHeadPosition();
|
||||||
|
while (it != NULL)
|
||||||
while (pEntry)
|
|
||||||
{
|
{
|
||||||
if (!memcmp(&pEntry->ClassID, pclsid, sizeof(CLSID)))
|
const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
|
||||||
|
if (info.ClassID == clsid)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid)
|
CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
|
||||||
|
|
||||||
TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(pclsid));
|
if (IsShellExtensionAlreadyLoaded(clsid))
|
||||||
|
|
||||||
if (IsShellExtensionAlreadyLoaded(pclsid))
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
CComPtr<IContextMenu> pcm;
|
CComPtr<IContextMenu> pcm;
|
||||||
hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IContextMenu, &pcm));
|
hr = SHCoCreateInstance(NULL, &clsid, NULL, IID_PPV_ARG(IContextMenu, &pcm));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
|
ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,41 +333,21 @@ CDefaultContextMenu::LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsi
|
||||||
hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
|
hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
|
ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
|
hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
|
WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_site)
|
if (m_site)
|
||||||
IUnknown_SetSite(pcm, m_site);
|
IUnknown_SetSite(pcm, m_site);
|
||||||
|
|
||||||
PDynamicShellEntry pEntry = (DynamicShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(DynamicShellEntry));
|
m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
|
||||||
if (!pEntry)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
pEntry->iIdCmdFirst = 0;
|
|
||||||
pEntry->pNext = NULL;
|
|
||||||
pEntry->NumIds = 0;
|
|
||||||
pEntry->pCM = pcm.Detach();
|
|
||||||
memcpy(&pEntry->ClassID, pclsid, sizeof(CLSID));
|
|
||||||
|
|
||||||
if (m_pDynamicEntries)
|
|
||||||
{
|
|
||||||
PDynamicShellEntry pLastEntry = m_pDynamicEntries;
|
|
||||||
|
|
||||||
while (pLastEntry->pNext)
|
|
||||||
pLastEntry = pLastEntry->pNext;
|
|
||||||
|
|
||||||
pLastEntry->pNext = pEntry;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_pDynamicEntries = pEntry;
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -463,7 +407,7 @@ CDefaultContextMenu::EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = LoadDynamicContextMenuHandler(hKey, &clsid);
|
hr = LoadDynamicContextMenuHandler(hKey, clsid);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
|
WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
|
||||||
}
|
}
|
||||||
|
@ -477,27 +421,27 @@ CDefaultContextMenu::AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UIN
|
||||||
{
|
{
|
||||||
UINT cIds = 0;
|
UINT cIds = 0;
|
||||||
|
|
||||||
if (!m_pDynamicEntries)
|
if (m_DynamicEntries.IsEmpty())
|
||||||
return cIds;
|
return cIds;
|
||||||
|
|
||||||
PDynamicShellEntry pEntry = m_pDynamicEntries;
|
POSITION it = m_DynamicEntries.GetHeadPosition();
|
||||||
do
|
while (it != NULL)
|
||||||
{
|
{
|
||||||
HRESULT hr = pEntry->pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, CMF_NORMAL);
|
DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
|
||||||
|
|
||||||
|
HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, CMF_NORMAL);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
pEntry->iIdCmdFirst = cIds;
|
info.iIdCmdFirst = cIds;
|
||||||
pEntry->NumIds = LOWORD(hr);
|
info.NumIds = LOWORD(hr);
|
||||||
(*pIndexMenu) += pEntry->NumIds;
|
(*pIndexMenu) += info.NumIds;
|
||||||
|
|
||||||
cIds += pEntry->NumIds;
|
cIds += info.NumIds;
|
||||||
if(idCmdFirst + cIds >= idCmdLast)
|
if (idCmdFirst + cIds >= idCmdLast)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
|
TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
|
||||||
pEntry = pEntry->pNext;
|
}
|
||||||
} while (pEntry);
|
|
||||||
|
|
||||||
return cIds;
|
return cIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,50 +463,53 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
mii.fType = MFT_STRING;
|
mii.fType = MFT_STRING;
|
||||||
mii.dwTypeData = NULL;
|
mii.dwTypeData = NULL;
|
||||||
|
|
||||||
PStaticShellEntry pEntry = m_pStaticEntries;
|
POSITION it = m_StaticEntries.GetHeadPosition();
|
||||||
|
bool first = true;
|
||||||
while (pEntry)
|
while (it != NULL)
|
||||||
{
|
{
|
||||||
|
StaticShellEntry& info = m_StaticEntries.GetNext(it);
|
||||||
|
|
||||||
fState = MFS_ENABLED;
|
fState = MFS_ENABLED;
|
||||||
mii.dwTypeData = NULL;
|
mii.dwTypeData = NULL;
|
||||||
|
|
||||||
/* set first entry as default */
|
/* set first entry as default */
|
||||||
if (pEntry == m_pStaticEntries)
|
if (first)
|
||||||
|
{
|
||||||
fState |= MFS_DEFAULT;
|
fState |= MFS_DEFAULT;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wcsicmp(pEntry->szVerb, L"open"))
|
if (info.Verb.CompareNoCase(L"open") == 0)
|
||||||
{
|
{
|
||||||
/* override default when open verb is found */
|
/* override default when open verb is found */
|
||||||
fState |= MFS_DEFAULT;
|
fState |= MFS_DEFAULT;
|
||||||
idResource = IDS_OPEN_VERB;
|
idResource = IDS_OPEN_VERB;
|
||||||
}
|
}
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"explore"))
|
else if (info.Verb.CompareNoCase(L"explore") == 0)
|
||||||
idResource = IDS_EXPLORE_VERB;
|
idResource = IDS_EXPLORE_VERB;
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"runas"))
|
else if (info.Verb.CompareNoCase(L"runas") == 0)
|
||||||
idResource = IDS_RUNAS_VERB;
|
idResource = IDS_RUNAS_VERB;
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"edit"))
|
else if (info.Verb.CompareNoCase(L"edit") == 0)
|
||||||
idResource = IDS_EDIT_VERB;
|
idResource = IDS_EDIT_VERB;
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"find"))
|
else if (info.Verb.CompareNoCase(L"find") == 0)
|
||||||
idResource = IDS_FIND_VERB;
|
idResource = IDS_FIND_VERB;
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"print"))
|
else if (info.Verb.CompareNoCase(L"print") == 0)
|
||||||
idResource = IDS_PRINT_VERB;
|
idResource = IDS_PRINT_VERB;
|
||||||
else if (!wcsicmp(pEntry->szVerb, L"printto"))
|
else if (info.Verb.CompareNoCase(L"printto") == 0)
|
||||||
{
|
{
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
idResource = 0;
|
idResource = 0;
|
||||||
|
|
||||||
/* By default use verb for menu item name */
|
/* By default use verb for menu item name */
|
||||||
mii.dwTypeData = pEntry->szVerb;
|
mii.dwTypeData = (LPWSTR)info.Verb.GetString();
|
||||||
|
|
||||||
WCHAR wszKey[256];
|
WCHAR wszKey[256];
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
|
hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
{
|
{
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +522,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
else
|
else
|
||||||
ERR("Failed to load string\n");
|
ERR("Failed to load string\n");
|
||||||
|
|
||||||
LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
|
LONG res = RegOpenKeyW(info.hkClass, wszKey, &hkVerb);
|
||||||
if (res == ERROR_SUCCESS)
|
if (res == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
|
res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
|
||||||
|
@ -586,7 +533,7 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
|
LONG res = RegOpenKeyW(info.hkClass, wszKey, &hkVerb);
|
||||||
if (res == ERROR_SUCCESS)
|
if (res == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DWORD cbVerb = sizeof(wszVerb);
|
DWORD cbVerb = sizeof(wszVerb);
|
||||||
|
@ -614,8 +561,6 @@ CDefaultContextMenu::AddStaticContextMenusToMenu(
|
||||||
cIds++;
|
cIds++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
|
|
||||||
if (mii.wID >= iIdCmdLast)
|
if (mii.wID >= iIdCmdLast)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1001,18 +946,21 @@ CDefaultContextMenu::DoCreateNewFolder(
|
||||||
|
|
||||||
PDynamicShellEntry CDefaultContextMenu::GetDynamicEntry(UINT idCmd)
|
PDynamicShellEntry CDefaultContextMenu::GetDynamicEntry(UINT idCmd)
|
||||||
{
|
{
|
||||||
PDynamicShellEntry pEntry = m_pDynamicEntries;
|
POSITION it = m_DynamicEntries.GetHeadPosition();
|
||||||
|
while (it != NULL)
|
||||||
|
{
|
||||||
|
DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
|
||||||
|
|
||||||
while(pEntry && idCmd >= pEntry->iIdCmdFirst + pEntry->NumIds)
|
if (idCmd >= info.iIdCmdFirst + info.NumIds)
|
||||||
pEntry = pEntry->pNext;
|
continue;
|
||||||
|
|
||||||
if (!pEntry)
|
if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (idCmd < pEntry->iIdCmdFirst || idCmd > pEntry->iIdCmdFirst + pEntry->NumIds)
|
return &info;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
return pEntry;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
|
// FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
|
||||||
|
@ -1093,7 +1041,7 @@ CDefaultContextMenu::BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticSh
|
||||||
FlagsName = L"BrowserFlags";
|
FlagsName = L"BrowserFlags";
|
||||||
|
|
||||||
/* Try to get the flag from the verb */
|
/* Try to get the flag from the verb */
|
||||||
hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
|
hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1152,7 +1100,7 @@ CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl,
|
||||||
sei.cbSize = sizeof(sei);
|
sei.cbSize = sizeof(sei);
|
||||||
sei.hwnd = lpcmi->hwnd;
|
sei.hwnd = lpcmi->hwnd;
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
sei.nShow = SW_SHOWNORMAL;
|
||||||
sei.lpVerb = pEntry->szVerb;
|
sei.lpVerb = pEntry->Verb;
|
||||||
sei.lpDirectory = wszDir;
|
sei.lpDirectory = wszDir;
|
||||||
sei.lpIDList = pidlFull;
|
sei.lpIDList = pidlFull;
|
||||||
sei.hkeyClass = pEntry->hkClass;
|
sei.hkeyClass = pEntry->hkClass;
|
||||||
|
@ -1173,16 +1121,16 @@ HRESULT
|
||||||
CDefaultContextMenu::InvokeRegVerb(
|
CDefaultContextMenu::InvokeRegVerb(
|
||||||
LPCMINVOKECOMMANDINFO lpcmi)
|
LPCMINVOKECOMMANDINFO lpcmi)
|
||||||
{
|
{
|
||||||
PStaticShellEntry pEntry = m_pStaticEntries;
|
INT iCmd = LOWORD(lpcmi->lpVerb);
|
||||||
INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
while (pEntry && (iCmd--) > 0)
|
POSITION it = m_StaticEntries.FindIndex(iCmd);
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
|
|
||||||
if (iCmd > 0)
|
if (it == NULL)
|
||||||
return E_FAIL;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
|
||||||
|
|
||||||
/* Get the browse flags to see if we need to browse */
|
/* Get the browse flags to see if we need to browse */
|
||||||
DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
|
DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
|
||||||
|
@ -1236,14 +1184,14 @@ CDefaultContextMenu::InvokeCommand(
|
||||||
|
|
||||||
CmdId = LOWORD(LocalInvokeInfo.lpVerb);
|
CmdId = LOWORD(LocalInvokeInfo.lpVerb);
|
||||||
|
|
||||||
if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
|
if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
|
||||||
{
|
{
|
||||||
LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
|
LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
|
||||||
Result = InvokeShellExt(&LocalInvokeInfo);
|
Result = InvokeShellExt(&LocalInvokeInfo);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
|
if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
|
||||||
{
|
{
|
||||||
LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
|
LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
|
||||||
Result = InvokeRegVerb(&LocalInvokeInfo);
|
Result = InvokeRegVerb(&LocalInvokeInfo);
|
||||||
|
@ -1332,7 +1280,7 @@ CDefaultContextMenu::GetCommandString(
|
||||||
|
|
||||||
UINT CmdId = LOWORD(idCommand);
|
UINT CmdId = LOWORD(idCommand);
|
||||||
|
|
||||||
if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
|
if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
|
||||||
{
|
{
|
||||||
idCommand -= m_iIdSHEFirst;
|
idCommand -= m_iIdSHEFirst;
|
||||||
PDynamicShellEntry pEntry = GetDynamicEntry(idCommand);
|
PDynamicShellEntry pEntry = GetDynamicEntry(idCommand);
|
||||||
|
@ -1347,7 +1295,7 @@ CDefaultContextMenu::GetCommandString(
|
||||||
uMaxNameLen);
|
uMaxNameLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
|
if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
|
||||||
{
|
{
|
||||||
/* Validation just returns S_OK on a match. The id exists. */
|
/* Validation just returns S_OK on a match. The id exists. */
|
||||||
if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
|
if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
|
||||||
|
@ -1355,19 +1303,19 @@ CDefaultContextMenu::GetCommandString(
|
||||||
|
|
||||||
CmdId -= m_iIdSCMFirst;
|
CmdId -= m_iIdSCMFirst;
|
||||||
|
|
||||||
PStaticShellEntry pEntry = m_pStaticEntries;
|
POSITION it = m_StaticEntries.FindIndex(CmdId);
|
||||||
while (pEntry && (CmdId--) > 0)
|
|
||||||
pEntry = pEntry->pNext;
|
|
||||||
|
|
||||||
if (!pEntry)
|
if (it == NULL)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
PStaticShellEntry pEntry = &m_StaticEntries.GetAt(it);
|
||||||
|
|
||||||
if (uFlags == GCS_VERBW)
|
if (uFlags == GCS_VERBW)
|
||||||
return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->szVerb);
|
return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
|
||||||
|
|
||||||
if (uFlags == GCS_VERBA)
|
if (uFlags == GCS_VERBA)
|
||||||
{
|
{
|
||||||
if (SHUnicodeToAnsi(pEntry->szVerb, lpszName, uMaxNameLen))
|
if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1464,11 +1412,11 @@ CDefaultContextMenu::HandleMenuMsg2(
|
||||||
{
|
{
|
||||||
if (uMsg == WM_INITMENUPOPUP)
|
if (uMsg == WM_INITMENUPOPUP)
|
||||||
{
|
{
|
||||||
PDynamicShellEntry pEntry = m_pDynamicEntries;
|
POSITION it = m_DynamicEntries.GetHeadPosition();
|
||||||
while (pEntry)
|
while (it != NULL)
|
||||||
{
|
{
|
||||||
SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
|
DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
|
||||||
pEntry = pEntry->pNext;
|
SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <atlwin.h>
|
#include <atlwin.h>
|
||||||
#include <atlstr.h>
|
#include <atlstr.h>
|
||||||
#include <atlsimpcoll.h>
|
#include <atlsimpcoll.h>
|
||||||
|
#include <atlcoll.h>
|
||||||
#include <powrprof.h>
|
#include <powrprof.h>
|
||||||
#include <winnetwk.h>
|
#include <winnetwk.h>
|
||||||
#include <objsafe.h>
|
#include <objsafe.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue