多个高分屏导致 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也有关    
代码
| 12
 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();
 }
 
 |