多个高分屏导致 Aero 主题无法开启
简介
Aero 主题 仅仅是一个受人追捧的毛玻璃效果而已,但是在项目实际使用的时候却发现与 DirectX 渲染效率相关,在未开启 Aero 主题的情况下叠加透明窗体 Device.Present() 方法) 延迟约在 00:00:00.1258071 相比开启了 Aero 主题的延迟约在 00:00:00.0000365,千倍的时间差。
测试结果
换个主题并不是难事,但是面对一个早已不受微软支持的操作系统,对多屏幕的支持不是很好,目前也没什么解决办法,实际测试中 3 块 1080p 显示器及以上无法被动开启 Aero 主题,2 块 4k 显示器及以上无法被动开启 Aero 主题,试过多型号显卡(Quadro P1000、Quadro P2000、Quadro P4000、Gtx 1080、Rtx 2070、Rtx 4000),排除显卡性能问题,试过多版本驱动,但是不排除显卡驱动与 Windows 7 兼容不好。
系统设置上的比对
桌面右键菜单个性化
异常情况左下角提示:解决透明度和其他 Aero 效果问题
证明此时 Windows 7 系统是知道显示存在问题的
解决透明度和其他 Aero 效果问题
点击修复程序,结果却显示很多问题不存在,无法修复
点击个性化中的窗口颜色
此时点击个性化中的窗口颜色,弹出的窗口颜色外观界面不同,异常情况无法设置 Aero 效果
系统性能选项
在系统性能选项卡中异常情况缺少 启用 Aero Peek 选项与其他重要选项
解决方案
在 Windows 7 兼容(4块1080p显示器以下或2块4k显示器以下)允许的范围内解决显示器接入断开导致 Aero 效果失效,软件操作恢复而不用人工操作。
处理方式
- 通过 dwmapi.dll 库的 DwmIsCompositionEnabled 检测 Aero 开启状态
- 通过系统 Environment.OSVersion.Version 方法获取 Windows 版本
- 通过 CMD 命令切换 Aero 主题和启动服务
- 通过 System.ServiceProcess.ServiceController 重启服务
涉及到的服务主要由 UxSms,或可能与 Themes也有关
代码
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
|
[DllImport("dwmapi.dll", PreserveSig = false)] public static extern bool DwmIsCompositionEnabled();
private bool IsWindows7() { return Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1; }
private void RunCmd(string strCmdCommand) { Process cmd = new Process(); cmd.StartInfo.FileName = "cmd"; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.CreateNoWindow = true; cmd.StartInfo.UseShellExecute = false; cmd.Start(); cmd.StandardInput.WriteLine(strCmdCommand); cmd.StandardInput.Flush(); cmd.StandardInput.Close(); cmd.Close(); cmd.Dispose(); }
private bool RecoveryAero() { if (IsWindows7() && !DwmIsCompositionEnabled()) { ServiceController service = new ServiceController("UxSms"); if (service.Status == ServiceControllerStatus.Stopped) { RunCmd("net start UxSms"); } if (!DwmIsCompositionEnabled()) { string strAeroTheme = @"C:\WINDOWS\Resources\Themes\aero.theme"; string strCmdCommand = string.Format(@"rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""{0}""", strAeroTheme); RunCmd(strCmdCommand); Thread.Sleep(5000); } if (!DwmIsCompositionEnabled()) { try { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped); service.Start(); service.WaitForStatus(ServiceControllerStatus.Running); } catch {
} } } return DwmIsCompositionEnabled(); }
|