From 9ae6d290e1caa0d93be90d2a06b4d6da95e80050 Mon Sep 17 00:00:00 2001 From: DaZiYuan Date: Tue, 19 Nov 2024 22:28:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:win11=E8=A7=86=E9=A2=91=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=9A=82=E5=81=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Utils/MaximizedMonitor.cs | 2 +- .../Utils/OtherProgramChecker.cs | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 LiveWallpaperEngineAPI/Utils/OtherProgramChecker.cs diff --git a/LiveWallpaperEngineAPI/Utils/MaximizedMonitor.cs b/LiveWallpaperEngineAPI/Utils/MaximizedMonitor.cs index d35f4081..65f85fe6 100644 --- a/LiveWallpaperEngineAPI/Utils/MaximizedMonitor.cs +++ b/LiveWallpaperEngineAPI/Utils/MaximizedMonitor.cs @@ -25,7 +25,7 @@ public static void Check() if (_cp == null) _cp = Process.GetCurrentProcess(); - new OtherProgramChecker(_cp.Id).CheckMaximized(out List fullscreenWindow); + new DZY.WinAPI.Helpers.OtherProgramChecker(_cp.Id).CheckMaximized(out List fullscreenWindow); if (_maximizedScreens.Count == fullscreenWindow.Count) return; diff --git a/LiveWallpaperEngineAPI/Utils/OtherProgramChecker.cs b/LiveWallpaperEngineAPI/Utils/OtherProgramChecker.cs new file mode 100644 index 00000000..3e7c80ac --- /dev/null +++ b/LiveWallpaperEngineAPI/Utils/OtherProgramChecker.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using WinAPI; + +namespace DZY.WinAPI.Helpers +{ + public class OtherProgramChecker + { + private bool _maximized = false; + private static int? _ignorePid; + private readonly bool _onlyFullScreen; + private List _maximizedScreens; + + public OtherProgramChecker(int? currentProcess = null, bool onlyFullScreen = false) + { + _ignorePid = currentProcess; + //是否只检测全屏,任务栏没遮挡不算 + _onlyFullScreen = onlyFullScreen; + } + + public void CheckMaximized(out List maximizedScreens) + { + _maximizedScreens = new List(); + bool ok = User32Wrapper.EnumDesktopWindows(IntPtr.Zero, new User32Wrapper.EnumDelegate(EnumDesktopWindowsCallBack), IntPtr.Zero); + maximizedScreens = _maximizedScreens; + //return _maximized; + } + + private bool EnumDesktopWindowsCallBack(IntPtr hWnd, int lParam) + { + if (_ignorePid != null) + { + //过滤当前进程 + int pid = User32WrapperEx.GetProcessId(hWnd); + if (pid == _ignorePid) + return true; + } + + _maximized = IsMAXIMIZED(hWnd, _onlyFullScreen); + if (_maximized) + { + var screen = Screen.FromHandle(hWnd); + if (_maximizedScreens.Contains(screen)) + return true; + + _maximizedScreens.Add(screen); + if (Screen.AllScreens.Length == _maximizedScreens.Count) + //所有屏幕都已经全屏,不用继续检查 + return false; + return true; + } + + return true; + } + + /// + /// 窗口是否是最大化 + /// + /// + /// + public static bool IsMAXIMIZED(IntPtr handle, bool onlyFullScreen) + { + var className = User32Wrapper.GetClassName(handle); + //过滤一些class,导致错误暂停视频 + string[] strings = { "Progman", "WorkerW", "Shell_TrayWnd", "DV2ControlHost" }; + if (Array.IndexOf(strings, className) >= 0) + return false; + + WINDOWPLACEMENT placment = new WINDOWPLACEMENT(); + User32Wrapper.GetWindowPlacement(handle, ref placment); + //_ = User32WrapperEx.GetProcessId(handle); + + bool visible = User32Wrapper.IsWindowVisible(handle); + if (visible) + { + if (!onlyFullScreen && placment.showCmd == WINDOWPLACEMENTFlags.SW_SHOWMAXIMIZED) + {//窗口最大化 + // Exclude suspended Windows apps + _ = DwmapiWrapper.DwmGetWindowAttribute(handle, DwmapiWrapper.DWMWINDOWATTRIBUTE.DWMWA_CLOAKED, out var cloaked, Marshal.SizeOf()); + //隐藏的UWP窗口 + if (cloaked) + { + return false; + } + //System.Diagnostics.Debug.WriteLine($"pid:{pid} maximized"); + return true; + } + + ////判断一些隐藏窗口 + ////http://forums.codeguru.com/showthread.php?445207-Getting-HWND-of-visible-windows + //var wl = User32Wrapper.GetWindowLong(handle, WindowLongConstants.GWL_STYLE) & WindowStyles.WS_EX_APPWINDOW; + //if (wl <= 0) + // return false; + + //判断是否是游戏全屏 + User32Wrapper.GetWindowRect(handle, out var r); + + //System.Diagnostics.Debug.WriteLine($"pid:{pid} r:{r.Left} {r.Top} {r.Right} {r.Bottom} {DateTime.Now}"); + if (r.Left == 0 && r.Top == 0) + { + int with = r.Right - r.Left; + int height = r.Bottom - r.Top; + + if (height == Screen.PrimaryScreen.Bounds.Height + && with == Screen.PrimaryScreen.Bounds.Width) + { + //当前窗口最大化,进入了游戏 + var foregroundWIndow = User32Wrapper.GetForegroundWindow(); + if (foregroundWIndow == handle) + { + _ = User32WrapperEx.GetWindowTextEx(handle); + //var desktop = User32Wrapper.GetDesktopWindow(); + if (className == "WorkerW") + return false; + return true; + } + } + } + } + return false; + } + } +} \ No newline at end of file