草庐IT

windows - 从外部窗口的 GetWindowRect 获取 DPI 感知正确的 RECT

coder 2023-11-09 原文

我正在制作一个应用程序 DPI Aware,但我需要对来自其他应用程序的 HWND 执行 GetWindowRect。我的问题是这在同样具有 DPI 感知能力的应用程序上运行良好,但我如何检测 HWND 句柄是否为 DPI 虚拟化,例如缩放以便我可以自己缩放?或者是否有其他我错过的 API 可以从另一个进程的 HWND 中以 DPI 感知方式为我提供窗口大小?

我已经尝试过 LogicalToPhysicalPoint 但似乎总是失败,可能是因为 HWND 不属于我的应用程序。

最佳答案

这不是实际问题。如果您将您的进程标记为高 DPI 感知,那么系统将不再进行任何类型的 DPI 虚拟化,并且 API 将不再欺骗您实际值。

特别是,如果您从高 DPI 感知应用程序调用 GetWindowRectGetClientRect,您将获得屏幕坐标中的实际值 .这不仅适用于属于您的应用程序进程的窗口,也适用于属于其他进程的窗口,无论其他进程的 DPI 感知设置如何。

从 Windows 8.1 开始,PhysicalToLogicalPointLogicalToPhysicalPoint功能不再是必需的,实际上不做任何事情。这两个函数的文档明确指出了这一点:

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.

最后一句话只是我上面所说的一种不同的措辞方式。 系统根据调用者的 DPI 感知返回值。如果您的进程是高 DPI 感知的,那么您将获得真正的值。您不需要自己缩放值。如果您不了解高 DPI,那么您可能会在实际值方面被骗。但这是有道理的,因为假设您无法处理真相并且不会做出适当的 react 。

为了清楚起见,我应该指出,从 Windows 8.1 开始(并在 Windows 10 中继续),现在实际上有两个级别的高 DPI 感知:

  1. 第一层是高 DPI 感知,早在 Windows Vista 中就引入了。这由应用程序 list 文件中的 true 设置指示,它仅意味着您(应用程序)能够处理设置为的系统 DPI经典默认值 96 DPI 以外的东西。

    根据以上知识,那么,我们知道,如果具有此 DPI 感知设置的进程调用返回屏幕坐标的 API 函数,它将收到系统 DPI 的值。

  2. 然后是随 Windows 8.1 引入的新级别,即 per-monitor 高 DPI 感知。这由应用程序 list 中的 True/PM 设置指示,这意味着您(应用程序)能够处理具有不同 DPI 设置的不同显示器。换句话说,虽然系统默认 DPI 仍然存在(可能是 96 DPI,也可能是其他),但可能有连接到系统的显示器使用不同的 DPI 设置(不同于系统 DPI 的设置)。

    同样,基于上述理解,我们知道,如果一个每个监视器高 DPI 感知的进程调用一个返回屏幕坐标的 API 函数,它将收到相对于包含的监视器 DPI 的实际坐标有问题的窗口。

如果您的进程根本不知道 DPI( list 中没有设置,或者 false),那么当您调用返回屏幕坐标的 API 函数时,您将收到基于缩放/虚拟化的坐标在 96 DPI 的全系统 DPI 上。

关于windows - 从外部窗口的 GetWindowRect 获取 DPI 感知正确的 RECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8060280/

有关windows - 从外部窗口的 GetWindowRect 获取 DPI 感知正确的 RECT的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  3. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  4. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  5. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  6. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  7. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  8. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  9. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  10. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

随机推荐