Skip to content

Commit fd3576d

Browse files
authored
Merge pull request #3122 from Jack251970/dev3
Replace DllImport and flags with CSWin32 & Remove useless DllImport and flags & Fix right Win key click issue
2 parents e7e825e + 9350e82 commit fd3576d

31 files changed

+659
-843
lines changed

Flow.Launcher.Core/Resource/Theme.cs

Lines changed: 2 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
using System.IO;
44
using System.Linq;
55
using System.Xml;
6-
using System.Runtime.InteropServices;
76
using System.Windows;
87
using System.Windows.Controls;
9-
using System.Windows.Interop;
108
using System.Windows.Markup;
119
using System.Windows.Media;
1210
using System.Windows.Media.Effects;
@@ -98,12 +96,12 @@ public bool ChangeTheme(string theme)
9896
_oldTheme = Path.GetFileNameWithoutExtension(_oldResource.Source.AbsolutePath);
9997
}
10098

101-
BlurEnabled = IsBlurTheme();
99+
BlurEnabled = Win32Helper.IsBlurTheme();
102100

103101
if (Settings.UseDropShadowEffect && !BlurEnabled)
104102
AddDropShadowEffectToCurrentTheme();
105103

106-
SetBlurForWindow();
104+
Win32Helper.SetBlurForWindow(Application.Current.MainWindow, BlurEnabled);
107105
}
108106
catch (DirectoryNotFoundException)
109107
{
@@ -357,98 +355,6 @@ public void RemoveDropShadowEffectFromCurrentTheme()
357355
UpdateResourceDictionary(dict);
358356
}
359357

360-
#region Blur Handling
361-
/*
362-
Found on https://github.com/riverar/sample-win10-aeroglass
363-
*/
364-
private enum AccentState
365-
{
366-
ACCENT_DISABLED = 0,
367-
ACCENT_ENABLE_GRADIENT = 1,
368-
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
369-
ACCENT_ENABLE_BLURBEHIND = 3,
370-
ACCENT_INVALID_STATE = 4
371-
}
372-
373-
[StructLayout(LayoutKind.Sequential)]
374-
private struct AccentPolicy
375-
{
376-
public AccentState AccentState;
377-
public int AccentFlags;
378-
public int GradientColor;
379-
public int AnimationId;
380-
}
381-
382-
[StructLayout(LayoutKind.Sequential)]
383-
private struct WindowCompositionAttributeData
384-
{
385-
public WindowCompositionAttribute Attribute;
386-
public IntPtr Data;
387-
public int SizeOfData;
388-
}
389-
390-
private enum WindowCompositionAttribute
391-
{
392-
WCA_ACCENT_POLICY = 19
393-
}
394-
[DllImport("user32.dll")]
395-
private static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
396-
397-
/// <summary>
398-
/// Sets the blur for a window via SetWindowCompositionAttribute
399-
/// </summary>
400-
public void SetBlurForWindow()
401-
{
402-
if (BlurEnabled)
403-
{
404-
SetWindowAccent(Application.Current.MainWindow, AccentState.ACCENT_ENABLE_BLURBEHIND);
405-
}
406-
else
407-
{
408-
SetWindowAccent(Application.Current.MainWindow, AccentState.ACCENT_DISABLED);
409-
}
410-
}
411-
412-
private bool IsBlurTheme()
413-
{
414-
if (Environment.OSVersion.Version >= new Version(6, 2))
415-
{
416-
var resource = Application.Current.TryFindResource("ThemeBlurEnabled");
417-
418-
if (resource is bool)
419-
return (bool)resource;
420-
421-
return false;
422-
}
423-
424-
return false;
425-
}
426-
427-
private void SetWindowAccent(Window w, AccentState state)
428-
{
429-
var windowHelper = new WindowInteropHelper(w);
430-
431-
windowHelper.EnsureHandle();
432-
433-
var accent = new AccentPolicy { AccentState = state };
434-
var accentStructSize = Marshal.SizeOf(accent);
435-
436-
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
437-
Marshal.StructureToPtr(accent, accentPtr, false);
438-
439-
var data = new WindowCompositionAttributeData
440-
{
441-
Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
442-
SizeOfData = accentStructSize,
443-
Data = accentPtr
444-
};
445-
446-
SetWindowCompositionAttribute(windowHelper.Handle, ref data);
447-
448-
Marshal.FreeHGlobal(accentPtr);
449-
}
450-
#endregion
451-
452358
public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, bool? HasBlur = null);
453359
}
454360
}

