Skip to content

Commit f461ff0

Browse files
committed
Unfinished
1 parent 4575b08 commit f461ff0

File tree

5 files changed

+90
-35
lines changed

5 files changed

+90
-35
lines changed

src/Files.App.CsWin32/Extras.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ public static unsafe nint SetWindowLongPtr(HWND hWnd, WINDOW_LONG_PTR_INDEX nInd
4444
public const int PixelFormat32bppARGB = 2498570;
4545
}
4646

47+
namespace Foundation
48+
{
49+
public partial struct PCSTR
50+
{
51+
public static unsafe PCSTR FromString(string value)
52+
{
53+
fixed (byte* p = global::System.Text.Encoding.UTF8.GetBytes(value))
54+
{
55+
return new PCSTR(p);
56+
}
57+
}
58+
59+
public static unsafe PCSTR FromInt(int value)
60+
{
61+
return new PCSTR((byte*)&value);
62+
}
63+
}
64+
}
65+
4766
namespace Extras
4867
{
4968
[GeneratedComInterface, Guid("EACDD04C-117E-4E17-88F4-D1B12B0E3D89"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

src/Files.App.CsWin32/NativeMethods.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,8 @@ QITIPF_FLAGS
225225
GetKeyboardState
226226
MapVirtualKey
227227
GetKeyboardLayout
228+
MENUITEMINFO
229+
GetMenuItemCount
230+
GetMenuItemInfo
231+
IContextMenu2
232+
CreateMenu
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cb1ca000ef2f03f1afc7bde9ed4fb2987669c89a58b63919e67574696091f60f
1+
04fb6dcd84d19b858484bd1812b2361d06897f802eabaf430ec8799e1b3ca1f9

src/Files.App/Helpers/Win32/Win32Helper.Storage.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,37 @@ public static Task<bool> MountVhdDisk(string vhdPath)
602602
}
603603
}
604604

605+
public static Bitmap? GetBitmapFromHBitmap(Windows.Win32.Graphics.Gdi.HBITMAP hBitmap)
606+
{
607+
try
608+
{
609+
Bitmap bmp = Image.FromHbitmap((IntPtr)hBitmap);
610+
if (Image.GetPixelFormatSize(bmp.PixelFormat) < 32)
611+
return bmp;
612+
613+
Rectangle bmBounds = new Rectangle(0, 0, bmp.Width, bmp.Height);
614+
var bmpData = bmp.LockBits(bmBounds, ImageLockMode.ReadOnly, bmp.PixelFormat);
615+
616+
if (IsAlphaBitmap(bmpData))
617+
{
618+
var alpha = GetAlphaBitmapFromBitmapData(bmpData);
619+
620+
bmp.UnlockBits(bmpData);
621+
bmp.Dispose();
622+
623+
return alpha;
624+
}
625+
626+
bmp.UnlockBits(bmpData);
627+
628+
return bmp;
629+
}
630+
catch
631+
{
632+
return null;
633+
}
634+
}
635+
605636
public static Shell32.ITaskbarList4? CreateTaskbarObject()
606637
{
607638
try

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

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
using System.Drawing;
55
using System.Runtime.InteropServices;
6-
using Vanara.InteropServices;
7-
using Vanara.PInvoke;
8-
using Vanara.Windows.Shell;
96
using Windows.Win32;
107
using Windows.Win32.UI.WindowsAndMessaging;
8+
using Windows.Win32.UI.Shell;
9+
using Windows.Win32.Foundation;
10+
using Windows.Win32.Graphics.Gdi;
1111

1212
namespace Files.App.Utils.Shell
1313
{
@@ -16,9 +16,9 @@ namespace Files.App.Utils.Shell
1616
/// </summary>
1717
public partial class ContextMenu : Win32ContextMenu, IDisposable
1818
{
19-
private Shell32.IContextMenu _cMenu;
19+
private IContextMenu _cMenu;
2020

21-
private User32.SafeHMENU _hMenu;
21+
private HMENU _hMenu;
2222

2323
private readonly ThreadWithMessageQueue _owningThread;
2424

@@ -31,7 +31,7 @@ public partial class ContextMenu : Win32ContextMenu, IDisposable
3131

3232
public List<string> ItemsPath { get; }
3333

34-
private ContextMenu(Shell32.IContextMenu cMenu, User32.SafeHMENU hMenu, IEnumerable<string> itemsPath, ThreadWithMessageQueue owningThread, Func<string, bool>? itemFilter)
34+
private ContextMenu(IContextMenu cMenu, HMENU hMenu, IEnumerable<string> itemsPath, ThreadWithMessageQueue owningThread, Func<string, bool>? itemFilter)
3535
{
3636
_cMenu = cMenu;
3737
_hMenu = hMenu;
@@ -64,10 +64,10 @@ public async Task<bool> InvokeVerb(string? verb)
6464
{
6565
var currentWindows = Win32Helper.GetDesktopWindows();
6666

67-
var pici = new Shell32.CMINVOKECOMMANDINFOEX
67+
var pici = new CMINVOKECOMMANDINFO
6868
{
69-
lpVerb = new SafeResourceId(verb, CharSet.Ansi),
70-
nShow = ShowWindowCommand.SW_SHOWNORMAL,
69+
lpVerb = PCSTR.FromString(verb),
70+
nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL
7171
};
7272

7373
pici.cbSize = (uint)Marshal.SizeOf(pici);
@@ -93,15 +93,15 @@ public async Task<bool> InvokeItem(int itemID, string? workingDirectory = null)
9393
try
9494
{
9595
var currentWindows = Win32Helper.GetDesktopWindows();
96-
var pici = new Shell32.CMINVOKECOMMANDINFOEX
96+
var pici = new CMINVOKECOMMANDINFO
9797
{
98-
lpVerb = Macros.MAKEINTRESOURCE(itemID),
99-
nShow = ShowWindowCommand.SW_SHOWNORMAL,
98+
lpVerb = PCSTR.FromInt(itemID),
99+
nShow = (int)SHOW_WINDOW_CMD.SW_SHOWNORMAL,
100100
};
101101

102102
pici.cbSize = (uint)Marshal.SizeOf(pici);
103103
if (workingDirectory is not null)
104-
pici.lpDirectoryW = workingDirectory;
104+
pici.lpDirectory = PCSTR.FromString(workingDirectory);
105105

106106
await _owningThread.PostMethod(() => _cMenu.InvokeCommand(pici));
107107
Win32Helper.BringToForeground(currentWindows);
@@ -161,9 +161,9 @@ public async Task<bool> InvokeItem(int itemID, string? workingDirectory = null)
161161
// NOTE: The items are all in the same folder
162162
using var sf = shellItems[0].Parent;
163163

164-
Shell32.IContextMenu menu = sf.GetChildrenUIObjects<Shell32.IContextMenu>(default, shellItems);
165-
var hMenu = User32.CreatePopupMenu();
166-
menu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, (Shell32.CMF)flags);
164+
IContextMenu menu = sf.GetChildrenUIObjects<IContextMenu>(default, shellItems);
165+
var hMenu = PInvoke.CreatePopupMenu();
166+
menu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, flags);
167167
var contextMenu = new ContextMenu(menu, hMenu, shellItems.Select(x => x.ParsingName), owningThread, itemFilter);
168168
contextMenu.EnumMenuItems(hMenu, contextMenu.Items);
169169

@@ -181,34 +181,34 @@ public static async Task WarmUpQueryContextMenuAsync()
181181
using var cMenu = await GetContextMenuForFiles(new string[] { $@"{Constants.UserEnvironmentPaths.SystemDrivePath}\" }, PInvoke.CMF_NORMAL);
182182
}
183183

184-
private void EnumMenuItems(Vanara.PInvoke.HMENU hMenu, List<Win32ContextMenuItem> menuItemsResult, bool loadSubenus = false)
184+
private void EnumMenuItems(HMENU hMenu, List<Win32ContextMenuItem> menuItemsResult, bool loadSubenus = false)
185185
{
186-
var itemCount = User32.GetMenuItemCount(hMenu);
186+
var itemCount = PInvoke.GetMenuItemCount(hMenu);
187187

188-
var menuItemInfo = new User32.MENUITEMINFO()
188+
var menuItemInfo = new MENUITEMINFOW()
189189
{
190190
fMask =
191-
User32.MenuItemInfoMask.MIIM_BITMAP |
192-
User32.MenuItemInfoMask.MIIM_FTYPE |
193-
User32.MenuItemInfoMask.MIIM_STRING |
194-
User32.MenuItemInfoMask.MIIM_ID |
195-
User32.MenuItemInfoMask.MIIM_SUBMENU,
191+
MENU_ITEM_MASK.MIIM_BITMAP |
192+
MENU_ITEM_MASK.MIIM_FTYPE |
193+
MENU_ITEM_MASK.MIIM_STRING |
194+
MENU_ITEM_MASK.MIIM_ID |
195+
MENU_ITEM_MASK.MIIM_SUBMENU,
196196
};
197197

198198
menuItemInfo.cbSize = (uint)Marshal.SizeOf(menuItemInfo);
199199

200200
for (uint index = 0; index < itemCount; index++)
201201
{
202202
var menuItem = new ContextMenuItem();
203-
var container = new SafeCoTaskMemString(512);
204-
var cMenu2 = _cMenu as Shell32.IContextMenu2;
203+
var container = new Marshal.SafeCoTaskMemString(512);
204+
var cMenu2 = _cMenu as IContextMenu2;
205205

206206
menuItemInfo.dwTypeData = (IntPtr)container;
207207

208208
// See also, https://devblogs.microsoft.com/oldnewthing/20040928-00/?p=37723
209209
menuItemInfo.cch = (uint)container.Capacity - 1;
210210

211-
var result = User32.GetMenuItemInfo(hMenu, index, true, ref menuItemInfo);
211+
var result = PInvoke.GetMenuItemInfo(new , index, true, ref menuItemInfo);
212212
if (!result)
213213
{
214214
container.Dispose();
@@ -234,7 +234,7 @@ private void EnumMenuItems(Vanara.PInvoke.HMENU hMenu, List<Win32ContextMenuItem
234234
continue;
235235
}
236236

237-
if (menuItemInfo.hbmpItem != HBITMAP.NULL && !Enum.IsDefined(typeof(HBITMAP_HMENU), ((IntPtr)menuItemInfo.hbmpItem).ToInt64()))
237+
if (menuItemInfo.hbmpItem != HBITMAP.Null && !Enum.IsDefined(typeof(HBITMAP_HMENU), ((IntPtr)menuItemInfo.hbmpItem).ToInt64()))
238238
{
239239
using var bitmap = Win32Helper.GetBitmapFromHBitmap(menuItemInfo.hbmpItem);
240240

@@ -248,7 +248,7 @@ private void EnumMenuItems(Vanara.PInvoke.HMENU hMenu, List<Win32ContextMenuItem
248248
}
249249
}
250250

251-
if (menuItemInfo.hSubMenu != Vanara.PInvoke.HMENU.NULL)
251+
if (menuItemInfo.hSubMenu != HMENU.Null)
252252
{
253253
Debug.WriteLine("Item {0}: has submenu", index);
254254
var subItems = new List<Win32ContextMenuItem>();
@@ -267,7 +267,7 @@ void LoadSubMenu()
267267
{
268268
try
269269
{
270-
cMenu2?.HandleMenuMsg((uint)User32.WindowMessage.WM_INITMENUPOPUP, (IntPtr)hSubMenu, new IntPtr(index));
270+
cMenu2?.HandleMenuMsg(PInvoke.WM_INITMENUPOPUP, (IntPtr)hSubMenu, new IntPtr(index));
271271
}
272272
catch (Exception ex) when (ex is InvalidCastException or ArgumentException)
273273
{
@@ -316,7 +316,7 @@ public Task<bool> LoadSubMenu(List<Win32ContextMenuItem> subItems)
316316
}
317317
}
318318

319-
private static string? GetCommandString(Shell32.IContextMenu cMenu, uint offset, Shell32.GCS flags = Shell32.GCS.GCS_VERBW)
319+
private static string? GetCommandString(IContextMenu cMenu, uint offset, GCS flags = GCS.GCS_VERBW)
320320
{
321321
// A workaround to avoid an AccessViolationException on some items,
322322
// notably the "Run with graphic processor" menu item of NVIDIA cards
@@ -325,11 +325,11 @@ public Task<bool> LoadSubMenu(List<Win32ContextMenuItem> subItems)
325325
return null;
326326
}
327327

328-
SafeCoTaskMemString? commandString = null;
328+
PSTR? commandString = null;
329329

330330
try
331331
{
332-
commandString = new SafeCoTaskMemString(512);
332+
commandString = new PSTR(512);
333333
cMenu.GetCommandString(new IntPtr(offset), flags, IntPtr.Zero, commandString, (uint)commandString.Capacity - 1);
334334
Debug.WriteLine("Verb {0}: {1}", offset, commandString);
335335

@@ -374,7 +374,7 @@ protected virtual void Dispose(bool disposing)
374374
// TODO: Free unmanaged resources (unmanaged objects) and override a finalizer below
375375
if (_hMenu is not null)
376376
{
377-
User32.DestroyMenu(_hMenu);
377+
PInvoke.DestroyMenu(_hMenu);
378378
_hMenu = null;
379379
}
380380
if (_cMenu is not null)

0 commit comments

Comments
 (0)