shell32: Use a smaller range of shellview menu IDs in our IContextMenu functions.
The shellview menu IDs are very large, eg. FCIDM_SHVIEW_OPEN is 0x7102,
while applications want menu IDs to fit into a small range, eg. 1-1000 for
Explorer++. This causes our IContextMenu_QueryContextMenu() functions to
leave out most menu options. We should rebase our shellview menu ids
by -0x7000 so they occupy a smaller range.
This gets both Explorer++ and Double Commander to show the correct
right-click menus.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=24893
Signed-off-by: Damjan Jovanovic <damjan.jov@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit 2b6458b757
)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
This commit is contained in:
parent
3b90fc2314
commit
df085a31ff
|
@ -45,6 +45,8 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||||
|
|
||||||
|
#define FCIDM_BASE 0x7000
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IContextMenu3 IContextMenu3_iface;
|
IContextMenu3 IContextMenu3_iface;
|
||||||
|
@ -142,6 +144,37 @@ static ULONG WINAPI ContextMenu_Release(IContextMenu3 *iface)
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT max_menu_id(HMENU hmenu, UINT offset, UINT last)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UINT max_id = 0;
|
||||||
|
|
||||||
|
for (i = GetMenuItemCount(hmenu) - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
MENUITEMINFOW item;
|
||||||
|
memset(&item, 0, sizeof(MENUITEMINFOW));
|
||||||
|
item.cbSize = sizeof(MENUITEMINFOW);
|
||||||
|
item.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE;
|
||||||
|
if (!GetMenuItemInfoW(hmenu, i, TRUE, &item))
|
||||||
|
continue;
|
||||||
|
if (!(item.fType & MFT_SEPARATOR))
|
||||||
|
{
|
||||||
|
if (item.hSubMenu)
|
||||||
|
{
|
||||||
|
UINT submenu_max_id = max_menu_id(item.hSubMenu, offset, last);
|
||||||
|
if (max_id < submenu_max_id)
|
||||||
|
max_id = submenu_max_id;
|
||||||
|
}
|
||||||
|
if (item.wID + offset <= last)
|
||||||
|
{
|
||||||
|
if (max_id <= item.wID + offset)
|
||||||
|
max_id = item.wID + offset + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max_id;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||||
IContextMenu3 *iface,
|
IContextMenu3 *iface,
|
||||||
HMENU hmenu,
|
HMENU hmenu,
|
||||||
|
@ -162,7 +195,8 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||||
if(uFlags & CMF_EXPLORE)
|
if(uFlags & CMF_EXPLORE)
|
||||||
RemoveMenu(hmenures, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
|
RemoveMenu(hmenures, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
|
||||||
|
|
||||||
uIDMax = Shell_MergeMenus(hmenu, GetSubMenu(hmenures, 0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
|
Shell_MergeMenus(hmenu, GetSubMenu(hmenures, 0), indexMenu, idCmdFirst - FCIDM_BASE, idCmdLast, MM_SUBMENUSHAVEIDS);
|
||||||
|
uIDMax = max_menu_id(GetSubMenu(hmenures, 0), idCmdFirst - FCIDM_BASE, idCmdLast);
|
||||||
|
|
||||||
DestroyMenu(hmenures);
|
DestroyMenu(hmenures);
|
||||||
|
|
||||||
|
@ -174,14 +208,14 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||||
mi.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE;
|
mi.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE;
|
||||||
mi.dwTypeData = str;
|
mi.dwTypeData = str;
|
||||||
mi.cch = 255;
|
mi.cch = 255;
|
||||||
GetMenuItemInfoW(hmenu, FCIDM_SHVIEW_EXPLORE + idCmdFirst, MF_BYCOMMAND, &mi);
|
GetMenuItemInfoW(hmenu, FCIDM_SHVIEW_EXPLORE - FCIDM_BASE + idCmdFirst, MF_BYCOMMAND, &mi);
|
||||||
RemoveMenu(hmenu, FCIDM_SHVIEW_EXPLORE + idCmdFirst, MF_BYCOMMAND);
|
RemoveMenu(hmenu, FCIDM_SHVIEW_EXPLORE - FCIDM_BASE + idCmdFirst, MF_BYCOMMAND);
|
||||||
|
|
||||||
mi.cbSize = sizeof(mi);
|
mi.cbSize = sizeof(mi);
|
||||||
mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_STRING;
|
mi.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_STRING;
|
||||||
mi.dwTypeData = str;
|
mi.dwTypeData = str;
|
||||||
mi.fState = MFS_ENABLED;
|
mi.fState = MFS_ENABLED;
|
||||||
mi.wID = FCIDM_SHVIEW_EXPLORE + idCmdFirst;
|
mi.wID = FCIDM_SHVIEW_EXPLORE - FCIDM_BASE + idCmdFirst;
|
||||||
mi.fType = MFT_STRING;
|
mi.fType = MFT_STRING;
|
||||||
InsertMenuItemW(hmenu, (uFlags & CMF_EXPLORE) ? 1 : 2, MF_BYPOSITION, &mi);
|
InsertMenuItemW(hmenu, (uFlags & CMF_EXPLORE) ? 1 : 2, MF_BYPOSITION, &mi);
|
||||||
}
|
}
|
||||||
|
@ -189,7 +223,7 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||||
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
|
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
|
||||||
|
|
||||||
if(uFlags & ~CMF_CANRENAME)
|
if(uFlags & ~CMF_CANRENAME)
|
||||||
RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME + idCmdFirst, MF_BYCOMMAND);
|
RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME - FCIDM_BASE + idCmdFirst, MF_BYCOMMAND);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT enable = MF_BYCOMMAND;
|
UINT enable = MF_BYCOMMAND;
|
||||||
|
@ -205,7 +239,7 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||||
enable |= (attr & SFGAO_CANRENAME) ? MFS_ENABLED : MFS_DISABLED;
|
enable |= (attr & SFGAO_CANRENAME) ? MFS_ENABLED : MFS_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME + idCmdFirst, enable);
|
EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME - FCIDM_BASE + idCmdFirst, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
|
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
|
||||||
|
@ -738,7 +772,7 @@ static HRESULT WINAPI ItemMenu_InvokeCommand(
|
||||||
|
|
||||||
if (IS_INTRESOURCE(lpcmi->lpVerb))
|
if (IS_INTRESOURCE(lpcmi->lpVerb))
|
||||||
{
|
{
|
||||||
switch(LOWORD(lpcmi->lpVerb))
|
switch(LOWORD(lpcmi->lpVerb) + FCIDM_BASE)
|
||||||
{
|
{
|
||||||
case FCIDM_SHVIEW_EXPLORE:
|
case FCIDM_SHVIEW_EXPLORE:
|
||||||
TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
|
TRACE("Verb FCIDM_SHVIEW_EXPLORE\n");
|
||||||
|
@ -830,7 +864,7 @@ static HRESULT WINAPI ItemMenu_GetCommandString(IContextMenu3 *iface, UINT_PTR c
|
||||||
|
|
||||||
case GCS_VERBA:
|
case GCS_VERBA:
|
||||||
case GCS_VERBW:
|
case GCS_VERBW:
|
||||||
switch (cmdid)
|
switch (cmdid + FCIDM_BASE)
|
||||||
{
|
{
|
||||||
case FCIDM_SHVIEW_OPEN:
|
case FCIDM_SHVIEW_OPEN:
|
||||||
cmdW = openW;
|
cmdW = openW;
|
||||||
|
@ -1059,8 +1093,9 @@ static HRESULT WINAPI BackgroundMenu_QueryContextMenu(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
|
Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
|
||||||
idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
|
idCmdFirst - FCIDM_BASE, idCmdLast, MM_SUBMENUSHAVEIDS);
|
||||||
|
idMax = max_menu_id(GetSubMenu(hMyMenu, 0), idCmdFirst - FCIDM_BASE, idCmdLast);
|
||||||
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst);
|
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst);
|
||||||
}
|
}
|
||||||
DestroyMenu(hMyMenu);
|
DestroyMenu(hMyMenu);
|
||||||
|
@ -1228,7 +1263,7 @@ static HRESULT WINAPI BackgroundMenu_InvokeCommand(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (LOWORD(lpcmi->lpVerb))
|
switch (LOWORD(lpcmi->lpVerb) + FCIDM_BASE)
|
||||||
{
|
{
|
||||||
case FCIDM_SHVIEW_REFRESH:
|
case FCIDM_SHVIEW_REFRESH:
|
||||||
if (view) IShellView_Refresh(view);
|
if (view) IShellView_Refresh(view);
|
||||||
|
|
|
@ -4385,7 +4385,15 @@ static void test_contextmenu(IContextMenu *menu, BOOL background)
|
||||||
ok(hr == S_OK || hr == E_NOTIMPL || hr == E_INVALIDARG,
|
ok(hr == S_OK || hr == E_NOTIMPL || hr == E_INVALIDARG,
|
||||||
"Got unexpected hr %#x for ID %d, string %s.\n", hr, mii.wID, debugstr_a(mii.dwTypeData));
|
"Got unexpected hr %#x for ID %d, string %s.\n", hr, mii.wID, debugstr_a(mii.dwTypeData));
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
|
{
|
||||||
trace("Got ID %d, verb %s, string %s.\n", mii.wID, debugstr_a(buf), debugstr_a(mii.dwTypeData));
|
trace("Got ID %d, verb %s, string %s.\n", mii.wID, debugstr_a(buf), debugstr_a(mii.dwTypeData));
|
||||||
|
if (!strcmp(buf, "copy"))
|
||||||
|
ok(mii.wID == 64 - 0x7000 + FCIDM_SHVIEW_COPY, "wrong menu wID %d\n", mii.wID);
|
||||||
|
else if (!strcmp(buf, "paste"))
|
||||||
|
ok(mii.wID == 64 - 0x7000 + FCIDM_SHVIEW_INSERT, "wrong menu wID %d\n", mii.wID);
|
||||||
|
else if (!strcmp(buf, "properties"))
|
||||||
|
ok(mii.wID == 64 - 0x7000 + FCIDM_SHVIEW_PROPERTIES, "wrong menu wID %d\n", mii.wID);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
trace("Got ID %d, hr %#x, string %s.\n", mii.wID, hr, debugstr_a(mii.dwTypeData));
|
trace("Got ID %d, hr %#x, string %s.\n", mii.wID, hr, debugstr_a(mii.dwTypeData));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue