improve:悬浮窗拦截

This commit is contained in:
2026-05-02 15:16:59 +08:00
parent 81b291f2e6
commit f39d0c0f82
+22 -24
View File
@@ -822,10 +822,6 @@ namespace Ink_Canvas.Helpers
var foundWindows = new List<(IntPtr hwnd, InterceptRule rule)>(); var foundWindows = new List<(IntPtr hwnd, InterceptRule rule)>();
// Reset per-scan state
foreach (var rule in _interceptRules.Values)
rule.foundHwnd = false;
EnumWindows((hWnd, lParam) => EnumWindows((hWnd, lParam) =>
{ {
EnumChildWindows(hWnd, (childHwnd, _) => EnumChildWindows(hWnd, (childHwnd, _) =>
@@ -840,13 +836,11 @@ namespace Ink_Canvas.Helpers
var interceptedCount = 0; var interceptedCount = 0;
foreach (var (hWnd, rule) in foundWindows) foreach (var (hWnd, rule) in foundWindows)
{ {
bool shouldAct = !_interceptedWindows.ContainsKey(hWnd) || // 已被隐藏且仍不可见:已拦截,无需重复操作
(_interceptedWindows.ContainsKey(hWnd) && IsWindowVisible(hWnd)); if (_interceptedWindows.ContainsKey(hWnd) && !IsWindowVisible(hWnd))
if (shouldAct) continue;
{ ApplyIntercept(hWnd, rule);
ApplyIntercept(hWnd, rule); interceptedCount++;
interceptedCount++;
}
} }
if (interceptedCount == 0) _consecutiveEmptyScans++; if (interceptedCount == 0) _consecutiveEmptyScans++;
@@ -865,19 +859,21 @@ namespace Ink_Canvas.Helpers
private void CheckWindow(IntPtr hWnd, List<(IntPtr, InterceptRule)> found) private void CheckWindow(IntPtr hWnd, List<(IntPtr, InterceptRule)> found)
{ {
if (!IsWindow(hWnd) || !IsWindowVisible(hWnd)) return; // 必须是合法窗口句柄,但不要求可见(被我们隐藏的窗口也需要被发现以维持拦截状态)
if (!IsWindow(hWnd)) return;
foreach (var rule in _interceptRules.Values) foreach (var rule in _interceptRules.Values)
{ {
if (!rule.IsEnabled || rule.foundHwnd) continue; if (!rule.IsEnabled) continue;
if (MatchesRule(hWnd, rule)) if (MatchesRule(hWnd, rule))
{ {
rule.outHwnd = hWnd;
rule.foundHwnd = true;
found.Add((hWnd, rule)); found.Add((hWnd, rule));
break; // 一个窗口只匹配第一条命中的规则
} }
} }
} }
<<<END_W2P:old_string:h4e39a0fd>>>
END_CALL
private bool MatchesRule(IntPtr hWnd, InterceptRule rule) private bool MatchesRule(IntPtr hWnd, InterceptRule rule)
{ {
@@ -954,34 +950,36 @@ namespace Ink_Canvas.Helpers
int h = rect.Bottom - rect.Top; int h = rect.Bottom - rect.Top;
if (w == 0 && h == 0) return false; if (w == 0 && h == 0) return false;
// DWM 返回物理像素,GetSystemMetrics 返回逻辑像素,需换算
var hdc = GetDC(IntPtr.Zero);
float scaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
float scaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f;
ReleaseDC(IntPtr.Zero, hdc);
int screenW = (int)(GetSystemMetrics(SM_CXSCREEN) * scaleX);
int screenH = (int)(GetSystemMetrics(SM_CYSCREEN) * scaleY);
const int tolerance = 2; const int tolerance = 2;
switch (rule.SizeMatchType) switch (rule.SizeMatchType)
{ {
case SizeMatchType.FullScreen: case SizeMatchType.FullScreen:
if (w != GetSystemMetrics(SM_CXSCREEN) || h != GetSystemMetrics(SM_CYSCREEN)) if (Math.Abs(w - screenW) > tolerance || Math.Abs(h - screenH) > tolerance)
return false; return false;
break; break;
case SizeMatchType.FullHeight: case SizeMatchType.FullHeight:
if (h != GetSystemMetrics(SM_CYSCREEN)) return false; if (Math.Abs(h - screenH) > tolerance) return false;
break; break;
case SizeMatchType.FullWidth: case SizeMatchType.FullWidth:
if (w != GetSystemMetrics(SM_CXSCREEN)) return false; if (Math.Abs(w - screenW) > tolerance) return false;
break; break;
case SizeMatchType.Exact: case SizeMatchType.Exact:
if (w != rule.WindowWidth || h != rule.WindowHeight) return false; if (w != rule.WindowWidth || h != rule.WindowHeight) return false;
break; break;
case SizeMatchType.DPIScale: case SizeMatchType.DPIScale:
{
var hdc = GetDC(IntPtr.Zero);
float scaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
float scaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0f;
ReleaseDC(IntPtr.Zero, hdc);
if (Math.Abs(rule.WindowWidth * scaleX - w) > tolerance || if (Math.Abs(rule.WindowWidth * scaleX - w) > tolerance ||
Math.Abs(rule.WindowHeight * scaleY - h) > tolerance) Math.Abs(rule.WindowHeight * scaleY - h) > tolerance)
return false; return false;
break; break;
}
case SizeMatchType.Scale: case SizeMatchType.Scale:
{ {
if (rule.WindowWidth == 0 || rule.WindowHeight == 0) return false; if (rule.WindowWidth == 0 || rule.WindowHeight == 0) return false;