我可能用 "Disable Display Scaling?" 修复了什么错误

What bug did I probably fix with "Disable Display Scaling?"

我继承了现在必须在 Windows 10 上 运行 的遗留应用程序。在测试期间,我们发现该程序的一部分(它是一个子 window 作为工具栏)在程序启动时只会部分绘制——工具栏右侧的一半以上只会绘制黑色。在 运行 时,修复是调整整个 window 的大小,这将 resize/redraw 工具栏 window。我们最终发现,如果我们设置 "Disable display scaling" 似乎可以完全防止错误(到目前为止,测试的置信度刚刚超过万分之一,这对我来说已经足够了)。

问题是:

这个错误的发生概率只有 1/12 到 1/20(这是我从我们的程序自动测试视频中确定的,它涉及 185 个错误发生的机会。没有发生的模式被识破)。我从来没有遇到过这样的错误,所以我想知道:鉴于错误的明显随机性和修复,发生了什么? Windows 然后升级为 "high DPI" 的位图渲染与布置工具栏的功能之间的竞争条件?

Windows10 扩展了DPI意识的概念。以前,DPI 感知是针对每个进程设置的,但现在它是针对每个线程的概念。 MSDN docs 措辞现在有点难以破译,但听起来调用 SetProcessDPIAwareness(我希望遗留应用程序正在做)只影响调用线程(尽管名称中有 "Process")。

理论 #1:也许您的工具栏 window 有时是在具有 DPI 感知的线程上创建的,有时是在不同的线程上创建的。

理论 #2:调用 SetProcessDPIAware 的应用程序与一些 UI 缓存显示指标的代码之间存在竞争,后者稍后用于绘制工具栏 window。根据谁赢得比赛,您可能会得到不正确的行为。

文档建议较旧的应用程序(a.k.a.,遗留应用程序)使用清单设置为整个过程设置 DPI 感知。我相信这将确保该设置应用于进程中的所有线程,并且它应该在任何用户代码运行之前发生,因此不应该存在竞争。由于禁用缩放似乎可以解决问题,并且设置 DPI 感知应该大致相当于(实际上),如果任何一种理论都是正确的,我希望这可以解决问题。

documentation for SetProcessDpiAware 解释了如何使用清单设置 DPI 感知。