Getting an DPI aware correct RECT from GetWindowRect from a external window

前端 未结 2 1835
有刺的猬
有刺的猬 2020-12-31 04:15

I\'m in the process of making an application DPI Aware but I have a need to do a GetWindowRect on HWNDs from other applications. My problem is this works fine o

相关标签:
2条回答
  • 2020-12-31 05:02

    This is not an actual problem. If you mark your process as high-DPI aware, then the system will no longer do any sort of DPI virtualization and the APIs will no longer lie to you about the actual values.

    In particular, if you call GetWindowRect or GetClientRect from a high-DPI aware application, you will get the actual values in screen coordinates. This will be true not only for windows belonging to your application's process, but also for windows belonging to other processes, regardless of that other process's DPI awareness setting.

    As of Windows 8.1, the PhysicalToLogicalPoint and LogicalToPhysicalPoint functions are no longer necessary and don't actually do anything. The documentation for these two functions calls this out explicitly:

    In Windows 8.1, the additional virtualization of the system and inter-process communications means that for the majority of applications, you do not need these APIs. As a result, in Windows 8.1, PhysicalToLogicalPoint and LogicalToPhysicalPoint no longer transform points. The system returns all points to an application in its own coordinate space.

    The last sentence is just a different way of phrasing what I said above. The system returns values according to the DPI awareness of the caller. If your process is high-DPI aware, then you will get the real values. You do not need to scale the values yourself. If you are not high-DPI aware, then you are subject to being lied to about the actual values. But that makes sense, because it is assumed that you cannot handle the truth and will not react appropriately.

    Just to be clear, I should point out that there are actually two levels of high-DPI awareness now, as of Windows 8.1 (and continued in Windows 10):

    1. There is the first level, introduced way back with Windows Vista, of high-DPI awareness. This is indicated by a setting of true in the application's manifest file, and it just means that you (the application) is able to deal with a system DPI that is set to something other than the classic default of 96 DPI.

      Based on the above knowledge, then, we know that if a process with this DPI-awareness setting calls an API function that returns screen coordinates, it will receive the values in terms of the system DPI.

    2. Then there is the new level, introduced with Windows 8.1, of per-monitor high-DPI awareness. This is indicated by a setting of True/PM in the application's manifest, and it means that you (the application) is able to deal with different monitors having different DPI settings. In other words, while there is still a system default DPI (and it may be 96 DPI or it may be something else), there may be monitors attached to the system that use a different DPI setting (something other than the system DPI).

      Again, based on the above understanding, we know that if a process that is per-monitor high-DPI aware calls an API function that returns screen coordinates, it will receive the actual coordinates relative to the DPI of the monitor that contains the window in question.

    If your process is not DPI aware at all (no setting in the manifest, or false), then when you call API functions that return screen coordinates, you will receive the coordinates scaled/virtualized based on a system-wide DPI of 96 DPI.

    0 讨论(0)
  • 2020-12-31 05:07

    DPI aware flag is set over application level and not the window level So if you are able to get the process of that particular window handle of other application then you can use GetProcessDpiAwareness() function to get the dpi aware flag of that particular process please see this microsoft documentation https://msdn.microsoft.com/en-us/library/windows/desktop/dn302113(v=vs.85).aspx

    0 讨论(0)
提交回复
热议问题