代码之家  ›  专栏  ›  技术社区  ›  Dan Andreatta

Aero是否操作dpi和屏幕大小?为什么?

  •  2
  • Dan Andreatta  · 技术社区  · 15 年前

    在我的应用程序中,我通过以下代码获得屏幕分辨率:

    SystemInformation.PrimaryMonitorSize
    

    我用这个代码得到dpi:

        using (Graphics g = Graphics.FromHdc(NativeMethods.GetDC(IntPtr.Zero)))
        {
            dpiX = g.DpiX;
            dpiY = g.DpiY; 
        }
    

    这在大多数情况下都很有效。但是,当代码在打开Aero的Vista机器上运行时,用户设置了高dpi的监视器,奇怪的结果又出现了。

    假设用户将机器设置为1024 x 768并将dpi设置为144,上面的代码将返回683 x 512的分辨率和96的dpi。

    但是,如果关闭Aero,结果会像我预期的那样回来。Aero在做什么?如何获得真正的分辨率和dpi?

    2 回复  |  直到 15 年前
        1
  •  7
  •   Pavel Minaev    15 年前

    你需要 declare your application as DPI-aware 在清单中(首选),或通过使用 SetProcessDPIAware Win32 API函数。因为有太多的应用程序写得不正确,vista添加了“dpi虚拟化”,让应用程序假装在使用“标准”96dpi屏幕,然后自己进行缩放-作为一个合成窗口管理器的dwm可以进行缩放。如果您的应用程序正确地处理不同的dpi,那么您必须明确地这样说。

    旁注,你不应该 HWND_DESKTOP (这就是 (HWND)0 是)。当合成(“aero”)关闭时,它确实代表物理屏幕,因此,如果您得到它的dc并绘制它,则直接绘制到帧缓冲区中。使用合成窗口管理器,这是不可能的 by definition . 我不确定这是否会影响DPI测量,但无论如何,将DC用于应用程序窗口可能是一个更好的主意-它不会造成伤害/