兼谈如何写 DPI-Aware 的 windows 程序

作者: admin 分类: 取词 发布时间: 2014-03-13 15:39 ė2,568 浏览数 6没有评论
文章转自王牌软件
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)

我在知乎上这篇关于 AlwaysMouseWheel 的文章说过,AWM 不支持高 dpi,使用有 bug。为什么我会发现呢?因为我有一个笔记本换上了 1080p 的屏幕,然后把 dpi 改成了 1.25x。Windows 从 vista 开始引入了 DPI 虚拟化技术,让 dwm 有权力直接放大窗口,而为了确保兼容性,许多 API——包括 GetCursorPos 和WindowFromPoint——都做了一些处理。

具体表现就是,在旧程序的窗口上方,GetCursorPos 的结果并非鼠标的物理座标,而是经过重新计算的新位置。如果要获取真实的鼠标座标,需要使用 Vista 开始提供的新 API:GetPhysicalCursorPosWindowFromPoint 函数也不能用(事实上使用它会得到相当鬼畜的结果),应该使用WindowFromPhysicalPoint。显然 AlwaysMouseWheel 没有正确地使用新 api,于是它在高 dpi 下就不能正常工作了。

AlwaysMouseWheel 是个典型的鼠标钩子。在 Windows 下,写这种钩子程序最简单的办法是用 AutoHotkey。可能是教主光环过于强大,我在 Github 上找到了一个 类似的项目,然后制作了一个正确的版本。主要修改的地方有:

  • 使用 GetPhysicalCursorPos 获取鼠标座标,替换原来版本里的 AHK 函数
  • 使用 WindowFromPhysicalPoint 获取指针下的窗口
  • 在送滚轮消息前,将 GetPhysicalCursorPos 获取得到的物理座标用PhysicalToLogicalPoint 转换成逻辑座标,生成用于 SendMessage 的lparam

各位下载后,用 autohotkey 最新版运行即可。当然,它必须在 vista 及以上版本的 windows 里方可运行。

其实支持高 dpi,涉及到窗口间互操作的就是 Logical 和 Physical 点的变换问题了。不过我还是挺纳闷的,DPI 虚拟化这个 06 年就有的技术为什么到现在还没几个软件跟进呢?



只回答业务咨询点击这里给我发消息 点击这里给我发消息

学习日记,兼职软件设计,软件修改,毕业设计。

本文出自 学习日记,转载时请注明出处及相应链接。

本文永久链接: https://www.softwareace.cn/?p=729

0

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">


Ɣ回顶部

无觅相关文章插件,快速提升流量