Skip to content

Commit ce8b42b

Browse files
committed
Replace DllImport & flags with CSWin32
1 parent 22170ee commit ce8b42b

File tree

6 files changed

+65
-87
lines changed

6 files changed

+65
-87
lines changed

Flow.Launcher/Flow.Launcher.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
</PackageReference>
9191
<PackageReference Include="InputSimulator" Version="1.0.4" />
9292
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
93+
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
94+
<PrivateAssets>all</PrivateAssets>
95+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
96+
</PackageReference>
9397
<!-- ModernWpfUI v0.9.5 introduced WinRT changes that causes Notification platform unavailable error on some machines -->
9498
<!-- https://github.com/Flow-Launcher/Flow.Launcher/issues/1772#issuecomment-1502440801 -->
9599
<PackageReference Include="ModernWpfUI" Version="0.9.4" />

Flow.Launcher/Helper/DWMDropShadow.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
using System;
2-
using System.Drawing.Printing;
3-
using System.Runtime.InteropServices;
42
using System.Windows;
53
using System.Windows.Interop;
4+
using Windows.Win32;
5+
using Windows.Win32.Graphics.Dwm;
6+
using Windows.Win32.UI.Controls;
67

78
namespace Flow.Launcher.Helper;
89

910
public class DwmDropShadow
1011
{
1112

12-
[DllImport("dwmapi.dll", PreserveSig = true)]
13-
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
14-
15-
[DllImport("dwmapi.dll")]
16-
private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset);
17-
1813
/// <summary>
1914
/// Drops a standard shadow to a WPF Window, even if the window isborderless. Only works with DWM (Vista and Seven).
2015
/// This method is much more efficient than setting AllowsTransparency to true and using the DropShadow effect,
@@ -43,18 +38,18 @@ private static void window_SourceInitialized(object sender, EventArgs e) //fixed
4338
/// </summary>
4439
/// <param name="window">Window to which the shadow will be applied</param>
4540
/// <returns>True if the method succeeded, false if not</returns>
46-
private static bool DropShadow(Window window)
41+
private unsafe static bool DropShadow(Window window)
4742
{
4843
try
4944
{
5045
WindowInteropHelper helper = new WindowInteropHelper(window);
5146
int val = 2;
52-
int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4);
47+
int ret1 = PInvoke.DwmSetWindowAttribute(new(helper.Handle), DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY, &val, 4);
5348

5449
if (ret1 == 0)
5550
{
56-
Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 };
57-
int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m);
51+
var m = new MARGINS { cyBottomHeight = 0, cxLeftWidth = 0, cxRightWidth = 0, cyTopHeight = 0 };
52+
int ret2 = PInvoke.DwmExtendFrameIntoClientArea(new(helper.Handle), &m);
5853
return ret2 == 0;
5954
}
6055
else

Flow.Launcher/Helper/WallpaperPathRetrieval.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
using System;
2-
using System.Linq;
3-
using System.Runtime.InteropServices;
1+
using System.Linq;
42
using System.Text;
53
using System.Windows.Media;
64
using Microsoft.Win32;
5+
using Windows.Win32;
6+
using Windows.Win32.UI.WindowsAndMessaging;
77

88
namespace Flow.Launcher.Helper;
99

