From ce8b42bc6edb3e5759c7700dd11c71dfb4bff1d4 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Tue, 10 Dec 2024 22:01:55 +0800
Subject: [PATCH] Replace DllImport & flags with CSWin32
---
Flow.Launcher/Flow.Launcher.csproj | 4 +
Flow.Launcher/Helper/DWMDropShadow.cs | 19 ++--
.../Helper/WallpaperPathRetrieval.cs | 17 ++--
Flow.Launcher/Helper/WindowsInteropHelper.cs | 89 +++++++------------
Flow.Launcher/MainWindow.xaml.cs | 9 +-
Flow.Launcher/NativeMethods.txt | 14 +++
6 files changed, 65 insertions(+), 87 deletions(-)
create mode 100644 Flow.Launcher/NativeMethods.txt
diff --git a/Flow.Launcher/Flow.Launcher.csproj b/Flow.Launcher/Flow.Launcher.csproj
index afc3fbbaa..7bd59e8c1 100644
--- a/Flow.Launcher/Flow.Launcher.csproj
+++ b/Flow.Launcher/Flow.Launcher.csproj
@@ -90,6 +90,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Flow.Launcher/Helper/DWMDropShadow.cs b/Flow.Launcher/Helper/DWMDropShadow.cs
index e448acd4c..7cb719d07 100644
--- a/Flow.Launcher/Helper/DWMDropShadow.cs
+++ b/Flow.Launcher/Helper/DWMDropShadow.cs
@@ -1,20 +1,15 @@
using System;
-using System.Drawing.Printing;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
+using Windows.Win32;
+using Windows.Win32.Graphics.Dwm;
+using Windows.Win32.UI.Controls;
namespace Flow.Launcher.Helper;
public class DwmDropShadow
{
- [DllImport("dwmapi.dll", PreserveSig = true)]
- private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
-
- [DllImport("dwmapi.dll")]
- private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
-
///
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven).
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect,
@@ -43,18 +38,18 @@ public class DwmDropShadow
///
/// Window to which the shadow will be applied
/// True if the method succeeded, false if not
- private static bool DropShadow(Window window)
+ private unsafe static bool DropShadow(Window window)
{
try
{
WindowInteropHelper helper = new WindowInteropHelper(window);
int val = 2;
- int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);
+ int ret1 = PInvoke.DwmSetWindowAttribute(new(helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
if (ret1 == 0)
{
- Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 };
- int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m);
+ var m = new MARGINS { cyBottomHeight = 0, cxLeftWidth = 0, cxRightWidth = 0, cyTopHeight = 0 };
+ int ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
return ret2 == 0;
}
else
diff --git a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
index e08e227cc..8ab06e78d 100644
--- a/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
+++ b/Flow.Launcher/Helper/WallpaperPathRetrieval.cs
@@ -1,24 +1,21 @@
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
+using System.Linq;
using System.Text;
using System.Windows.Media;
using Microsoft.Win32;
+using Windows.Win32;
+using Windows.Win32.UI.WindowsAndMessaging;
namespace Flow.Launcher.Helper;
public static class WallpaperPathRetrieval
{
- [DllImport("user32.dll", CharSet = CharSet.Unicode)]
- private static extern Int32 SystemParametersInfo(UInt32 action,
- Int32 uParam, StringBuilder vParam, UInt32 winIni);
- private static readonly UInt32 SPI_GETDESKWALLPAPER = 0x73;
- private static int MAX_PATH = 260;
+
+ private static readonly int MAX_PATH = 260;
- public static string GetWallpaperPath()
+ public static unsafe string GetWallpaperPath()
{
var wallpaper = new StringBuilder(MAX_PATH);
- SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallpaper, 0);
+ PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH, &wallpaper, 0);
var str = wallpaper.ToString();
if (string.IsNullOrEmpty(str))
diff --git a/Flow.Launcher/Helper/WindowsInteropHelper.cs b/Flow.Launcher/Helper/WindowsInteropHelper.cs
index 89fbec967..ae48034e8 100644
--- a/Flow.Launcher/Helper/WindowsInteropHelper.cs
+++ b/Flow.Launcher/Helper/WindowsInteropHelper.cs
@@ -1,75 +1,50 @@
using System;
using System.Drawing;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Interop;
using System.Windows.Media;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.UI.WindowsAndMessaging;
using Point = System.Windows.Point;
namespace Flow.Launcher.Helper;
public class WindowsInteropHelper
{
- private const int GWL_STYLE = -16; //WPF's Message code for Title Bar's Style
- private const int WS_SYSMENU = 0x80000; //WPF's Message code for System Menu
- private static IntPtr _hwnd_shell;
- private static IntPtr _hwnd_desktop;
+ private static HWND _hwnd_shell;
+ private static HWND _hwnd_desktop;
//Accessors for shell and desktop handlers
//Will set the variables once and then will return them
- private static IntPtr HWND_SHELL
+ private static HWND HWND_SHELL
{
get
{
- return _hwnd_shell != IntPtr.Zero ? _hwnd_shell : _hwnd_shell = GetShellWindow();
+ return _hwnd_shell != HWND.Null ? _hwnd_shell : _hwnd_shell = PInvoke.GetShellWindow();
}
}
- private static IntPtr HWND_DESKTOP
+
+ private static HWND HWND_DESKTOP
{
get
{
- return _hwnd_desktop != IntPtr.Zero ? _hwnd_desktop : _hwnd_desktop = GetDesktopWindow();
+ return _hwnd_desktop != HWND.Null ? _hwnd_desktop : _hwnd_desktop = PInvoke.GetDesktopWindow();
}
}
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll")]
- internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetForegroundWindow();
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetDesktopWindow();
-
- [DllImport("user32.dll")]
- internal static extern IntPtr GetShellWindow();
-
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
-
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
-
- [DllImport("user32.DLL")]
- public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
-
-
const string WINDOW_CLASS_CONSOLE = "ConsoleWindowClass";
const string WINDOW_CLASS_WINTAB = "Flip3D";
const string WINDOW_CLASS_PROGMAN = "Progman";
const string WINDOW_CLASS_WORKERW = "WorkerW";
- public static bool IsWindowFullscreen()
+ public unsafe static bool IsWindowFullscreen()
{
//get current active window
- IntPtr hWnd = GetForegroundWindow();
+ var hWnd = PInvoke.GetForegroundWindow();
- if (hWnd.Equals(IntPtr.Zero))
+ if (hWnd.Equals(HWND.Null))
{
return false;
}
@@ -80,9 +55,16 @@ public class WindowsInteropHelper
return false;
}
- StringBuilder sb = new StringBuilder(256);
- GetClassName(hWnd, sb, sb.Capacity);
- string windowClass = sb.ToString();
+ string windowClass;
+ int capacity = 256;
+ char[] buffer = new char[capacity];
+ fixed (char* pBuffer = buffer)
+ {
+ PInvoke.GetClassName(hWnd, pBuffer, capacity);
+ int validLength = Array.IndexOf(buffer, '\0');
+ if (validLength < 0) validLength = capacity;
+ windowClass = new string(buffer, 0, validLength);
+ }
//for Win+Tab (Flip3D)
if (windowClass == WINDOW_CLASS_WINTAB)
@@ -90,20 +72,19 @@ public class WindowsInteropHelper
return false;
}
- RECT appBounds;
- GetWindowRect(hWnd, out appBounds);
+ PInvoke.GetWindowRect(hWnd, out var appBounds);
//for console (ConsoleWindowClass), we have to check for negative dimensions
if (windowClass == WINDOW_CLASS_CONSOLE)
{
- return appBounds.Top < 0 && appBounds.Bottom < 0;
+ return appBounds.top < 0 && appBounds.bottom < 0;
}
//for desktop (Progman or WorkerW, depends on the system), we have to check
if (windowClass is WINDOW_CLASS_PROGMAN or WINDOW_CLASS_WORKERW)
{
- IntPtr hWndDesktop = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
- hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", "FolderView");
+ var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
+ hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
if (!hWndDesktop.Equals(IntPtr.Zero))
{
return false;
@@ -111,7 +92,7 @@ public class WindowsInteropHelper
}
Rectangle screenBounds = Screen.FromHandle(hWnd).Bounds;
- return (appBounds.Bottom - appBounds.Top) == screenBounds.Height && (appBounds.Right - appBounds.Left) == screenBounds.Width;
+ return (appBounds.bottom - appBounds.top) == screenBounds.Height && (appBounds.right - appBounds.left) == screenBounds.Width;
}
///
@@ -120,8 +101,8 @@ public class WindowsInteropHelper
///
public static void DisableControlBox(Window win)
{
- var hwnd = new WindowInteropHelper(win).Handle;
- SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
+ var hwnd = new HWND(new WindowInteropHelper(win).Handle);
+ PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE) & ~(int)WINDOW_STYLE.WS_SYSMENU);
}
///
@@ -146,14 +127,4 @@ public class WindowsInteropHelper
}
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
}
-
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
}
diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs
index 0f8b8f6d7..b4f1fb031 100644
--- a/Flow.Launcher/MainWindow.xaml.cs
+++ b/Flow.Launcher/MainWindow.xaml.cs
@@ -26,7 +26,7 @@ using System.Media;
using DataObject = System.Windows.DataObject;
using System.Windows.Media;
using System.Windows.Interop;
-using System.Runtime.InteropServices;
+using Windows.Win32;
namespace Flow.Launcher
{
@@ -34,9 +34,6 @@ namespace Flow.Launcher
{
#region Private Fields
- [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern IntPtr SetForegroundWindow(IntPtr hwnd);
-
private readonly Storyboard _progressBarStoryboard = new Storyboard();
private bool isProgressBarStoryboardPaused;
private Settings _settings;
@@ -424,7 +421,7 @@ namespace Flow.Launcher
// Get context menu handle and bring it to the foreground
if (PresentationSource.FromVisual(contextMenu) is HwndSource hwndSource)
{
- _ = SetForegroundWindow(hwndSource.Handle);
+ PInvoke.SetForegroundWindow(new(hwndSource.Handle));
}
contextMenu.Focus();
@@ -692,7 +689,7 @@ namespace Flow.Launcher
screen = Screen.PrimaryScreen;
break;
case SearchWindowScreens.Focus:
- IntPtr foregroundWindowHandle = WindowsInteropHelper.GetForegroundWindow();
+ var foregroundWindowHandle = PInvoke.GetForegroundWindow().Value;
screen = Screen.FromHandle(foregroundWindowHandle);
break;
case SearchWindowScreens.Custom:
diff --git a/Flow.Launcher/NativeMethods.txt b/Flow.Launcher/NativeMethods.txt
new file mode 100644
index 000000000..bbf55502e
--- /dev/null
+++ b/Flow.Launcher/NativeMethods.txt
@@ -0,0 +1,14 @@
+DwmSetWindowAttribute
+DwmExtendFrameIntoClientArea
+SystemParametersInfo
+SetForegroundWindow
+
+GetWindowLong
+SetWindowLong
+GetForegroundWindow
+GetDesktopWindow
+GetShellWindow
+GetWindowRect
+GetClassName
+FindWindowEx
+WINDOW_STYLE
\ No newline at end of file