-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainWindow.NativeInterop.cs
More file actions
159 lines (136 loc) · 4.77 KB
/
MainWindow.NativeInterop.cs
File metadata and controls
159 lines (136 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
using System.Runtime.InteropServices;
using System.Windows;
namespace ScreenSearchOverlay;
// Win32 P/Invoke surface + the small instance helpers that wrap it.
// All members live on the same partial class as the rest of MainWindow.
public partial class MainWindow : Window
{
// ── Instance helpers used by the scroll state machine ──
private void SetClickThrough(bool enable)
{
var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
if (hwnd == IntPtr.Zero) return;
var ex = GetWindowLong(hwnd, GWL_EXSTYLE);
var newEx = enable ? (ex | WS_EX_TRANSPARENT) : (ex & ~WS_EX_TRANSPARENT);
SetWindowLong(hwnd, GWL_EXSTYLE, newEx);
}
private bool IsCursorOverThisWindow()
{
var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
if (hwnd == IntPtr.Zero) return false;
if (!GetWindowRect(hwnd, out var rect)) return false;
if (!GetCursorPos(out var p)) return false;
return p.X >= rect.Left && p.X < rect.Right
&& p.Y >= rect.Top && p.Y < rect.Bottom;
}
private static void InjectMouseWheel(int delta)
{
var input = new INPUT
{
type = INPUT_MOUSE,
u = new INPUTUNION
{
mi = new MOUSEINPUT
{
dx = 0,
dy = 0,
mouseData = (uint)delta,
dwFlags = MOUSEEVENTF_WHEEL,
time = 0,
dwExtraInfo = IntPtr.Zero
}
}
};
SendInput(1, [input], Marshal.SizeOf<INPUT>());
}
internal static ScreenInfo GetCurrentScreenInfo()
{
GetCursorPos(out var cursorPos);
var hMonitor = MonitorFromPoint(cursorPos, MONITOR_DEFAULTTONEAREST);
var monitorInfo = new MONITORINFO { cbSize = Marshal.SizeOf<MONITORINFO>() };
GetMonitorInfo(hMonitor, ref monitorInfo);
var r = monitorInfo.rcMonitor;
return new ScreenInfo(r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top);
}
// ── P/Invoke ──
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GetCursorPos(out POINT lpPoint);
[LibraryImport("user32.dll")]
private static partial IntPtr MonitorFromPoint(POINT pt, uint dwFlags);
[LibraryImport("user32.dll", EntryPoint = "GetMonitorInfoW")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
[LibraryImport("user32.dll", EntryPoint = "GetWindowLongW")]
private static partial int GetWindowLong(IntPtr hWnd, int nIndex);
[LibraryImport("user32.dll", EntryPoint = "SetWindowLongW")]
private static partial int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[LibraryImport("user32.dll")]
private static partial uint SendInput(uint nInputs, [In] INPUT[] pInputs, int cbSize);
private const uint MONITOR_DEFAULTTONEAREST = 2;
private const int GWL_EXSTYLE = -20;
private const int WS_EX_TRANSPARENT = 0x00000020;
private const uint INPUT_MOUSE = 0;
private const uint MOUSEEVENTF_WHEEL = 0x0800;
[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct HARDWAREINPUT
{
public uint uMsg;
public ushort wParamL;
public ushort wParamH;
}
[StructLayout(LayoutKind.Explicit)]
private struct INPUTUNION
{
[FieldOffset(0)] public MOUSEINPUT mi;
[FieldOffset(0)] public KEYBDINPUT ki;
[FieldOffset(0)] public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
private struct INPUT
{
public uint type;
public INPUTUNION u;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left, Top, Right, Bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
}