Skip to content

Commit 942dd94

Browse files
committed
Updated
1 parent ab66a18 commit 942dd94

11 files changed

+90
-31
lines changed

src/Files.App.Storage/Storables/WindowsStorage/ContextMenuType.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ namespace Files.App.Storage
55
{
66
public enum ContextMenuType
77
{
8-
Enabled = 0x00000000,
9-
Unchecked = 0x00000000,
10-
Unhighlighted = 0x00000000,
8+
Normal = 0x00000000,
119

12-
Grayed = 0x00000003,
1310
Disabled = 0x00000003,
1411

1512
Checked = 0x00000008,

src/Files.App.Storage/Storables/WindowsStorage/ShellNewItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Files.App.Storage
88
/// </summary>
99
public partial class ShellNewItem
1010
{
11-
public ContextMenuType Type { get; set; } = ContextMenuType.Enabled;
11+
public ContextMenuType Type { get; set; } = ContextMenuType.Normal;
1212

1313
public uint Id { get; set; }
1414

src/Files.App.Storage/Storables/WindowsStorage/WindowsFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Files.App.Storage
99
{
1010
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
11-
public unsafe sealed class WindowsFile : WindowsStorable, IChildFile
11+
public unsafe class WindowsFile : WindowsStorable, IChildFile
1212
{
1313
public WindowsFile(IShellItem* ptr)
1414
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsFolder.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using System.Runtime.CompilerServices;
45
using Windows.Win32;
56
using Windows.Win32.Foundation;
67
using Windows.Win32.System.SystemServices;
@@ -9,8 +10,26 @@
910
namespace Files.App.Storage
1011
{
1112
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
12-
public unsafe sealed class WindowsFolder : WindowsStorable, IChildFolder
13+
public unsafe class WindowsFolder : WindowsStorable, IChildFolder
1314
{
15+
internal IContextMenu* NewMenuPtr
16+
{
17+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
18+
get;
19+
20+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
21+
set;
22+
}
23+
24+
internal IContextMenu* ContextMenuPtr
25+
{
26+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
27+
get;
28+
29+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
30+
set;
31+
}
32+
1433
public WindowsFolder(IShellItem* ptr)
1534
{
1635
ThisPtr = ptr;

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Icon.cs renamed to src/Files.App.Storage/Storables/WindowsStorage/WindowsStorageHelpers.Icon.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
namespace Files.App.Storage
1515
{
16-
public static partial class WindowsStorableHelpers
16+
public static partial class WindowsStorageHelpers
1717
{
1818
// Fields
1919

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.PowerShell.cs renamed to src/Files.App.Storage/Storables/WindowsStorage/WindowsStorageHelpers.PowerShell.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Files.App.Storage
55
{
6-
public static partial class WindowsStorableHelpers
6+
public static partial class WindowsStorageHelpers
77
{
88
public static async Task<bool> TrySetShortcutIconOnPowerShellAsElevatedAsync(this IWindowsStorable storable, IWindowsStorable iconFile, int index)
99
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Registry.cs renamed to src/Files.App.Storage/Storables/WindowsStorage/WindowsStorageHelpers.Registry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Files.App.Storage
1212
{
13-
public unsafe static partial class WindowsStorableHelpers
13+
public unsafe static partial class WindowsStorageHelpers
1414
{
1515
public static bool OpenRegistryKey(HKEY hRootKey, string subKey, REG_SAM_FLAGS flags, out HKEY hKey)
1616
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Shell.cs renamed to src/Files.App.Storage/Storables/WindowsStorage/WindowsStorageHelpers.Shell.cs

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
namespace Files.App.Storage
1717
{
18-
public unsafe static partial class WindowsStorableHelpers
18+
public unsafe static partial class WindowsStorageHelpers
1919
{
2020
public unsafe static HRESULT GetPropertyValue<TValue>(this IWindowsStorable storable, string propKey, out TValue value)
2121
{
@@ -149,33 +149,56 @@ public unsafe static HRESULT TryGetShellTooltip(this IWindowsStorable storable,
149149

150150
public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable storable)
151151
{
152+
if (storable is not WindowsFolder folder)
153+
return [];
154+
152155
HRESULT hr = default;
153156

154-
using ComPtr<IContextMenu> pNewMenu = default;
157+
IContextMenu* pNewMenu = default;
155158
using ComPtr<IShellExtInit> pShellExtInit = default;
156159
using ComPtr<IContextMenu2> pContextMenu2 = default;
157160

158-
// Instantiate CNewMenu as IContextMenu, IContextMenu2, and IShellExtInit
159-
hr = PInvoke.CoCreateInstance(CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IContextMenu, (void**)pNewMenu.GetAddressOf());
160-
hr = pNewMenu.Get()->QueryInterface(IID.IID_IContextMenu2, (void**)pContextMenu2.GetAddressOf());
161-
hr = pNewMenu.Get()->QueryInterface(IID.IID_IShellExtInit, (void**)pShellExtInit.GetAddressOf());
161+
hr = PInvoke.CoCreateInstance(CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IContextMenu, (void**)&pNewMenu);
162+
if (hr.ThrowIfFailedOnDebug().Failed)
163+
return [];
164+
165+
hr = pNewMenu->QueryInterface(IID.IID_IContextMenu2, (void**)pContextMenu2.GetAddressOf());
166+
if (hr.ThrowIfFailedOnDebug().Failed)
167+
return [];
168+
169+
hr = pNewMenu->QueryInterface(IID.IID_IShellExtInit, (void**)pShellExtInit.GetAddressOf());
170+
if (hr.ThrowIfFailedOnDebug().Failed)
171+
return [];
172+
173+
folder.NewMenuPtr = pNewMenu;
162174

163-
// Initialize CNewMenu with the PIDL of the folder
164175
ITEMIDLIST* pFolderPidl = default;
165176
hr = PInvoke.SHGetIDListFromObject((IUnknown*)storable.ThisPtr, &pFolderPidl);
177+
if (hr.ThrowIfFailedOnDebug().Failed)
178+
return [];
179+
166180
hr = pShellExtInit.Get()->Initialize(pFolderPidl, null, default);
181+
if (hr.ThrowIfFailedOnDebug().Failed)
182+
return [];
167183

168184
// Inserts "New (&W)"
169185
HMENU hMenu = PInvoke.CreatePopupMenu();
170-
hr = pNewMenu.Get()->QueryContextMenu(hMenu, 0, 1, 256, 0);
186+
hr = pNewMenu->QueryContextMenu(hMenu, 0, 1, 256, 0);
187+
if (hr.ThrowIfFailedOnDebug().Failed)
188+
return [];
171189

172190
// Invokes CNewMenu::_InitMenuPopup(), which populates the hSubMenu
173191
HMENU hSubMenu = PInvoke.GetSubMenu(hMenu, 0);
174192
hr = pContextMenu2.Get()->HandleMenuMsg(PInvoke.WM_INITMENUPOPUP, (WPARAM)(nuint)hSubMenu.Value, 0);
193+
if (hr.ThrowIfFailedOnDebug().Failed)
194+
return [];
175195

176-
// Enumerate and populate the list
196+
uint dwCount = unchecked((uint)PInvoke.GetMenuItemCount(hSubMenu));
197+
if (dwCount is unchecked((uint)-1))
198+
return [];
199+
200+
// Enumerates and populates the list
177201
List<ShellNewItem> shellNewItems = [];
178-
uint dwCount = (uint)PInvoke.GetMenuItemCount(hSubMenu);
179202
for (uint dwIndex = 0; dwIndex < dwCount; dwIndex++)
180203
{
181204
MENUITEMINFOW mii = default;
@@ -186,8 +209,6 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
186209

187210
if (PInvoke.GetMenuItemInfo(hSubMenu, dwIndex, true, &mii))
188211
{
189-
Console.WriteLine($"{dwIndex:X}: {mii.wID:X}, {mii.fState}, {mii.dwTypeData}");
190-
191212
shellNewItems.Add(new()
192213
{
193214
Id = mii.wID,
@@ -201,5 +222,33 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
201222

202223
return shellNewItems;
203224
}
225+
226+
public static bool InvokeShellNewItem(this IWindowsStorable storable, ShellNewItem item)
227+
{
228+
if (storable is not WindowsFolder folder)
229+
return false;
230+
231+
HRESULT hr = default;
232+
233+
CMINVOKECOMMANDINFO cmici = default;
234+
cmici.cbSize = (uint)sizeof(CMINVOKECOMMANDINFO);
235+
cmici.lpVerb = (PCSTR)(byte*)item.Id;
236+
cmici.nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL;
237+
238+
if (folder.NewMenuPtr is null)
239+
{
240+
IContextMenu* pNewMenu = default;
241+
242+
hr = PInvoke.CoCreateInstance(CLSID.CLSID_NewMenu, null, CLSCTX.CLSCTX_INPROC_SERVER, IID.IID_IContextMenu, (void**)&pNewMenu);
243+
if (hr.ThrowIfFailedOnDebug().Failed)
244+
return false;
245+
246+
folder.NewMenuPtr = pNewMenu;
247+
}
248+
249+
folder.NewMenuPtr->InvokeCommand(&cmici);
250+
251+
return false;
252+
}
204253
}
205254
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Storage.cs renamed to src/Files.App.Storage/Storables/WindowsStorage/WindowsStorageHelpers.Storage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Files.App.Storage
1010
{
11-
public unsafe static partial class WindowsStorableHelpers
11+
public unsafe static partial class WindowsStorageHelpers
1212
{
1313
public static bool TryGetFileAttributes(this IWindowsStorable storable, out FILE_FLAGS_AND_ATTRIBUTES attributes)
1414
{

src/Files.App/Extensions/ShellNewEntryExtensions.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4-
using Files.App.Utils;
5-
using Files.App.Helpers;
6-
using Files.App.Utils.Shell;
7-
using Files.Shared;
8-
using Files.Shared.Extensions;
9-
using System;
10-
using System.Collections.Generic;
114
using System.IO;
12-
using System.Threading.Tasks;
135
using Windows.Storage;
146

157
namespace Files.App.Extensions
168
{
9+
[Obsolete($"Use {nameof(WindowsStorageHelpers.GetShellNewItems())} instead.")]
1710
public static class ShellNewEntryExtensions
1811
{
1912
public static async Task<List<ShellNewEntry>> GetNewContextMenuEntries()

src/Files.App/Utils/Shell/ShellNewMenuHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace Files.App.Utils.Shell
1212
/// <summary>
1313
/// Provides static helper to get extension-specific shell context menu from Windows Registry.
1414
/// </summary>
15+
[Obsolete($"Use {nameof(WindowsStorageHelpers.GetShellNewItems())} instead.")]
1516
public static class ShellNewMenuHelper
1617
{
1718
public static async Task<List<ShellNewEntry>> GetNewContextMenuEntries()

0 commit comments

Comments
 (0)