Flow.Launcher.Infrastructure/FileExplorerHelper.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5-
using System.Runtime.InteropServices;
5+
using Windows.Win32;
66

77
namespace Flow.Launcher.Infrastructure
88
{
@@ -54,10 +54,6 @@ private static dynamic GetActiveExplorer()
5454
return explorerWindows.Zip(zOrders).MinBy(x => x.Second).First;
5555
}
5656

57-
[DllImport("user32.dll")]
58-
[return: MarshalAs(UnmanagedType.Bool)]
59-
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
60-
6157
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
6258

6359
/// <summary>
@@ -70,9 +66,9 @@ private static IEnumerable<int> GetZOrder(List<dynamic> hWnds)
7066

7167
var index = 0;
7268
var numRemaining = hWnds.Count;
73-
EnumWindows((wnd, _) =>
69+
PInvoke.EnumWindows((wnd, _) =>
7470
{
75-
var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.ToInt32());
71+
var searchIndex = hWnds.FindIndex(x => x.HWND == wnd.Value);
7672
if (searchIndex != -1)
7773
{
7874
z[searchIndex] = index;

Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
<Prefer32Bit>false</Prefer32Bit>
3636
</PropertyGroup>
3737

38+
<ItemGroup>
39+
<AdditionalFiles Include="NativeMethods.txt" />
40+
</ItemGroup>
41+
3842
<ItemGroup>
3943
<Compile Include="..\SolutionAssemblyInfo.cs" Link="Properties\SolutionAssemblyInfo.cs" />
4044
<None Include="FodyWeavers.xml" />
@@ -56,6 +60,10 @@
5660
</PackageReference>
5761
<PackageReference Include="MemoryPack" Version="1.21.3" />
5862
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.12.19" />
63+
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
64+
<PrivateAssets>all</PrivateAssets>
65+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
66+
</PackageReference>
5967
<PackageReference Include="NLog" Version="4.7.10" />
6068
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0" />
6169
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
using System;
1+
using System;
2+
using System.Diagnostics;
23
using System.Runtime.InteropServices;
34
using Flow.Launcher.Plugin;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.UI.Input.KeyboardAndMouse;
8+
using Windows.Win32.UI.WindowsAndMessaging;
49

510
namespace Flow.Launcher.Infrastructure.Hotkey
611
{
@@ -10,44 +15,45 @@ namespace Flow.Launcher.Infrastructure.Hotkey
1015
/// </summary>
1116
public unsafe class GlobalHotkey : IDisposable
1217
{
13-
private static readonly IntPtr hookId;
14-
15-
16-
18+
private static readonly HOOKPROC _procKeyboard = HookKeyboardCallback;
19+
private static readonly UnhookWindowsHookExSafeHandle hookId;
20+
1721
public delegate bool KeyboardCallback(KeyEvent keyEvent, int vkCode, SpecialKeyState state);
1822
internal static Func<KeyEvent, int, SpecialKeyState, bool> hookedKeyboardCallback;
1923

20-
//Modifier key constants
21-
private const int VK_SHIFT = 0x10;
22-
private const int VK_CONTROL = 0x11;
23-
private const int VK_ALT = 0x12;
24-
private const int VK_WIN = 91;
25-
2624
static GlobalHotkey()
2725
{
2826
// Set the hook
29-
hookId = InterceptKeys.SetHook(& LowLevelKeyboardProc);
27+
hookId = SetHook(_procKeyboard, WINDOWS_HOOK_ID.WH_KEYBOARD_LL);
28+
}
29+
30+
private static UnhookWindowsHookExSafeHandle SetHook(HOOKPROC proc, WINDOWS_HOOK_ID hookId)
31+
{
32+
using var curProcess = Process.GetCurrentProcess();
33+
using var curModule = curProcess.MainModule;
34+
return PInvoke.SetWindowsHookEx(hookId, proc, PInvoke.GetModuleHandle(curModule.ModuleName), 0);
3035
}
3136

3237
public static SpecialKeyState CheckModifiers()
3338
{
3439
SpecialKeyState state = new SpecialKeyState();
35-
if ((InterceptKeys.GetKeyState(VK_SHIFT) & 0x8000) != 0)
40+
if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_SHIFT) & 0x8000) != 0)
3641
{
3742
//SHIFT is pressed
3843
state.ShiftPressed = true;
3944
}
40-
if ((InterceptKeys.GetKeyState(VK_CONTROL) & 0x8000) != 0)
45+
if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_CONTROL) & 0x8000) != 0)
4146
{
4247
//CONTROL is pressed
4348
state.CtrlPressed = true;
4449
}
45-
if ((InterceptKeys.GetKeyState(VK_ALT) & 0x8000) != 0)
50+
if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_MENU) & 0x8000) != 0)
4651
{
4752
//ALT is pressed
4853
state.AltPressed = true;
4954
}
50-
if ((InterceptKeys.GetKeyState(VK_WIN) & 0x8000) != 0)
55+
if ((PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_LWIN) & 0x8000) != 0 ||
56+
(PInvoke.GetKeyState((int)VIRTUAL_KEY.VK_RWIN) & 0x8000) != 0)
5157
{
5258
//WIN is pressed
5359
state.WinPressed = true;
@@ -56,38 +62,38 @@ public static SpecialKeyState CheckModifiers()
5662
return state;
5763
}
5864

