mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to implement shell32 NewMenu class with new folder item.
This commit is contained in:
parent
67f1219393
commit
79253e6534
@ -39,12 +39,13 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [9]:**
|
||||
**Bug fixes and features included in the next upcoming release [10]:**
|
||||
|
||||
* Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699))
|
||||
* Catch invalid memory accesses in imagehlp.CheckSumMappedFile
|
||||
* Fix implementation of ntdll.MapViewOfSection
|
||||
* Implement enumeration of sound devices and basic properties to dxdiagn ([Wine Bug #32613](https://bugs.winehq.org/show_bug.cgi?id=32613))
|
||||
* Implement shell32 NewMenu class with new folder item ([Wine Bug #24812](https://bugs.winehq.org/show_bug.cgi?id=24812))
|
||||
* Implement special handling for calling GetChildContainer with an empty string ([Wine Bug #38014](https://bugs.winehq.org/show_bug.cgi?id=38014))
|
||||
* Implement vcomp locking functions ([Wine Bug #26688](https://bugs.winehq.org/show_bug.cgi?id=26688))
|
||||
* Improve startup performance by delaying font initialization
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -11,6 +11,7 @@ wine-staging (1.7.50) UNRELEASED; urgency=low
|
||||
(fixes Wine Staging Bug #401).
|
||||
* Added patch to set SFGAO_HASSUBFOLDER only when there are really subfolders.
|
||||
* Added patch to fix multiple uninitialized memory issues in wineserver.
|
||||
* Added patch to implement shell32 NewMenu class with new folder item.
|
||||
* Removed patch to move security cookie initialization from memory management
|
||||
to loader.
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Tue, 11 Aug 2015 06:12:14 +0200
|
||||
|
@ -229,6 +229,7 @@ patch_enable_all ()
|
||||
enable_shell32_File_Property_Dialog="$1"
|
||||
enable_shell32_IDragSourceHelper="$1"
|
||||
enable_shell32_Icons="$1"
|
||||
enable_shell32_NewMenu_Interface="$1"
|
||||
enable_shell32_Placeholder_Icons="$1"
|
||||
enable_shell32_Progress_Dialog="$1"
|
||||
enable_shell32_RunDLL_CallEntry16="$1"
|
||||
@ -777,6 +778,9 @@ patch_enable ()
|
||||
shell32-Icons)
|
||||
enable_shell32_Icons="$2"
|
||||
;;
|
||||
shell32-NewMenu_Interface)
|
||||
enable_shell32_NewMenu_Interface="$2"
|
||||
;;
|
||||
shell32-Placeholder_Icons)
|
||||
enable_shell32_Placeholder_Icons="$2"
|
||||
;;
|
||||
@ -4721,6 +4725,22 @@ if test "$enable_shell32_Icons" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset shell32-NewMenu_Interface
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#24812] Implement shell32 NewMenu class with new folder item
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/shell32/Makefile.in, dlls/shell32/shell32_classes.idl, dlls/shell32/shell32_main.h, dlls/shell32/shellnew.c,
|
||||
# | dlls/shell32/shellole.c, include/shlguid.h
|
||||
# |
|
||||
if test "$enable_shell32_NewMenu_Interface" -eq 1; then
|
||||
patch_apply shell32-NewMenu_Interface/0001-shell32-Implement-NewMenu-with-new-folder-item.patch
|
||||
(
|
||||
echo '+ { "Michael Müller", "shell32: Implement NewMenu with new folder item.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset shell32-Placeholder_Icons
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,647 @@
|
||||
From 0e08c56df7f0d6beefbf6726f9db0b5ad3541348 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sun, 16 Aug 2015 17:34:22 +0200
|
||||
Subject: shell32: Implement NewMenu with new folder item.
|
||||
|
||||
---
|
||||
dlls/shell32/Makefile.in | 1 +
|
||||
dlls/shell32/shell32_classes.idl | 5 +
|
||||
dlls/shell32/shell32_main.h | 1 +
|
||||
dlls/shell32/shellnew.c | 558 +++++++++++++++++++++++++++++++++++++++
|
||||
dlls/shell32/shellole.c | 1 +
|
||||
include/shlguid.h | 2 +
|
||||
6 files changed, 568 insertions(+)
|
||||
create mode 100644 dlls/shell32/shellnew.c
|
||||
|
||||
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
|
||||
index 038db7f..7b677ff 100644
|
||||
--- a/dlls/shell32/Makefile.in
|
||||
+++ b/dlls/shell32/Makefile.in
|
||||
@@ -32,6 +32,7 @@ C_SRCS = \
|
||||
shelldispatch.c \
|
||||
shellitem.c \
|
||||
shelllink.c \
|
||||
+ shellnew.c \
|
||||
shellole.c \
|
||||
shellord.c \
|
||||
shellpath.c \
|
||||
diff --git a/dlls/shell32/shell32_classes.idl b/dlls/shell32/shell32_classes.idl
|
||||
index f0131e7..0140fec 100644
|
||||
--- a/dlls/shell32/shell32_classes.idl
|
||||
+++ b/dlls/shell32/shell32_classes.idl
|
||||
@@ -76,6 +76,11 @@ coclass KnownFolderManager { interface IKnownFolderManager; }
|
||||
|
||||
[
|
||||
threading(apartment),
|
||||
+ uuid(d969a300-e7ff-11d0-a93b-00a0c90f2719)
|
||||
+] coclass NewMenu { interface IShellExtInit; }
|
||||
+
|
||||
+[
|
||||
+ threading(apartment),
|
||||
uuid(00bb2763-6a77-11d0-a535-00c04fd7d062)
|
||||
] coclass AutoComplete { interface IAutoComplete2; }
|
||||
|
||||
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
|
||||
index 492f79f..83c5655 100644
|
||||
--- a/dlls/shell32/shell32_main.h
|
||||
+++ b/dlls/shell32/shell32_main.h
|
||||
@@ -98,6 +98,7 @@ HRESULT WINAPI RecycleBin_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID
|
||||
HRESULT WINAPI QueryAssociations_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppOutput) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI KnownFolderManager_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
+HRESULT WINAPI NewMenu_Constructor(IUnknown *outer, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||
extern HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST, LPWSTR, UINT, int*) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
|
||||
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/shell32/shellnew.c b/dlls/shell32/shellnew.c
|
||||
new file mode 100644
|
||||
index 0000000..59e18d6
|
||||
--- /dev/null
|
||||
+++ b/dlls/shell32/shellnew.c
|
||||
@@ -0,0 +1,558 @@
|
||||
+/*
|
||||
+ * Copyright 2015 Michael Müller
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#define COBJMACROS
|
||||
+#define NONAMELESSUNION
|
||||
+
|
||||
+#include "wine/debug.h"
|
||||
+#include "winerror.h"
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+#include "winnls.h"
|
||||
+#include "winreg.h"
|
||||
+
|
||||
+#include "winuser.h"
|
||||
+#include "wingdi.h"
|
||||
+#include "shlobj.h"
|
||||
+#include "undocshell.h"
|
||||
+
|
||||
+#include "pidl.h"
|
||||
+#include "shell32_main.h"
|
||||
+#include "shlguid.h"
|
||||
+#include "shlwapi.h"
|
||||
+#include "shresdef.h"
|
||||
+#include "shellfolder.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ IShellExtInit IShellExtInit_iface;
|
||||
+ IContextMenu IContextMenu_iface;
|
||||
+ IContextMenu3 IContextMenu3_iface;
|
||||
+ IObjectWithSite IObjectWithSite_iface;
|
||||
+
|
||||
+ LONG ref;
|
||||
+ IUnknown *site;
|
||||
+ LPITEMIDLIST pidl;
|
||||
+ HICON icon_folder;
|
||||
+
|
||||
+ UINT folder_cmd;
|
||||
+} NewMenuImpl;
|
||||
+
|
||||
+static inline NewMenuImpl *impl_from_IShellExtInit(IShellExtInit *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, NewMenuImpl, IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static inline NewMenuImpl *impl_from_IContextMenu(IContextMenu *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, NewMenuImpl, IContextMenu_iface);
|
||||
+}
|
||||
+
|
||||
+static inline NewMenuImpl *impl_from_IContextMenu3(IContextMenu3 *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, NewMenuImpl, IContextMenu3_iface);
|
||||
+}
|
||||
+
|
||||
+static inline NewMenuImpl *impl_from_IObjectWithSite(IObjectWithSite *iface)
|
||||
+{
|
||||
+ return CONTAINING_RECORD(iface, NewMenuImpl, IObjectWithSite_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ExtInit_QueryInterface(IShellExtInit *iface, REFIID riid, void **ppv)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
|
||||
+ TRACE("(%p)->(%s)\n", This, debugstr_guid(riid));
|
||||
+
|
||||
+ *ppv = NULL;
|
||||
+
|
||||
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IShellExtInit))
|
||||
+ {
|
||||
+ *ppv = &This->IShellExtInit_iface;
|
||||
+ }
|
||||
+ else if (IsEqualIID(riid, &IID_IObjectWithSite))
|
||||
+ {
|
||||
+ *ppv = &This->IObjectWithSite_iface;
|
||||
+ }
|
||||
+ else if (IsEqualIID(riid, &IID_IContextMenu))
|
||||
+ {
|
||||
+ *ppv = &This->IContextMenu_iface;
|
||||
+ }
|
||||
+ else if (IsEqualIID(riid, &IID_IContextMenu3))
|
||||
+ {
|
||||
+ *ppv = &This->IContextMenu3_iface;
|
||||
+ }
|
||||
+
|
||||
+ if (*ppv)
|
||||
+ {
|
||||
+ IUnknown_AddRef((IUnknown *)*ppv);
|
||||
+ TRACE("-- Interface: (%p)->(%p)\n", ppv, *ppv);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ ERR("-- Interface: E_NOINTERFACE for %s\n", debugstr_guid(riid));
|
||||
+ return E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ExtInit_AddRef(IShellExtInit *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
|
||||
+ ULONG ref = InterlockedIncrement(&This->ref);
|
||||
+
|
||||
+ TRACE("(%p), new refcount=%i\n", iface, ref);
|
||||
+
|
||||
+ return ref;
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ExtInit_Release(IShellExtInit *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
|
||||
+ ULONG ref = InterlockedDecrement(&This->ref);
|
||||
+
|
||||
+ TRACE("(%p), new refcount=%i\n", iface, ref);
|
||||
+
|
||||
+ if (!ref)
|
||||
+ {
|
||||
+ if (This->site) IUnknown_Release(This->site);
|
||||
+ if (This->pidl) ILFree(This->pidl);
|
||||
+ HeapFree(GetProcessHeap(), 0, This);
|
||||
+ }
|
||||
+
|
||||
+ return ref;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ExtInit_Initialize(IShellExtInit *iface, LPCITEMIDLIST pidl, IDataObject *obj, HKEY key)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IShellExtInit(iface);
|
||||
+
|
||||
+ TRACE("(%p)->(%p, %p, %p)\n", This, pidl, obj, key );
|
||||
+
|
||||
+ if (!pidl)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ if (This->pidl) ILFree(This->pidl);
|
||||
+ This->pidl = ILClone(pidl);
|
||||
+ This->icon_folder = LoadImageW(shell32_hInstance, (LPCWSTR)MAKEINTRESOURCE(IDI_SHELL_FOLDER), IMAGE_ICON,
|
||||
+ GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static const IShellExtInitVtbl eivt =
|
||||
+{
|
||||
+ NewMenu_ExtInit_QueryInterface,
|
||||
+ NewMenu_ExtInit_AddRef,
|
||||
+ NewMenu_ExtInit_Release,
|
||||
+ NewMenu_ExtInit_Initialize
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
|
||||
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ObjectWithSite_AddRef(IObjectWithSite *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
|
||||
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ObjectWithSite_Release(IObjectWithSite *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
|
||||
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID iid, void **ppv)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
|
||||
+
|
||||
+ TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), ppv);
|
||||
+
|
||||
+ if (!This->site)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ return IUnknown_QueryInterface(This->site, iid, ppv);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *punk)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IObjectWithSite(iface);
|
||||
+
|
||||
+ TRACE("(%p)->(%p)\n", This, punk);
|
||||
+
|
||||
+ if (punk)
|
||||
+ IUnknown_AddRef(punk);
|
||||
+
|
||||
+ if (This->site)
|
||||
+ IUnknown_Release(This->site);
|
||||
+
|
||||
+ This->site = punk;
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static const IObjectWithSiteVtbl owsvt =
|
||||
+{
|
||||
+ NewMenu_ObjectWithSite_QueryInterface,
|
||||
+ NewMenu_ObjectWithSite_AddRef,
|
||||
+ NewMenu_ObjectWithSite_Release,
|
||||
+ NewMenu_ObjectWithSite_SetSite,
|
||||
+ NewMenu_ObjectWithSite_GetSite,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_QueryInterface(IContextMenu3 *iface, REFIID riid, void **ppv)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ContextMenu3_AddRef(IContextMenu3 *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ContextMenu3_Release(IContextMenu3 *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_GetCommandString(IContextMenu3 *iface, UINT_PTR cmd, UINT type,
|
||||
+ UINT *reserved, LPSTR name, UINT max_len)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+
|
||||
+ FIXME("(%p)->(%lu %u %p %p %u): stub\n", This, cmd, type, reserved, name, max_len);
|
||||
+
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT create_folder(NewMenuImpl *This, IShellView *view)
|
||||
+{
|
||||
+ IFolderView *folder_view = NULL;
|
||||
+ IShellFolder *desktop = NULL;
|
||||
+ IShellFolder *parent = NULL;
|
||||
+ ISFHelper *helper = NULL;
|
||||
+ LPITEMIDLIST pidl = NULL;
|
||||
+ WCHAR nameW[MAX_PATH];
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (view)
|
||||
+ {
|
||||
+ hr = IShellView_QueryInterface(view, &IID_IFolderView, (void **)&folder_view);
|
||||
+ if (FAILED(hr)) return hr;
|
||||
+
|
||||
+ hr = IFolderView_GetFolder(folder_view, &IID_IShellFolder, (void **)&parent);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ hr = SHGetDesktopFolder(&desktop);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+
|
||||
+ hr = IShellFolder_BindToObject(desktop, This->pidl, NULL, &IID_IShellFolder, (void **)&parent);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+ }
|
||||
+
|
||||
+ IShellFolder_QueryInterface(parent, &IID_ISFHelper, (void **)&helper);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+
|
||||
+ hr = ISFHelper_GetUniqueName(helper, nameW, MAX_PATH);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+
|
||||
+ hr = ISFHelper_AddFolder(helper, 0, nameW, &pidl);
|
||||
+ if (FAILED(hr)) goto out;
|
||||
+
|
||||
+ if (view)
|
||||
+ {
|
||||
+ IShellView_SelectItem(view, pidl, SVSI_DESELECTOTHERS | SVSI_EDIT |
|
||||
+ SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ if (pidl) SHFree(pidl);
|
||||
+ if (helper) ISFHelper_Release(helper);
|
||||
+ if (parent) IShellFolder_Release(parent);
|
||||
+ if (desktop) IShellFolder_Release(desktop);
|
||||
+ if (folder_view) IFolderView_Release(folder_view);
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_InvokeCommand(IContextMenu3 *iface, LPCMINVOKECOMMANDINFO info)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+ IShellBrowser *browser;
|
||||
+ IShellView *view = NULL;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ TRACE("(%p)->(%p)\n", This, info);
|
||||
+
|
||||
+ /* New Folder */
|
||||
+ if (info->lpVerb == 0)
|
||||
+ {
|
||||
+ if ((browser = (IShellBrowser *)SendMessageA(info->hwnd, CWM_GETISHELLBROWSER, 0, 0)))
|
||||
+ {
|
||||
+ if (FAILED(IShellBrowser_QueryActiveShellView(browser, &view)))
|
||||
+ view = NULL;
|
||||
+ }
|
||||
+ hr = create_folder(This, view);
|
||||
+ if (view) IShellView_Release(view);
|
||||
+ }
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+static UINT insert_new_menu_items(NewMenuImpl *This, HMENU menu, UINT pos, UINT cmd_first, UINT cmd_last)
|
||||
+{
|
||||
+ MENUITEMINFOW item;
|
||||
+ WCHAR buffer[256];
|
||||
+
|
||||
+ memset(&item, 0, sizeof(item));
|
||||
+ item.cbSize = sizeof(item);
|
||||
+
|
||||
+ if (cmd_first > cmd_last)
|
||||
+ return cmd_first;
|
||||
+
|
||||
+ /* FIXME: on windows it is only 'Folder' not 'New Folder' */
|
||||
+ if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, buffer, sizeof(buffer) / sizeof(WCHAR)))
|
||||
+ buffer[0] = 0;
|
||||
+
|
||||
+ item.fMask = MIIM_ID | MIIM_BITMAP | MIIM_STRING;
|
||||
+ item.dwTypeData = buffer;
|
||||
+ item.cch = strlenW(buffer);
|
||||
+ item.wID = cmd_first;
|
||||
+ item.hbmpItem = HBMMENU_CALLBACK;
|
||||
+ if (InsertMenuItemW(menu, pos, TRUE, &item))
|
||||
+ {
|
||||
+ This->folder_cmd = cmd_first++;
|
||||
+ pos++;
|
||||
+ }
|
||||
+
|
||||
+ return cmd_first;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_QueryContextMenu(IContextMenu3 *iface, HMENU menu, UINT index,
|
||||
+ UINT cmd_first, UINT cmd_last, UINT flags)
|
||||
+{
|
||||
+ static WCHAR newW[] = {'N','e','w',0};
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+ MENUITEMINFOW item;
|
||||
+ HMENU submenu;
|
||||
+ UINT id;
|
||||
+
|
||||
+ TRACE("(%p)->(%p, %u, %u, %u, %u)\n", This,
|
||||
+ menu, index, cmd_first, cmd_last, flags );
|
||||
+
|
||||
+ if (!This->pidl)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ submenu = CreateMenu();
|
||||
+ if (!submenu) return E_FAIL;
|
||||
+
|
||||
+ id = insert_new_menu_items(This, submenu, 0, cmd_first, cmd_last);
|
||||
+
|
||||
+ memset(&item, 0, sizeof(item));
|
||||
+ item.cbSize = sizeof(item);
|
||||
+ item.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
|
||||
+ item.fType = MFT_STRING;
|
||||
+ item.wID = -1;
|
||||
+ item.dwTypeData = newW; /* FIXME: load from resource file */
|
||||
+ item.cch = strlenW(newW);
|
||||
+ item.fState = MFS_ENABLED;
|
||||
+ item.hSubMenu = submenu;
|
||||
+
|
||||
+ if (!InsertMenuItemW(menu, index, TRUE, &item))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, id);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_HandleMenuMsg2(IContextMenu3 *iface, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *result)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu3(iface);
|
||||
+
|
||||
+ TRACE("(%p)->(%u, %lx, %lx, %p)\n", This, uMsg, wParam, lParam, result);
|
||||
+
|
||||
+ switch (uMsg)
|
||||
+ {
|
||||
+ case WM_MEASUREITEM:
|
||||
+ {
|
||||
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
|
||||
+ if (!mis || mis->CtlType != ODT_MENU)
|
||||
+ break;
|
||||
+
|
||||
+ if (This->folder_cmd == mis->itemID)
|
||||
+ {
|
||||
+ mis->itemWidth = GetSystemMetrics(SM_CXSMICON);
|
||||
+ mis->itemHeight = GetSystemMetrics(SM_CYSMICON);
|
||||
+ }
|
||||
+
|
||||
+ if (result) *result = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case WM_DRAWITEM:
|
||||
+ {
|
||||
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
|
||||
+ HICON icon = 0;
|
||||
+ UINT x, y;
|
||||
+
|
||||
+ if (!dis || dis->CtlType != ODT_MENU)
|
||||
+ break;
|
||||
+
|
||||
+ if (This->folder_cmd == dis->itemID)
|
||||
+ icon = This->icon_folder;
|
||||
+
|
||||
+ if (!icon)
|
||||
+ break;
|
||||
+
|
||||
+ x = (dis->rcItem.right - dis->rcItem.left - GetSystemMetrics(SM_CXSMICON)) / 2;
|
||||
+ y = (dis->rcItem.bottom - dis->rcItem.top - GetSystemMetrics(SM_CYSMICON)) / 2;
|
||||
+ DrawStateW(dis->hDC, NULL, NULL, (LPARAM)icon, 0, x, y, 0, 0, DST_ICON | DSS_NORMAL);
|
||||
+
|
||||
+ if (result) *result = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu3_HandleMenuMsg(IContextMenu3 *iface, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
+{
|
||||
+ return NewMenu_ContextMenu3_HandleMenuMsg2(iface, uMsg, wParam, lParam, NULL);
|
||||
+}
|
||||
+
|
||||
+static const IContextMenu3Vtbl cmvt3 =
|
||||
+{
|
||||
+ NewMenu_ContextMenu3_QueryInterface,
|
||||
+ NewMenu_ContextMenu3_AddRef,
|
||||
+ NewMenu_ContextMenu3_Release,
|
||||
+ NewMenu_ContextMenu3_QueryContextMenu,
|
||||
+ NewMenu_ContextMenu3_InvokeCommand,
|
||||
+ NewMenu_ContextMenu3_GetCommandString,
|
||||
+ NewMenu_ContextMenu3_HandleMenuMsg,
|
||||
+ NewMenu_ContextMenu3_HandleMenuMsg2
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu_QueryInterface(IContextMenu *iface, REFIID riid, void **ppv)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ExtInit_QueryInterface(&This->IShellExtInit_iface, riid, ppv);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ContextMenu_AddRef(IContextMenu *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ExtInit_AddRef(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static ULONG WINAPI
|
||||
+NewMenu_ContextMenu_Release(IContextMenu *iface)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ExtInit_Release(&This->IShellExtInit_iface);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu_QueryContextMenu(IContextMenu *iface, HMENU menu, UINT index,
|
||||
+ UINT cmd_first, UINT cmd_last, UINT flags)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ContextMenu3_QueryContextMenu(&This->IContextMenu3_iface, menu, index,
|
||||
+ cmd_first, cmd_last, flags);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu_InvokeCommand(IContextMenu *iface, LPCMINVOKECOMMANDINFO info)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ContextMenu3_InvokeCommand(&This->IContextMenu3_iface, info);
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI
|
||||
+NewMenu_ContextMenu_GetCommandString(IContextMenu *iface, UINT_PTR cmd, UINT type,
|
||||
+ UINT *reserved, LPSTR name, UINT max_len)
|
||||
+{
|
||||
+ NewMenuImpl *This = impl_from_IContextMenu(iface);
|
||||
+ return NewMenu_ContextMenu3_GetCommandString(&This->IContextMenu3_iface, cmd, type, reserved, name, max_len);
|
||||
+}
|
||||
+
|
||||
+static const IContextMenuVtbl cmvt =
|
||||
+{
|
||||
+ NewMenu_ContextMenu_QueryInterface,
|
||||
+ NewMenu_ContextMenu_AddRef,
|
||||
+ NewMenu_ContextMenu_Release,
|
||||
+ NewMenu_ContextMenu_QueryContextMenu,
|
||||
+ NewMenu_ContextMenu_InvokeCommand,
|
||||
+ NewMenu_ContextMenu_GetCommandString
|
||||
+};
|
||||
+
|
||||
+
|
||||
+HRESULT WINAPI NewMenu_Constructor(IUnknown *outer, REFIID riid, void **obj)
|
||||
+{
|
||||
+ NewMenuImpl *menu;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("outer=%p riid=%s\n", outer, debugstr_guid(riid));
|
||||
+
|
||||
+ *obj = NULL;
|
||||
+
|
||||
+ if (outer)
|
||||
+ return CLASS_E_NOAGGREGATION;
|
||||
+
|
||||
+ menu = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NewMenuImpl));
|
||||
+ if (!menu) return E_OUTOFMEMORY;
|
||||
+
|
||||
+ menu->ref = 1;
|
||||
+ menu->IShellExtInit_iface.lpVtbl = &eivt;
|
||||
+ menu->IContextMenu_iface.lpVtbl = &cmvt;
|
||||
+ menu->IContextMenu3_iface.lpVtbl = &cmvt3;
|
||||
+ menu->IObjectWithSite_iface.lpVtbl = &owsvt;
|
||||
+
|
||||
+ TRACE("(%p)\n", menu);
|
||||
+
|
||||
+ hr = IShellExtInit_QueryInterface(&menu->IShellExtInit_iface, riid, obj);
|
||||
+ IShellExtInit_Release(&menu->IShellExtInit_iface);
|
||||
+ return hr;
|
||||
+}
|
||||
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
|
||||
index 637a101..9c1df75 100644
|
||||
--- a/dlls/shell32/shellole.c
|
||||
+++ b/dlls/shell32/shellole.c
|
||||
@@ -83,6 +83,7 @@ static const struct {
|
||||
{&CLSID_ExplorerBrowser,ExplorerBrowser_Constructor},
|
||||
{&CLSID_KnownFolderManager, KnownFolderManager_Constructor},
|
||||
{&CLSID_Shell, IShellDispatch_Constructor},
|
||||
+ {&CLSID_NewMenu, NewMenu_Constructor},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
diff --git a/include/shlguid.h b/include/shlguid.h
|
||||
index 2279def..09aacc5 100644
|
||||
--- a/include/shlguid.h
|
||||
+++ b/include/shlguid.h
|
||||
@@ -146,6 +146,8 @@ DEFINE_GUID(CLSID_ProgressDialog, 0xf8383852, 0xfcd3, 0x11d1, 0xa6, 0xb9, 0x0, 0
|
||||
|
||||
DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00, 0xc0, 0x4f, 0x8e, 0xeb, 0x3e);
|
||||
|
||||
+DEFINE_GUID(CLSID_NewMenu, 0xd969a300, 0xe7ff, 0x11d0, 0xa9, 0x3b, 0x0, 0xa0, 0xc9, 0xf, 0x27, 0x19);
|
||||
+
|
||||
#define PSGUID_SHELLDETAILS {0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0}
|
||||
DEFINE_GUID(FMTID_ShellDetails, 0x28636aa6, 0x953d, 0x11d2, 0xb5, 0xd6, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0);
|
||||
#define PID_FINDDATA 0
|
||||
--
|
||||
2.5.0
|
||||
|
1
patches/shell32-NewMenu_Interface/definition
Normal file
1
patches/shell32-NewMenu_Interface/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [24812] Implement shell32 NewMenu class with new folder item
|
Loading…
Reference in New Issue
Block a user