Skip to content

Code Quality: Replace Vanara with CsWin32 #16536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/Files.App.CsWin32/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ BHID_SFUIObject
IContextMenu
CMF_NORMAL
CMF_OPTIMIZEFORINVOKE
CMF_EXTENDEDVERBS
CMF_DEFAULTONLY
IApplicationDestinations
ApplicationDestinations
IApplicationDocumentLists
ApplicationDocumentLists
IApplicationActivationManager
MENU_ITEM_TYPE
18 changes: 9 additions & 9 deletions src/Files.App/Data/Factories/ShellContextFlyoutHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using System.IO;
using Vanara.PInvoke;
using Windows.System;
using Windows.UI.Core;
using static Vanara.PInvoke.Kernel32;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;

namespace Files.App.Helpers
{
Expand Down Expand Up @@ -55,7 +55,7 @@ bool filterMenuItemsImpl(string menuItem) => !string.IsNullOrEmpty(menuItem)
}

var contextMenu = await ContextMenu.GetContextMenuForFiles(filePaths,
shiftPressed ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL, FilterMenuItems(showOpenMenu));
shiftPressed ? PInvoke.CMF_EXTENDEDVERBS : PInvoke.CMF_NORMAL, FilterMenuItems(showOpenMenu));

if (contextMenu is not null)
LoadMenuFlyoutItem(menuItemsList, contextMenu, contextMenu.Items, cancellationToken, true);
Expand All @@ -78,10 +78,10 @@ private static void LoadMenuFlyoutItem(
return;

var itemsCount = 0; // Separators do not count for reaching the overflow threshold
var menuItems = menuFlyoutItems.TakeWhile(x => x.Type == MenuItemType.MFT_SEPARATOR || ++itemsCount <= itemsBeforeOverflow).ToList();
var menuItems = menuFlyoutItems.TakeWhile(x => x.Type == MENU_ITEM_TYPE.MFT_SEPARATOR || ++itemsCount <= itemsBeforeOverflow).ToList();
var overflowItems = menuFlyoutItems.Except(menuItems).ToList();

if (overflowItems.Any(x => x.Type != MenuItemType.MFT_SEPARATOR))
if (overflowItems.Any(x => x.Type != MENU_ITEM_TYPE.MFT_SEPARATOR))
{
var moreItem = menuItemsListLocal.FirstOrDefault(x => x.ID == "ItemOverflow");
if (moreItem is null)
Expand All @@ -101,15 +101,15 @@ private static void LoadMenuFlyoutItem(
}

foreach (var menuFlyoutItem in menuItems
.SkipWhile(x => x.Type == MenuItemType.MFT_SEPARATOR) // Remove leading separators
.SkipWhile(x => x.Type == MENU_ITEM_TYPE.MFT_SEPARATOR) // Remove leading separators
.Reverse()
.SkipWhile(x => x.Type == MenuItemType.MFT_SEPARATOR)) // Remove trailing separators
.SkipWhile(x => x.Type == MENU_ITEM_TYPE.MFT_SEPARATOR)) // Remove trailing separators
{
if (cancellationToken.IsCancellationRequested)
break;

// Avoid duplicate separators
if ((menuFlyoutItem.Type == MenuItemType.MFT_SEPARATOR) && (menuItemsListLocal.FirstOrDefault()?.ItemType == ContextMenuFlyoutItemType.Separator))
if ((menuFlyoutItem.Type == MENU_ITEM_TYPE.MFT_SEPARATOR) && (menuItemsListLocal.FirstOrDefault()?.ItemType == ContextMenuFlyoutItemType.Separator))
continue;

BitmapImage? image = null;
Expand All @@ -120,7 +120,7 @@ private static void LoadMenuFlyoutItem(
image.SetSourceAsync(ms.AsRandomAccessStream()).AsTask().Wait(10);
}

if (menuFlyoutItem.Type is MenuItemType.MFT_SEPARATOR)
if (menuFlyoutItem.Type is MENU_ITEM_TYPE.MFT_SEPARATOR)
{
var menuLayoutItem = new ContextMenuFlyoutItemViewModel()
{
Expand Down
18 changes: 3 additions & 15 deletions src/Files.App/Data/Items/ContextMenu.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.

using Windows.Win32.UI.WindowsAndMessaging;

namespace Files.App.Data.Items
{
// Same definition of Vanara.PInvoke.User32.MenuItemType
public enum MenuItemType : uint
{
MFT_STRING = 0,
MFT_BITMAP = 4,
MFT_MENUBARBREAK = 32,
MFT_MENUBREAK = 64,
MFT_OWNERDRAW = 256,
MFT_RADIOCHECK = 512,
MFT_SEPARATOR = 2048,
MFT_RIGHTORDER = 8192,
MFT_RIGHTJUSTIFY = 16384
}

public enum HBITMAP_HMENU : long
{
HBMMENU_CALLBACK = -1,
Expand All @@ -43,7 +31,7 @@ public class Win32ContextMenuItem
public int ID { get; set; } // Valid only in current menu to invoke item
public string Label { get; set; }
public string CommandString { get; set; }
public MenuItemType Type { get; set; }
public MENU_ITEM_TYPE Type { get; set; }
public List<Win32ContextMenuItem> SubItems { get; set; }
}
}
13 changes: 6 additions & 7 deletions src/Files.App/UserControls/FilePreviews/ShellPreview.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Files.App.ViewModels.Previews;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Vanara.PInvoke;
using Windows.Foundation;

namespace Files.App.UserControls.FilePreviews
Expand Down Expand Up @@ -32,17 +31,17 @@ private void PreviewHost_SizeChanged(object sender, SizeChangedEventArgs e)
ViewModel.SizeChanged(GetPreviewSize());
}

private RECT GetPreviewSize()
private Rect GetPreviewSize()
{
var source = contentPresenter.TransformToVisual(XamlRoot.Content);
var physicalSize = contentPresenter.RenderSize;
var physicalPos = source.TransformPoint(new Point(0, 0));
var scale = XamlRoot.RasterizationScale;
var result = new RECT();
result.Left = (int)(physicalPos.X * scale + 0.5);
result.Top = (int)(physicalPos.Y * scale + 0.5);
result.Width = (int)(physicalSize.Width * scale + 0.5);
result.Height = (int)(physicalSize.Height * scale + 0.5);
var result = new Rect();
result.X = physicalPos.X * scale + 0.5;
result.Y = physicalPos.Y * scale + 0.5;
result.Width = physicalSize.Width * scale + 0.5;
result.Height = physicalSize.Height * scale + 0.5;
return result;
}

Expand Down
22 changes: 12 additions & 10 deletions src/Files.App/Utils/Shell/ContextMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Vanara.InteropServices;
using Vanara.PInvoke;
using Vanara.Windows.Shell;
using Windows.Win32;
using Windows.Win32.UI.WindowsAndMessaging;

namespace Files.App.Utils.Shell
{
Expand Down Expand Up @@ -43,7 +45,7 @@ private ContextMenu(Shell32.IContextMenu cMenu, User32.SafeHMENU hMenu, IEnumera

public async static Task<bool> InvokeVerb(string verb, params string[] filePaths)
{
using var cMenu = await GetContextMenuForFiles(filePaths, Shell32.CMF.CMF_DEFAULTONLY);
using var cMenu = await GetContextMenuForFiles(filePaths, PInvoke.CMF_DEFAULTONLY);

return cMenu is not null && await cMenu.InvokeVerb(verb);
}
Expand Down Expand Up @@ -112,7 +114,7 @@ public async Task<bool> InvokeItem(int itemID)
return false;
}

public async static Task<ContextMenu?> GetContextMenuForFiles(string[] filePathList, Shell32.CMF flags, Func<string, bool>? itemFilter = null)
public async static Task<ContextMenu?> GetContextMenuForFiles(string[] filePathList, uint flags, Func<string, bool>? itemFilter = null)
{
var owningThread = new ThreadWithMessageQueue();

Expand Down Expand Up @@ -140,14 +142,14 @@ public async Task<bool> InvokeItem(int itemID)
});
}

public async static Task<ContextMenu?> GetContextMenuForFiles(ShellItem[] shellItems, Shell32.CMF flags, Func<string, bool>? itemFilter = null)
public async static Task<ContextMenu?> GetContextMenuForFiles(ShellItem[] shellItems, uint flags, Func<string, bool>? itemFilter = null)
{
var owningThread = new ThreadWithMessageQueue();

return await owningThread.PostMethod<ContextMenu>(() => GetContextMenuForFiles(shellItems, flags, owningThread, itemFilter));
}

private static ContextMenu? GetContextMenuForFiles(ShellItem[] shellItems, Shell32.CMF flags, ThreadWithMessageQueue owningThread, Func<string, bool>? itemFilter = null)
private static ContextMenu? GetContextMenuForFiles(ShellItem[] shellItems, uint flags, ThreadWithMessageQueue owningThread, Func<string, bool>? itemFilter = null)
{
if (!shellItems.Any())
return null;
Expand All @@ -159,7 +161,7 @@ public async Task<bool> InvokeItem(int itemID)

Shell32.IContextMenu menu = sf.GetChildrenUIObjects<Shell32.IContextMenu>(default, shellItems);
var hMenu = User32.CreatePopupMenu();
menu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, flags);
menu.QueryContextMenu(hMenu, 0, 1, 0x7FFF, (Shell32.CMF)flags);
var contextMenu = new ContextMenu(menu, hMenu, shellItems.Select(x => x.ParsingName), owningThread, itemFilter);
contextMenu.EnumMenuItems(hMenu, contextMenu.Items);

Expand All @@ -174,10 +176,10 @@ public async Task<bool> InvokeItem(int itemID)

public static async Task WarmUpQueryContextMenuAsync()
{
using var cMenu = await GetContextMenuForFiles(new string[] { $@"{Constants.UserEnvironmentPaths.SystemDrivePath}\" }, Shell32.CMF.CMF_NORMAL);
using var cMenu = await GetContextMenuForFiles(new string[] { $@"{Constants.UserEnvironmentPaths.SystemDrivePath}\" }, PInvoke.CMF_NORMAL);
}

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

Expand Down Expand Up @@ -211,12 +213,12 @@ private void EnumMenuItems(HMENU hMenu, List<Win32ContextMenuItem> menuItemsResu
continue;
}

menuItem.Type = (MenuItemType)menuItemInfo.fType;
menuItem.Type = (MENU_ITEM_TYPE)menuItemInfo.fType;

// wID - idCmdFirst
menuItem.ID = (int)(menuItemInfo.wID - 1);

if (menuItem.Type == MenuItemType.MFT_STRING)
if (menuItem.Type == MENU_ITEM_TYPE.MFT_STRING)
{
Debug.WriteLine("Item {0} ({1}): {2}", index, menuItemInfo.wID, menuItemInfo.dwTypeData);

Expand Down Expand Up @@ -244,7 +246,7 @@ private void EnumMenuItems(HMENU hMenu, List<Win32ContextMenuItem> menuItemsResu
}
}

if (menuItemInfo.hSubMenu != HMENU.NULL)
if (menuItemInfo.hSubMenu != Vanara.PInvoke.HMENU.NULL)
{
Debug.WriteLine("Item {0}: has submenu", index);
var subItems = new List<Win32ContextMenuItem>();
Expand Down
10 changes: 6 additions & 4 deletions src/Files.App/Utils/Shell/LaunchHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.IO;
using Vanara.PInvoke;
using Vanara.Windows.Shell;
using Windows.Win32;
using Windows.Win32.UI.Shell;

namespace Files.App.Utils.Shell
{
Expand All @@ -16,12 +18,12 @@ public static class LaunchHelper
{
public static void LaunchSettings(string page)
{
var appActiveManager = new Shell32.IApplicationActivationManager();
var appActiveManager = new IApplicationActivationManager();

appActiveManager.ActivateApplication(
"windows.immersivecontrolpanel_cw5n1h2txyewy!microsoft.windows.immersivecontrolpanel",
page,
Shell32.ACTIVATEOPTIONS.AO_NONE,
ACTIVATEOPTIONS.AO_NONE,
out _);
}

Expand Down Expand Up @@ -160,7 +162,7 @@ private static async Task<bool> HandleApplicationLaunch(string application, stri
if (!group.Any())
continue;

using var cMenu = await ContextMenu.GetContextMenuForFiles(group.ToArray(), Shell32.CMF.CMF_DEFAULTONLY);
using var cMenu = await ContextMenu.GetContextMenuForFiles(group.ToArray(), PInvoke.CMF_DEFAULTONLY);

if (cMenu is not null)
await cMenu.InvokeVerb(Shell32.CMDSTR_OPEN);
Expand All @@ -176,7 +178,7 @@ private static async Task<bool> HandleApplicationLaunch(string application, stri
{
opened = await Win32Helper.StartSTATask(async () =>
{
using var cMenu = await ContextMenu.GetContextMenuForFiles(new[] { application }, Shell32.CMF.CMF_DEFAULTONLY);
using var cMenu = await ContextMenu.GetContextMenuForFiles(new[] { application }, PInvoke.CMF_DEFAULTONLY);

if (cMenu is not null)
await cMenu.InvokeItem(cMenu.Items.FirstOrDefault()?.ID ?? -1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Files.App.Services.SizeProvider;
using Files.Shared.Helpers;
using System.IO;
using Vanara.PInvoke;
using Windows.Storage;
using static Files.App.Helpers.Win32Helper;
using FileAttributes = System.IO.FileAttributes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System.IO;
using System.Windows.Input;
using Vanara.PInvoke;
using Windows.Storage;

namespace Files.App.ViewModels.Dialogs
Expand Down
1 change: 0 additions & 1 deletion src/Files.App/ViewModels/Settings/AdvancedViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.IO;
using System.Text;
using System.Windows.Input;
using Vanara.PInvoke;
using Windows.ApplicationModel;
using Windows.Storage;
using Windows.Storage.Pickers;
Expand Down
1 change: 0 additions & 1 deletion src/Files.App/ViewModels/Settings/GeneralViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System.Collections.Specialized;
using System.Globalization;
using Vanara.PInvoke;
using Windows.Globalization;
using Windows.Storage;
using Windows.Storage.Pickers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,18 @@ public async override Task<List<FileProperty>> LoadPreviewAndDetailsAsync()
}
}

public void SizeChanged(RECT size)
public void SizeChanged(Windows.Foundation.Rect size)
{
var width = (int)size.Width;
var height = (int)size.Height;

if (hwnd != HWND.NULL)
SetWindowPos(hwnd, HWND.HWND_TOP, size.Left, size.Top, size.Width, size.Height, SetWindowPosFlags.SWP_NOACTIVATE);
SetWindowPos(hwnd, HWND.HWND_TOP, (int)size.Left, (int)size.Top, width, height, SetWindowPosFlags.SWP_NOACTIVATE);

currentHandler?.ResetBounds(new(0, 0, size.Width, size.Height));
currentHandler?.ResetBounds(new(0, 0, width, height));

if (outputLink is not null)
outputLink.PlacementVisual.Size = new(size.Width, size.Height);
outputLink.PlacementVisual.Size = new(width, height);
}

private nint WndProc(HWND hwnd, uint msg, nint wParam, nint lParam)
Expand Down