1010
public static class WallpaperPathRetrieval
1111
{
12-
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
13-
private static extern Int32 SystemParametersInfo(UInt32 action,
14-
Int32 uParam, StringBuilder vParam, UInt32 winIni);
15-
private static readonly UInt32 SPI_GETDESKWALLPAPER = 0x73;
16-
private static int MAX_PATH = 260;
12+
13+
private static readonly int MAX_PATH = 260;
1714

18-
public static string GetWallpaperPath()
15+
public static unsafe string GetWallpaperPath()
1916
{
2017
var wallpaper = new StringBuilder(MAX_PATH);
21-
SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, wallpaper, 0);
18+
PInvoke.SystemParametersInfo(SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETDESKWALLPAPER, (uint)MAX_PATH, &wallpaper, 0);
2219

2320
var str = wallpaper.ToString();
2421
if (string.IsNullOrEmpty(str))
Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,50 @@
11
using System;
22
using System.Drawing;
3-
using System.Runtime.InteropServices;
4-
using System.Text;
53
using System.Windows;
64
using System.Windows.Forms;
75
using System.Windows.Interop;
86
using System.Windows.Media;
7+
using Windows.Win32;
8+
using Windows.Win32.Foundation;
9+
using Windows.Win32.UI.WindowsAndMessaging;
910
using Point = System.Windows.Point;
1011

1112
namespace Flow.Launcher.Helper;
1213

1314
public class WindowsInteropHelper
1415
{
15-
private const int GWL_STYLE = -16; //WPF's Message code for Title Bar's Style
16-
private const int WS_SYSMENU = 0x80000; //WPF's Message code for System Menu
17-
private static IntPtr _hwnd_shell;
18-
private static IntPtr _hwnd_desktop;
16+
private static HWND _hwnd_shell;
17+
private static HWND _hwnd_desktop;
1918

2019
//Accessors for shell and desktop handlers
2120
//Will set the variables once and then will return them
22-
private static IntPtr HWND_SHELL
21+
private static HWND HWND_SHELL
2322
{
2423
get
2524
{
26-
return _hwnd_shell != IntPtr.Zero ? _hwnd_shell : _hwnd_shell = GetShellWindow();
25+
return _hwnd_shell != HWND.Null ? _hwnd_shell : _hwnd_shell = PInvoke.GetShellWindow();
2726
}
2827
}
29-
private static IntPtr HWND_DESKTOP
28+
29+
private static HWND HWND_DESKTOP
3030
{
3131
get
3232
{
33-
return _hwnd_desktop != IntPtr.Zero ? _hwnd_desktop : _hwnd_desktop = GetDesktopWindow();
33+
return _hwnd_desktop != HWND.Null ? _hwnd_desktop : _hwnd_desktop = PInvoke.GetDesktopWindow();
3434
}
3535
}
3636

37-
[DllImport("user32.dll", SetLastError = true)]
38-
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
39-
40-
[DllImport("user32.dll")]
41-
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
42-
43-
[DllImport("user32.dll")]
44-
internal static extern IntPtr GetForegroundWindow();
45-
46-
[DllImport("user32.dll")]
47-
internal static extern IntPtr GetDesktopWindow();
48-
49-
[DllImport("user32.dll")]
50-
internal static extern IntPtr GetShellWindow();
51-
52-
[DllImport("user32.dll", SetLastError = true)]
53-
internal static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
54-
55-
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
56-
internal static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
57-
58-
[DllImport("user32.DLL")]
59-
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
60-
61-
6237
const string WINDOW_CLASS_CONSOLE = "ConsoleWindowClass";
6338
const string WINDOW_CLASS_WINTAB = "Flip3D";
6439
const string WINDOW_CLASS_PROGMAN = "Progman";
6540
const string WINDOW_CLASS_WORKERW = "WorkerW";
6641

67-
public static bool IsWindowFullscreen()
42+
public unsafe static bool IsWindowFullscreen()
6843
{
6944
//get current active window
70-
IntPtr hWnd = GetForegroundWindow();
45+
var hWnd = PInvoke.GetForegroundWindow();
7146

72-
if (hWnd.Equals(IntPtr.Zero))
47+
if (hWnd.Equals(HWND.Null))
7348
{
7449
return false;
7550
}
@@ -80,38 +55,44 @@ public static bool IsWindowFullscreen()
8055
return false;
8156
}
8257

83-
StringBuilder sb = new StringBuilder(256);
84-
GetClassName(hWnd, sb, sb.Capacity);
85-
string windowClass = sb.ToString();
58+
string windowClass;
59+
int capacity = 256;
60+
char[] buffer = new char[capacity];
61+
fixed (char* pBuffer = buffer)
62+
{
63+
PInvoke.GetClassName(hWnd, pBuffer, capacity);
64+
int validLength = Array.IndexOf(buffer, '\0');
65+
if (validLength < 0) validLength = capacity;
66+
windowClass = new string(buffer, 0, validLength);
67+
}
8668

8769
//for Win+Tab (Flip3D)
8870
if (windowClass == WINDOW_CLASS_WINTAB)
8971
{
9072
return false;
9173
}
9274

93-
RECT appBounds;
94-
GetWindowRect(hWnd, out appBounds);
75+
PInvoke.GetWindowRect(hWnd, out var appBounds);
9576

9677
//for console (ConsoleWindowClass), we have to check for negative dimensions
9778
if (windowClass == WINDOW_CLASS_CONSOLE)
9879
{
99-
return appBounds.Top < 0 && appBounds.Bottom < 0;
80+
return appBounds.top < 0 && appBounds.bottom < 0;
10081
}
10182

10283
//for desktop (Progman or WorkerW, depends on the system), we have to check
10384
if (windowClass is WINDOW_CLASS_PROGMAN or WINDOW_CLASS_WORKERW)
10485
{
105-
IntPtr hWndDesktop = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
106-
hWndDesktop = FindWindowEx(hWndDesktop, IntPtr.Zero, "SysListView32", "FolderView");
86+
var hWndDesktop = PInvoke.FindWindowEx(hWnd, HWND.Null, "SHELLDLL_DefView", null);
87+
hWndDesktop = PInvoke.FindWindowEx(hWndDesktop, HWND.Null, "SysListView32", "FolderView");
10788
if (!hWndDesktop.Equals(IntPtr.Zero))
10889
{
10990
return false;
11091
}
11192
}
11293

11394
Rectangle screenBounds = Screen.FromHandle(hWnd).Bounds;
114-
return (appBounds.Bottom - appBounds.Top) == screenBounds.Height && (appBounds.Right - appBounds.Left) == screenBounds.Width;
95+
return (appBounds.bottom - appBounds.top) == screenBounds.Height && (appBounds.right - appBounds.left) == screenBounds.Width;
11596
}
11697

11798
/// <summary>
@@ -120,8 +101,8 @@ public static bool IsWindowFullscreen()
120101
/// </summary>
121102
public static void DisableControlBox(Window win)
122103
{
123-
var hwnd = new WindowInteropHelper(win).Handle;
124-
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
104+
var hwnd = new HWND(new WindowInteropHelper(win).Handle);
105+
PInvoke.SetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE, PInvoke.GetWindowLong(hwnd, WINDOW_LONG_PTR_INDEX.GWL_STYLE) & ~(int)WINDOW_STYLE.WS_SYSMENU);
125106
}
126107