59-
[UnmanagedCallersOnly]
60-
private static IntPtr LowLevelKeyboardProc(int nCode, UIntPtr wParam, IntPtr lParam)
65+
private static LRESULT HookKeyboardCallback(int nCode, WPARAM wParam, LPARAM lParam)
6166
{
6267
bool continues = true;
6368

6469
if (nCode >= 0)
6570
{
66-
if (wParam.ToUInt32() == (int)KeyEvent.WM_KEYDOWN ||
67-
wParam.ToUInt32() == (int)KeyEvent.WM_KEYUP ||
68-
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYDOWN ||
69-
wParam.ToUInt32() == (int)KeyEvent.WM_SYSKEYUP)
71+
if (wParam.Value == (int)KeyEvent.WM_KEYDOWN ||
72+
wParam.Value == (int)KeyEvent.WM_KEYUP ||
73+
wParam.Value == (int)KeyEvent.WM_SYSKEYDOWN ||
74+
wParam.Value == (int)KeyEvent.WM_SYSKEYUP)
7075
{
7176
if (hookedKeyboardCallback != null)
72-
continues = hookedKeyboardCallback((KeyEvent)wParam.ToUInt32(), Marshal.ReadInt32(lParam), CheckModifiers());
77+
continues = hookedKeyboardCallback((KeyEvent)wParam.Value, Marshal.ReadInt32(lParam), CheckModifiers());
7378
}
7479
}
7580

7681
if (continues)
7782
{
78-
return InterceptKeys.CallNextHookEx(hookId, nCode, wParam, lParam);
83+
return PInvoke.CallNextHookEx(hookId, nCode, wParam, lParam);
7984
}
80-
return (IntPtr)(-1);
85+
86+
return new LRESULT(1);
8187
}
8288

8389
public void Dispose()
8490
{
85-
InterceptKeys.UnhookWindowsHookEx(hookId);
91+
hookId.Dispose();
8692
}
8793

8894
~GlobalHotkey()
8995
{
9096
Dispose();
9197
}
9298
}
93-
}
99+
}

Flow.Launcher.Infrastructure/Hotkey/InterceptKeys.cs

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1+
using Windows.Win32;
2+
13
namespace Flow.Launcher.Infrastructure.Hotkey
24
{
35
public enum KeyEvent
46
{
57
/// <summary>
68
/// Key down
79
/// </summary>
8-
WM_KEYDOWN = 256,
10+
WM_KEYDOWN = (int)PInvoke.WM_KEYDOWN,
911

1012
/// <summary>
1113
/// Key up
1214
/// </summary>
13-
WM_KEYUP = 257,
15+
WM_KEYUP = (int)PInvoke.WM_KEYUP,
1416

1517
/// <summary>
1618
/// System key up
1719
/// </summary>
18-
WM_SYSKEYUP = 261,
20+
WM_SYSKEYUP = (int)PInvoke.WM_SYSKEYUP,
1921

2022
/// <summary>
2123
/// System key down
2224
/// </summary>
23-
WM_SYSKEYDOWN = 260
25+
WM_SYSKEYDOWN = (int)PInvoke.WM_SYSKEYDOWN
2426
}
25-
}
27+
}

0 commit comments

Comments
 (0)