在每个监视器感知的应用程序中,子窗口与父项具有相同的DPI吗?

时间:2017-01-29 03:15:11

标签: windows winapi dpi

可选背景信息

不久之前,我问this question哪些内容专门讨论了文本大小和DLU,而且没有让我意识到每个DPI意识的实际意义。然而,它永远不会去任何地方。通过询问我的特定于实现的问题而不是由它产生的一般问题(" xX问题"?)来写一个明确的问题,这很可能是我的错。

我问了这个问题,因为我正在编写一个动态GUI布局引擎 - 可以处理控制存在和可见性的变化 - 并且需要知道基本单元相对于哪个窗口。当时,我决定坐标应该基于父母,尺寸应该基于孩子,但现在我意识到,如果孩子的DPI大于父母,那么会引起问题。第

当然,这种类型的东西不仅仅是DLU计算。例如,在两个垂直两半上绘制图片的窗口将不得不担心每个监视器DPI在中间向下变化。因此,请允许我提出一般的,毫不含糊的问题。

实际问题

今天我发现了这两篇MSDN文章:

阅读完之后,我现在对系统DPI意识有了解:

  • PROCESS_SYSTEM_DPI_AWARE
    • 当被问及某事物的DPI时,系统将给出主监视器的DPI
    • 此值不能,因此在程序的整个生命周期内都不会改变
    • 相当于调用较旧的SetProcessDPIAware()
  • PROCESS_DPI_UNAWARE
    • PROCESS_SYSTEM_DPI_AWARE类似,但DPI​​固定为96
  • PROCESS_PER_MONITOR_DPI_AWARE
    • 系统给出了一个窗口碰巧打开的监视器的DPI;如果更改,则会发送WM_DPICHANGED
    • 该消息的页面显示,如果监视器DPI发生变化,也会发生这种情况;我现在还不知道你能做到这一点

我想知道的是:

PROCESS_PER_MONITOR_DPI_AWARE的情况下,窗口的所有子窗口(非拥有)的DPI是否与父窗口的窗口相同?

注意最高级:关于DPI的部分没有改变程序的生命周期意味着答案是"是"对于其他两个意识值。

或者作为另一个例子,让我们说我有一个300px宽的窗口,两个控件,两个100px宽,在相对的边缘。如果我在具有不同DPI的两个监视器之间拖动该窗口,使得其中一个控件位于一个监视器上而另一个控件位于另一个监视器上,然后查询其DPI(使用GetDC()GetDeviceCaps()),他们会一样吗?

如果答案是肯定的,那么我就不用担心在父窗口和子窗口之间转换坐标了。

如果答案是否定的,那么下一个问题是WM_DPICHANGED是发送到子窗口,还是仅发送到顶层?因为我仍然需要一种方法来知道孩子的DPI何时发生变化,所以我至少可以尝试重新排列它以使其看起来正确(我还没有想出怎么做,哪个完全是另一个问题,但我认为应该只是MulDiv())。

感谢。

1 个答案:

答案 0 :(得分:1)

当系统确定大部分窗口已经越过另一台监视器时,顶级窗口将被发送WM_DPICHANGED,并且预计整个窗口将针对新DPI调整大小。

换句话说,系统不会尝试使用混合DPI的窗口。