Replace DllImport & flags with CSWin32

This commit is contained in:
Jack251970 2024-12-10 22:01:55 +08:00
parent 22170ee43a
commit ce8b42bc6e
6 changed files with 65 additions and 87 deletions

View file

@ -90,6 +90,10 @@
</PackageReference>
<PackageReference Include="InputSimulator" Version="1.0.4" />
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- ModernWpfUI v0.9.5 introduced WinRT changes that causes Notification platform unavailable error on some machines -->
<!-- https://github.com/Flow-Launcher/Flow.Launcher/issues/1772#issuecomment-1502440801 -->
<PackageReference Include="ModernWpfUI" Version="0.9.4" />

View file

@ -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);
/// <summary>
/// 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
/// </summary>
/// <param name="window">Window to which the shadow will be applied</param>
/// <returns>True if the method succeeded, false if not</returns>
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

View file

@ -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))

View file

@ -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;
}
/// <summary>
@ -120,8 +101,8 @@ public class WindowsInteropHelper
/// </summary>
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);
}
/// <summary>
@ -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;
}
}

View file

@ -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:

View file

@ -0,0 +1,14 @@
DwmSetWindowAttribute
DwmExtendFrameIntoClientArea
SystemParametersInfo
SetForegroundWindow
GetWindowLong
SetWindowLong
GetForegroundWindow
GetDesktopWindow
GetShellWindow
GetWindowRect
GetClassName
FindWindowEx
WINDOW_STYLE