127108
/// <summary>
@@ -146,14 +127,4 @@ public static Point TransformPixelsToDIP(Visual visual, double unitX, double uni
146127
}
147128
return new Point((int)(matrix.M11 * unitX), (int)(matrix.M22 * unitY));
148129
}
149-
150-
151-
[StructLayout(LayoutKind.Sequential)]
152-
public struct RECT
153-
{
154-
public int Left;
155-
public int Top;
156-
public int Right;
157-
public int Bottom;
158-
}
159130
}

Flow.Launcher/MainWindow.xaml.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,14 @@
2626
using DataObject = System.Windows.DataObject;
2727
using System.Windows.Media;
2828
using System.Windows.Interop;
29-
using System.Runtime.InteropServices;
29+
using Windows.Win32;
3030

3131
namespace Flow.Launcher
3232
{
3333
public partial class MainWindow
3434
{
3535
#region Private Fields
3636

37-
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
38-
public static extern IntPtr SetForegroundWindow(IntPtr hwnd);
39-
4037
private readonly Storyboard _progressBarStoryboard = new Storyboard();
4138
private bool isProgressBarStoryboardPaused;
4239
private Settings _settings;
@@ -424,7 +421,7 @@ private void InitializeNotifyIcon()
424421
// Get context menu handle and bring it to the foreground
425422
if (PresentationSource.FromVisual(contextMenu) is HwndSource hwndSource)
426423
{
427-
_ = SetForegroundWindow(hwndSource.Handle);
424+
PInvoke.SetForegroundWindow(new(hwndSource.Handle));
428425
}
429426

430427
contextMenu.Focus();
@@ -692,7 +689,7 @@ public Screen SelectedScreen()
692689
screen = Screen.PrimaryScreen;
693690
break;
694691
case SearchWindowScreens.Focus:
695-
IntPtr foregroundWindowHandle = WindowsInteropHelper.GetForegroundWindow();
692+
var foregroundWindowHandle = PInvoke.GetForegroundWindow().Value;
696693
screen = Screen.FromHandle(foregroundWindowHandle);
697694
break;
698695
case SearchWindowScreens.Custom:

Flow.Launcher/NativeMethods.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
DwmSetWindowAttribute
2+
DwmExtendFrameIntoClientArea
3+
SystemParametersInfo
4+
SetForegroundWindow
5+
6+
GetWindowLong
7+
SetWindowLong
8+
GetForegroundWindow
9+
GetDesktopWindow
10+
GetShellWindow
11+
GetWindowRect
12+
GetClassName
13+
FindWindowEx
14+
WINDOW_STYLE

0 commit comments

Comments
 (0)