mirror of
https://github.com/reactos/reactos.git
synced 2024-08-12 14:16:30 +00:00
- add szClass to static context menu struct
- remove szCmd from static context menu struct - let ShellExecuteEx do the work of executing static context menu - remove DoOpenExplore function, the verbs "open" + "explore" are now read from registry depending on the class - check if there are dynamic / static available shell extensions svn path=/trunk/; revision=30065
This commit is contained in:
parent
405a934dab
commit
42bab9d044
|
@ -46,7 +46,7 @@ BOOL fileMoving = FALSE;
|
|||
typedef struct _StaticShellEntry_
|
||||
{
|
||||
LPWSTR szVerb;
|
||||
LPWSTR szCmd;
|
||||
LPWSTR szClass;
|
||||
struct _StaticShellEntry_ * Next;
|
||||
}StaticShellEntry, *PStaticShellEntry;
|
||||
|
||||
|
@ -208,8 +208,8 @@ static ULONG WINAPI ISvItemCm_fnRelease(IContextMenu2 *iface)
|
|||
while(nextEntry)
|
||||
{
|
||||
nextEntry = nextEntry->Next;
|
||||
free(curEntry->szCmd);
|
||||
free(curEntry->szVerb);
|
||||
free(curEntry->szClass);
|
||||
free(curEntry);
|
||||
curEntry = nextEntry;
|
||||
}
|
||||
|
@ -368,38 +368,11 @@ SH_LoadContextMenuHandlers(ItemCmImpl *This, IDataObject * pDataObj, HMENU hMenu
|
|||
}
|
||||
|
||||
void
|
||||
SH_AddStaticEntry(ItemCmImpl * This, HKEY hKey, WCHAR *szVerb)
|
||||
SH_AddStaticEntry(ItemCmImpl * This, HKEY hKey, WCHAR *szVerb, WCHAR * szClass)
|
||||
{
|
||||
WCHAR szBuffer[50];
|
||||
WCHAR szCmd[100];
|
||||
DWORD dwCmd, dwBuffer;
|
||||
LONG result;
|
||||
HKEY hSubKey;
|
||||
PStaticShellEntry curEntry;
|
||||
PStaticShellEntry lastEntry = NULL;
|
||||
|
||||
wcscpy(szBuffer, szVerb);
|
||||
wcscat(szBuffer, L"\\command");
|
||||
|
||||
TRACE("szBuffer %s\n", debugstr_w(szBuffer));
|
||||
|
||||
result = RegOpenKeyExW(hKey, szBuffer, 0, KEY_READ, &hSubKey);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("RegOpenKeyEx failed with 0x%x\n", result);
|
||||
return;
|
||||
}
|
||||
dwCmd = sizeof(szCmd);
|
||||
dwBuffer = 50;
|
||||
result = RegEnumValueW(hSubKey, 0, szBuffer, &dwBuffer, 0, NULL, (LPBYTE)szCmd, &dwCmd);
|
||||
RegCloseKey(hSubKey);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("RegGetValueW failed with 0x%x\n", result);
|
||||
return;
|
||||
}
|
||||
TRACE("SH_AddStaticEntry szBuffer %s szCmd %s\n", debugstr_w(szBuffer), debugstr_w(szCmd));
|
||||
|
||||
curEntry = This->head;
|
||||
|
||||
while(curEntry)
|
||||
|
@ -413,12 +386,14 @@ SH_AddStaticEntry(ItemCmImpl * This, HKEY hKey, WCHAR *szVerb)
|
|||
curEntry = curEntry->Next;
|
||||
}
|
||||
|
||||
TRACE("adding verb %s szClass %s\n", debugstr_w(szVerb), debugstr_w(szClass));
|
||||
|
||||
curEntry = malloc(sizeof(StaticShellEntry));
|
||||
if (curEntry)
|
||||
{
|
||||
curEntry->Next = NULL;
|
||||
curEntry->szCmd = wcsdup(szCmd);
|
||||
curEntry->szVerb = wcsdup(szVerb);
|
||||
curEntry->szClass = wcsdup(szClass);
|
||||
}
|
||||
|
||||
if (lastEntry)
|
||||
|
@ -432,15 +407,13 @@ SH_AddStaticEntry(ItemCmImpl * This, HKEY hKey, WCHAR *szVerb)
|
|||
}
|
||||
|
||||
void
|
||||
SH_AddStaticEntryForKey(ItemCmImpl * This, HKEY hKey)
|
||||
SH_AddStaticEntryForKey(ItemCmImpl * This, HKEY hKey, WCHAR * szClass)
|
||||
{
|
||||
LONG result;
|
||||
DWORD dwIndex;
|
||||
WCHAR szName[40];
|
||||
DWORD dwName;
|
||||
|
||||
TRACE("SH_AddStaticEntryForKey entered\n");
|
||||
|
||||
dwIndex = 0;
|
||||
do
|
||||
{
|
||||
|
@ -450,8 +423,7 @@ SH_AddStaticEntryForKey(ItemCmImpl * This, HKEY hKey)
|
|||
szName[39] = 0;
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("szVerb %s\n", debugstr_w(szName));
|
||||
SH_AddStaticEntry(This, hKey, szName);
|
||||
SH_AddStaticEntry(This, hKey, szName, szClass);
|
||||
}
|
||||
dwIndex++;
|
||||
}while(result == ERROR_SUCCESS);
|
||||
|
@ -472,7 +444,7 @@ SH_AddStaticEntryForFileClass(ItemCmImpl * This, WCHAR * szExt)
|
|||
result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
SH_AddStaticEntryForKey(This, hKey);
|
||||
SH_AddStaticEntryForKey(This, hKey, szExt);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
@ -480,13 +452,15 @@ SH_AddStaticEntryForFileClass(ItemCmImpl * This, WCHAR * szExt)
|
|||
result = RegGetValueW(HKEY_CLASSES_ROOT, szExt, NULL, RRF_RT_REG_SZ, NULL, (LPBYTE)szBuffer, &dwBuffer);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
UINT length = strlenW(szBuffer);
|
||||
wcscat(szBuffer, L"\\shell");
|
||||
TRACE("szBuffer %s\n", debugstr_w(szBuffer));
|
||||
|
||||
result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
SH_AddStaticEntryForKey(This, hKey);
|
||||
szBuffer[length] = 0;
|
||||
SH_AddStaticEntryForKey(This, hKey, szBuffer);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
@ -496,18 +470,31 @@ SH_AddStaticEntryForFileClass(ItemCmImpl * This, WCHAR * szExt)
|
|||
result = RegGetValueW(HKEY_CLASSES_ROOT, szExt, L"PerceivedType", RRF_RT_REG_SZ, NULL, (LPBYTE)&szBuffer[23], &dwBuffer);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
UINT length = strlenW(szBuffer);
|
||||
wcscat(szBuffer, L"\\shell");
|
||||
TRACE("szBuffer %s\n", debugstr_w(szBuffer));
|
||||
|
||||
result = RegOpenKeyExW(HKEY_CLASSES_ROOT, szBuffer, 0, KEY_READ | KEY_QUERY_VALUE, &hKey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
SH_AddStaticEntryForKey(This, hKey);
|
||||
szBuffer[length] = 0;
|
||||
SH_AddStaticEntryForKey(This, hKey, szBuffer);
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
void
|
||||
SH_AddStaticEntrySpecial(ItemCmImpl * This)
|
||||
{
|
||||
if (_ILIsFolder(This->apidl[0])) // && (This->rfg & SFGAO_BROWSABLE))
|
||||
{
|
||||
SH_AddStaticEntryForFileClass(This, L"Folder");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UINT
|
||||
SH_AddStaticEntryToMenu(HMENU hMenu, UINT indexMenu, ItemCmImpl * This)
|
||||
{
|
||||
|
@ -584,7 +571,6 @@ static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
|
|||
char sBuffer[100];
|
||||
WCHAR szExt[10];
|
||||
|
||||
static const char sExplore[] = { '&','E','x','p','l','o','r','e',0 };
|
||||
static const char sCopy[] = { '&','C','o','p','y',0 };
|
||||
static const char sCut[] = { '&','C','u','t',0 };
|
||||
static const char sDelete[] = { '&','D','e','l','e','t','e',0 };
|
||||
|
@ -602,10 +588,15 @@ static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
|
|||
sBuffer[0] = '.';
|
||||
MultiByteToWideChar( CP_ACP, 0, sBuffer, -1, (LPWSTR)szExt, 10);
|
||||
SH_AddStaticEntryForFileClass(This, szExt);
|
||||
indexMenu = SH_AddStaticEntryToMenu(hmenu, indexMenu, This);
|
||||
_InsertMenuItem(hmenu, ++indexMenu, TRUE, 0, MFT_SEPARATOR, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_AddStaticEntrySpecial(This);
|
||||
|
||||
}
|
||||
indexMenu = SH_AddStaticEntryToMenu(hmenu, indexMenu, This);
|
||||
|
||||
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
|
||||
pDataObj = IDataObject_Constructor(NULL, This->pidl, This->apidl, This->cidl);
|
||||
if (pDataObj)
|
||||
{
|
||||
|
@ -619,21 +610,7 @@ static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
|
|||
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Select", MFS_ENABLED);
|
||||
|
||||
TRACE("rfg %x\n", This->rfg);
|
||||
if (This->rfg & SFGAO_BROWSABLE)
|
||||
{
|
||||
if(This->bAllValues)
|
||||
{
|
||||
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Open", MFS_ENABLED);
|
||||
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_EXPLORE, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_EXPLORE, sExplore, sBuffer), MFS_ENABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_EXPLORE, MFT_STRING, GetLocalizedString(hLocalMenu, FCIDM_SHVIEW_EXPLORE, sExplore, sBuffer), MFS_ENABLED);
|
||||
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Open", MFS_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
|
||||
|
||||
if (This->rfg & (SFGAO_CANCOPY | SFGAO_CANMOVE))
|
||||
{
|
||||
|
@ -670,51 +647,6 @@ static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
|
|||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, lastindex);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DoOpenExplore
|
||||
*
|
||||
* for folders only
|
||||
*/
|
||||
|
||||
static void DoOpenExplore(
|
||||
IContextMenu2 *iface,
|
||||
HWND hwnd,
|
||||
LPCSTR verb)
|
||||
{
|
||||
ItemCmImpl *This = (ItemCmImpl *)iface;
|
||||
|
||||
UINT i, bFolderFound = FALSE;
|
||||
LPITEMIDLIST pidlFQ;
|
||||
SHELLEXECUTEINFOA sei;
|
||||
|
||||
/* Find the first item in the list that is not a value. These commands
|
||||
should never be invoked if there isn't at least one folder item in the list.*/
|
||||
|
||||
for(i = 0; i<This->cidl; i++)
|
||||
{
|
||||
if(!_ILIsValue(This->apidl[i]))
|
||||
{
|
||||
bFolderFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFolderFound) return;
|
||||
|
||||
pidlFQ = ILCombine(This->pidl, This->apidl[i]);
|
||||
|
||||
ZeroMemory(&sei, sizeof(sei));
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_CLASSNAME;
|
||||
sei.lpIDList = pidlFQ;
|
||||
sei.lpClass = "Folder";
|
||||
sei.hwnd = hwnd;
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpVerb = verb;
|
||||
ShellExecuteExA(&sei);
|
||||
SHFree(pidlFQ);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DoRename
|
||||
*/
|
||||
|
@ -905,15 +837,10 @@ HRESULT
|
|||
DoStaticShellExtensions(ItemCmImpl *This, LPCMINVOKECOMMANDINFO lpcmi)
|
||||
{
|
||||
UINT i;
|
||||
WCHAR szTarget[MAX_PATH];
|
||||
WCHAR szTemp[MAX_PATH];
|
||||
WCHAR *ptr, *szCmd;
|
||||
PStaticShellEntry curEntry;
|
||||
LPITEMIDLIST pidl;
|
||||
STARTUPINFOW sInfo;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
static const WCHAR szP1[] = { '%', '1', 0 };
|
||||
UINT bFolderFound = FALSE;
|
||||
SHELLEXECUTEINFOW sei;
|
||||
|
||||
TRACE("DoStaticShellExtensions entered with lpVerb %x first %x last %x\n", LOWORD(lpcmi->lpVerb), This->iIdSCMFirst, This->iIdSCMLast);
|
||||
|
||||
|
@ -935,47 +862,38 @@ DoStaticShellExtensions(ItemCmImpl *This, LPCMINVOKECOMMANDINFO lpcmi)
|
|||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
ExpandEnvironmentStringsW(curEntry->szCmd, szTarget, MAX_PATH);
|
||||
|
||||
ptr = wcsstr(szTarget, szP1);
|
||||
if (ptr)
|
||||
{
|
||||
ptr[1] = 's';
|
||||
pidl = ILCombine(This->pidl, This->apidl[0]);
|
||||
if (pidl)
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
if (SHGetPathFromIDListW(pidl, szPath))
|
||||
{
|
||||
sprintfW(szTemp, szTarget, szPath);
|
||||
}
|
||||
SHFree(pidl);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[0] = 0;
|
||||
}
|
||||
ptr = szTemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = szTarget;
|
||||
}
|
||||
for(i = 0; i<This->cidl; i++)
|
||||
{
|
||||
if(!_ILIsValue(This->apidl[i]))
|
||||
{
|
||||
bFolderFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZeroMemory(&sInfo, sizeof(sInfo));
|
||||
sInfo.cb = sizeof(sizeof(sInfo));
|
||||
szCmd = wcsdup(ptr);
|
||||
if (bFolderFound && wcsicmp(curEntry->szClass, L"Folder"))
|
||||
{
|
||||
/* when there is a folder with item selected
|
||||
* do nothing
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!szCmd)
|
||||
return E_OUTOFMEMORY;
|
||||
TRACE("curEntry %p verb %s szClass %s\n", curEntry, debugstr_w(curEntry->szVerb), debugstr_w(curEntry->szClass));
|
||||
|
||||
if (CreateProcessW(NULL, szCmd, NULL, NULL,FALSE,0,NULL,NULL,&sInfo, &pi))
|
||||
{
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
}
|
||||
free(szCmd);
|
||||
return S_OK;
|
||||
pidl = ILCombine(This->pidl, This->apidl[0]);
|
||||
|
||||
ZeroMemory(&sei, sizeof(sei));
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.fMask = SEE_MASK_CLASSNAME | SEE_MASK_IDLIST;
|
||||
sei.lpIDList = pidl;
|
||||
sei.lpClass = curEntry->szClass;
|
||||
sei.hwnd = lpcmi->hwnd;
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpVerb = curEntry->szVerb;
|
||||
ShellExecuteExW(&sei);
|
||||
SHFree(pidl);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
@ -1032,14 +950,6 @@ static HRESULT WINAPI ISvItemCm_fnInvokeCommand(
|
|||
{
|
||||
switch(LOWORD(lpcmi->lpVerb))
|
||||
{
|
||||
case FCIDM_SHVIEW_EXPLORE:
|
||||
TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
|
||||
DoOpenExplore(iface, lpcmi->hwnd, "explore");
|
||||
break;
|
||||
case FCIDM_SHVIEW_OPEN:
|
||||
TRACE("Verb FCIDM_SHVIEW_OPEN\n");
|
||||
DoOpenExplore(iface, lpcmi->hwnd, "open");
|
||||
break;
|
||||
case FCIDM_SHVIEW_RENAME:
|
||||
TRACE("Verb FCIDM_SHVIEW_RENAME\n");
|
||||
DoRename(iface, lpcmi->hwnd);
|
||||
|
@ -1061,16 +971,21 @@ static HRESULT WINAPI ISvItemCm_fnInvokeCommand(
|
|||
DoProperties(iface, lpcmi->hwnd);
|
||||
break;
|
||||
default:
|
||||
if (LOWORD(lpcmi->lpVerb) >= This->iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSHELast)
|
||||
TRACE("iIdSHEFirst %x iIdSHELast %x iIdSCMFirst %x iIdSCMLast %x\n", This->iIdSHEFirst, This->iIdSHELast, This->iIdSCMFirst, This->iIdSCMLast);
|
||||
if (This->iIdSHEFirst && This->iIdSHELast)
|
||||
{
|
||||
return DoDynamicShellExtensions(This, lpcmi);
|
||||
if (LOWORD(lpcmi->lpVerb) >= This->iIdSHEFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSHELast)
|
||||
{
|
||||
return DoDynamicShellExtensions(This, lpcmi);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOWORD(lpcmi->lpVerb) >= This->iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSCMLast)
|
||||
if (This->iIdSCMFirst && This->iIdSCMLast)
|
||||
{
|
||||
return DoStaticShellExtensions(This, lpcmi);
|
||||
if (LOWORD(lpcmi->lpVerb) >= This->iIdSCMFirst && LOWORD(lpcmi->lpVerb) <= This->iIdSCMLast)
|
||||
{
|
||||
return DoStaticShellExtensions(This, lpcmi);
|
||||
}
|
||||
}
|
||||
|
||||
FIXME("Unhandled Verb %xl\n",LOWORD(lpcmi->lpVerb));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue