https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fc6330a01a6fb40a497d9…
commit fc6330a01a6fb40a497d9d47c85b010279ed7e7c
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Wed Mar 5 13:41:02 2025 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Mar 5 13:41:02 2025 +0100
[SHDOCVW] Don't show create shortcut context menu item in Explorer tree (#7735)
---
dll/win32/shdocvw/CNSCBand.cpp | 1 +
dll/win32/shdocvw/utility.cpp | 52 +++++++++++++++++++++++++++++++++++++++---
dll/win32/shdocvw/utility.h | 2 ++
3 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/dll/win32/shdocvw/CNSCBand.cpp b/dll/win32/shdocvw/CNSCBand.cpp
index f653a1a043c..5e5894d84ed 100644
--- a/dll/win32/shdocvw/CNSCBand.cpp
+++ b/dll/win32/shdocvw/CNSCBand.cpp
@@ -992,6 +992,7 @@ LRESULT CNSCBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM
lParam, BOOL &b
hr = contextMenu->QueryContextMenu(menuTemp, 0, idCmdFirst, FCIDM_SHVIEWLAST,
cmf);
if (FAILED_UNEXPECTEDLY(hr))
return 0;
+ SHELL_RemoveVerb(contextMenu, idCmdFirst, menuTemp, L"link");
enum { flags = TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON };
UINT uCommand = ::TrackPopupMenu(menuTemp, flags, pt.x, pt.y, 0, m_hWnd, NULL);
diff --git a/dll/win32/shdocvw/utility.cpp b/dll/win32/shdocvw/utility.cpp
index d9453696d3d..018d1177fad 100644
--- a/dll/win32/shdocvw/utility.cpp
+++ b/dll/win32/shdocvw/utility.cpp
@@ -10,9 +10,25 @@
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
-#ifndef SHCIDS_CANONICALONLY
-#define SHCIDS_CANONICALONLY 0x10000000L
-#endif
+static inline INT_PTR
+GetMenuItemIdByPos(HMENU hMenu, UINT Pos)
+{
+ MENUITEMINFOW mii;
+ mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */
+ mii.fMask = MIIM_ID; /* GetMenuItemID does not handle sub-menus, this does */
+ mii.cch = 0;
+ return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) ? mii.wID : -1;
+}
+
+static inline BOOL
+IsMenuSeparator(HMENU hMenu, UINT Pos)
+{
+ MENUITEMINFOW mii;
+ mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); /* USER32 version agnostic */
+ mii.fMask = MIIM_FTYPE;
+ mii.cch = 0;
+ return GetMenuItemInfoW(hMenu, Pos, TRUE, &mii) && (mii.fType &
MFT_SEPARATOR);
+}
EXTERN_C HRESULT
SHELL_GetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl)
@@ -71,6 +87,36 @@ SHELL_IsVerb(IContextMenu *pcm, UINT_PTR idCmd, LPCWSTR Verb)
return FALSE;
}
+static int
+SHELL_FindVerbPos(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR Verb)
+{
+ for (UINT i = 0, c = GetMenuItemCount(hMenu); i < c; ++i)
+ {
+ INT_PTR id = GetMenuItemIdByPos(hMenu, i);
+ if (id != -1 && SHELL_IsVerb(pcm, id - idCmdFirst, Verb))
+ return i;
+ }
+ return -1;
+}
+
+EXTERN_C VOID
+SHELL_RemoveVerb(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR Verb)
+{
+ int nPos = SHELL_FindVerbPos(pcm, idCmdFirst, hMenu, Verb);
+ if (nPos < 0)
+ return;
+ int nCount = GetMenuItemCount(hMenu);
+ BOOL bSepBefore = nPos && IsMenuSeparator(hMenu, nPos - 1);
+ BOOL bSepAfter = IsMenuSeparator(hMenu, nPos + 1);
+ if (DeleteMenu(hMenu, nPos, MF_BYPOSITION))
+ {
+ if ((bSepBefore && bSepAfter) || (bSepAfter && nPos == 0))
+ DeleteMenu(hMenu, nPos, MF_BYPOSITION);
+ else if (bSepBefore && nPos + 1 == nCount)
+ DeleteMenu(hMenu, nPos - 1, MF_BYPOSITION);
+ }
+}
+
EXTERN_C BOOL
_ILIsDesktop(LPCITEMIDLIST pidl)
{
diff --git a/dll/win32/shdocvw/utility.h b/dll/win32/shdocvw/utility.h
index 46399da02f1..3368ecc7356 100644
--- a/dll/win32/shdocvw/utility.h
+++ b/dll/win32/shdocvw/utility.h
@@ -10,4 +10,6 @@
EXTERN_C HRESULT SHELL_GetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl);
EXTERN_C BOOL SHELL_IsEqualAbsoluteID(PCIDLIST_ABSOLUTE a, PCIDLIST_ABSOLUTE b);
EXTERN_C BOOL SHELL_IsVerb(IContextMenu *pcm, UINT_PTR idCmd, LPCWSTR Verb);
+EXTERN_C VOID SHELL_RemoveVerb(IContextMenu *pcm, UINT idCmdFirst, HMENU hMenu, LPCWSTR
Verb);
EXTERN_C BOOL _ILIsDesktop(LPCITEMIDLIST pidl);
+