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