From: Zebediah Figura zfigura@codeweavers.com
--- dlls/shell32/new_menu.c | 47 +++++++++++++++++++++++++++++++++--- dlls/shell32/shell32.rc | 2 ++ dlls/shell32/shell32_main.c | 13 ++++++++++ dlls/shell32/shell32_main.h | 2 ++ dlls/shell32/shlview_cmenu.c | 10 +------- dlls/shell32/shresdef.h | 2 ++ 6 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/dlls/shell32/new_menu.c b/dlls/shell32/new_menu.c index 87ea93f9964..6a4d54e1b73 100644 --- a/dlls/shell32/new_menu.c +++ b/dlls/shell32/new_menu.c @@ -20,6 +20,10 @@
#include "shobjidl.h"
+#include "shell32_main.h" +#include "shresdef.h" +#include "pidl.h" + #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell); @@ -30,6 +34,8 @@ struct new_menu IContextMenu3 IContextMenu3_iface; IObjectWithSite IObjectWithSite_iface; LONG refcount; + + ITEMIDLIST *pidl; };
static struct new_menu *impl_from_IShellExtInit(IShellExtInit *iface) @@ -80,7 +86,10 @@ static ULONG WINAPI ext_init_Release(IShellExtInit *iface) TRACE("%p decreasing refcount to %lu.\n", menu, refcount);
if (!refcount) + { + ILFree(menu->pidl); free(menu); + }
return refcount; } @@ -91,6 +100,10 @@ static HRESULT WINAPI ext_init_Initialize(IShellExtInit *iface, LPCITEMIDLIST pi
TRACE("menu %p, pidl %p, obj %p, key %p.\n", menu, pidl, obj, key);
+ if (!pidl) + return E_INVALIDARG; + + menu->pidl = ILClone(pidl); return S_OK; }
@@ -131,10 +144,36 @@ static ULONG WINAPI context_menu_Release(IContextMenu3 *iface) static HRESULT WINAPI context_menu_QueryContextMenu(IContextMenu3 *iface, HMENU hmenu, UINT index, UINT min_id, UINT max_id, UINT flags) { - FIXME("iface %p, hmenu %p, index %u, min_id %u, max_id %u, flags %#x, stub!\n", - iface, hmenu, index, min_id, max_id, flags); + struct new_menu *menu = impl_from_IContextMenu3(iface); + MENUITEMINFOW info; + WCHAR *new_string; + HMENU submenu;
- return E_NOTIMPL; + TRACE("menu %p, hmenu %p, index %u, min_id %u, max_id %u, flags %#x.\n", + menu, hmenu, index, min_id, max_id, flags); + + if (!_ILIsFolder(ILFindLastID(menu->pidl)) && !_ILIsDrive(ILFindLastID(menu->pidl))) + { + TRACE("Not returning a New item for this pidl type.\n"); + return S_OK; + } + + submenu = CreatePopupMenu(); + new_string = shell_get_resource_string(IDS_NEW_MENU); + + info.cbSize = sizeof(info); + info.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU; + info.dwTypeData = new_string; + info.fState = MFS_ENABLED; + info.wID = min_id; + info.fType = MFT_STRING; + info.hSubMenu = submenu; + InsertMenuItemW(hmenu, 0, MF_BYPOSITION, &info); + + free(new_string); + + /* Native doesn't return the highest ID; it instead just returns 0x40. */ + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0x40); }
static HRESULT WINAPI context_menu_InvokeCommand(IContextMenu3 *iface, CMINVOKECOMMANDINFO *info) @@ -238,7 +277,7 @@ HRESULT WINAPI new_menu_create(IUnknown *outer, REFIID iid, void **out) if (outer) return CLASS_E_NOAGGREGATION;
- if (!(menu = malloc(sizeof(*menu)))) + if (!(menu = calloc(1, sizeof(*menu)))) return E_OUTOFMEMORY;
menu->IShellExtInit_iface.lpVtbl = &ext_init_vtbl; diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc index a50fab6815d..d70e4cc3ad9 100644 --- a/dlls/shell32/shell32.rc +++ b/dlls/shell32/shell32.rc @@ -157,6 +157,8 @@ STRINGTABLE IDS_VIEW_LIST "&List" IDS_VIEW_DETAILS "&Details"
+ IDS_NEW_MENU "Ne&w" + IDS_VERB_EXPLORE "E&xplore" IDS_VERB_OPEN "&Open" IDS_VERB_PRINT "&Print" diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index 847587c70c9..c739e1723f7 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -1137,6 +1137,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) return TRUE; }
+WCHAR *shell_get_resource_string(UINT id) +{ + const WCHAR *resource; + unsigned int size; + WCHAR *ret; + + size = LoadStringW(shell32_hInstance, id, (WCHAR *)&resource, 0); + ret = malloc((size + 1) * sizeof(WCHAR)); + memcpy(ret, resource, size * sizeof(WCHAR)); + ret[size] = 0; + return ret; +} + /************************************************************************* * DllInstall [SHELL32.@] * diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index 52c7d44f39f..f6fea65344d 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -273,4 +273,6 @@ typedef struct BOOL WINAPI StrRetToStrNA(char *, DWORD, STRRET *, const ITEMIDLIST *); BOOL WINAPI StrRetToStrNW(WCHAR *, DWORD, STRRET *, const ITEMIDLIST *);
+WCHAR *shell_get_resource_string(UINT id); + #endif diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index a5592d3c830..4df296ec042 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -1030,15 +1030,7 @@ static WCHAR *get_verb_desc(HKEY key, const WCHAR *verb) for (unsigned int i = 0; i < ARRAY_SIZE(builtin_verbs); ++i) { if (!wcscmp(verb, builtin_verbs[i].verb)) - { - const WCHAR *resource; - - size = LoadStringW(shell32_hInstance, builtin_verbs[i].id, (WCHAR *)&resource, 0); - desc = malloc((size + 1) * sizeof(WCHAR)); - memcpy(desc, resource, size * sizeof(WCHAR)); - desc[size] = 0; - return desc; - } + return shell_get_resource_string(builtin_verbs[i].id); }
return wcsdup(verb); diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h index 6aac654568e..58a1c07fa05 100644 --- a/dlls/shell32/shresdef.h +++ b/dlls/shell32/shresdef.h @@ -54,6 +54,8 @@ #define IDS_VIEW_LIST 27 #define IDS_VIEW_DETAILS 28
+#define IDS_NEW_MENU 29 + #define IDS_VERB_EXPLORE 30 #define IDS_VERB_OPEN 31 #define IDS_VERB_PRINT 32