Win 10 Excel 2016 无法解释的 PixelsToPoints 系数来定位用户窗体

2024-03-27

序言

当尝试将用户窗体定位在特定像素位置(存储在POINTAPI类型结构),必须将 Pixel 坐标转换为 Point 坐标才能设置UserForm.Left and UserForm.TopVBA 属性。我们称这个系数为K。

从我的测试中,我开始了解到,就我而言,GetWindowRect以及 UserForm 的 VBA 定位属性 (Left, Top, Width, Height)包括包含 MSForm UserForm 控件的窗口(属于“ThunderDFrame”类)周围的阴影。要真正获得由边框界定的窗口矩形,DwnGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, rcOutRECT, LenB(rcOutRECT)必须使用Win API。

定位 UserForm 的坐标系原点是 Pixel (0; 0),所以无需担心ActiveWindow.PointsToScreenPixelsX / ActiveWindow.PointsToScreenPixelsY以及 Excel 窗口的左上角与工作表网格的左上角之间的偏移量(至少直到Range.Left, Range.Top等属性发挥作用)。然而,有趣的是,ActiveWindow.PointsToScreenPixelsX行为不像ActiveWindow.ActivePane.PointsToScreenPixelsX。第一个使用具有输入的像素,而不是像第二个那样使用点。该方法的真实名称应该是ActiveWindow.WorksheetPixelsXToScreenPixelsX。您可以轻松验证:

ActiveWindow.PointsToScreenPixelsX(1) - ActiveWindow.PointsToScreenPixelsX(0)

返回 1,而如果它确实在进行转换,则应该返回大于 1 的值,因为 1 Point 占用屏幕上的多个像素。 (由于像素的整数舍入,也不是真正的 1/K)

Problem

考虑到缩放系数为 1 以简化我的 MCV 示例,确定的系数.Left and .Top我们希望其显示的屏幕像素中 (x; y) 位置的用户窗体的 Points 属性应该是:

72 / GetDeviceCaps(GetDC(0), LOGPIXELSX)
72 / GetDeviceCaps(GetDC(0), LOGPIXELSY)

这是

  • 96 DPI 传统显示屏为 0.75(我已在使用 Win 7 + Excel 2007 的 PC 上尝试过)
  • 0.375,我的 Surface Pro 4 平板电脑在 Win 10 64 位和 Excel 2016 32 位上运行

现在的问题是,在我的平板电脑上,虽然上述计算返回 0.375,定位用户窗体的正确系数在给定的像素位置(从GetCursorPos以Win API为例)通过将其转换为对应的Point位置is 0.35. 我不知道这个价值从哪里来......???

现在的进展

在平板电脑上:

reg key HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\AppliedDPI表示 192 和72 / 192 = 0.375

我还尝试了 MSDN Windows 桌面应用程序 UI 参考中的高 DPI 参考中的一些功能:

  • GetDPIForWindow(我尝试使用Application.Hwnd和UserForm的窗口句柄)
  • GetDPIForMonitor

但一切都会正常返回 192。

最小、完整且可验证的示例

以下内容允许我在平板电脑上检索神秘的 K = 0.35 系数,但在另一台计算机上返回 0.75,正如预期的那样。

模块1.bas

Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, rcWindowRect As RECT) As Long
Private Declare Function GetCursorPos Lib "user32" (ptCursorPoint As POINTAPI) As Long

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Sub test()
    Dim rcUsfWindowRect As RECT
    UserForm1.Show vbModeless
    lRet& = GetWindowRect(UserForm1.hWnd, rcUsfWindowRect)
    dblUsfRectWidth# = rcUsfWindowRect.Right - rcUsfWindowRect.Left
    dblUsfRectHeight# = rcUsfWindowRect.Bottom - rcUsfWindowRect.Top
    Debug.Print UserForm1.Width / dblUsfRectWidth
End Sub

用户表单1

Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public hWnd As Long

Private Sub UserForm_Initialize()
    hWnd = FindWindowA("ThunderDFrame", UserForm1.Caption)
End Sub

我有同样的问题。我在 64 位上尝试了你的代码,也收到了 0.35。

module1

Option Explicit

Private Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As Long, rcWindowRect As RECT) As Long
Private Declare PtrSafe Function GetCursorPos Lib "user32" (ptCursorPoint As POINTAPI) As Long

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Sub test()
    Dim rcUsfWindowRect As RECT
    Dim dblUsfRectWidth As Double
    Dim dblUsfRectHeight As Double
    
    UserForm1.Show vbModeless
    Call GetWindowRect(UserForm1.hWnd, rcUsfWindowRect)
    dblUsfRectWidth = rcUsfWindowRect.Right - rcUsfWindowRect.Left
    dblUsfRectHeight = rcUsfWindowRect.Bottom - rcUsfWindowRect.Top
    Debug.Print UserForm1.Width / dblUsfRectWidth
End Sub

用户表单1

Option Explicit

Private Declare PtrSafe Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public hWnd As Long

Private Sub UserForm_Initialize()
    hWnd = FindWindowA("ThunderDFrame", UserForm1.Caption)
End Sub

奇怪的是,我下载了一个标尺应用程序来测量 UserForm1 的宽度(以像素为单位)。我将 Excel 中表单的宽度调整为 500,结果我得到的测量宽度为 1406 像素。并且 500/1406 = 0.356 而不是 0.375。 我还发现了为什么它是 0.356 而不是 0.35,这是因为 GetWindowRect 函数显然返回一个宽度,包括边框周围的阴影。 (左边是 15 或 16 像素,右边是 10 像素)。如果没有这个,宽度将为 1406 + 15 + 10 = 1431 和 500/1431 = 0.349,更接近 0.35。

我之前的笔记本电脑上没有出现这些问题,并且使用外接显示器也没有出现这些问题。这种情况仅发生在高 DPI 显示器上。 (可能是因为 Windows 中的这些显示器启用了显示虚拟化)。

编辑: 如果我将窗口缩放更改为 100% 注销并重新登录,我会得到 0.75 的值,一切都会按预期进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Win 10 Excel 2016 无法解释的 PixelsToPoints 系数来定位用户窗体 的相关文章

  • Access 2013/2016 不支持树形视图控件,给出错误消息“用户定义的类型未定义”

    我有一个 VBA 项目 可以完美运行到 Windows 7 32 64 位 和 Office 2010 但是当我尝试在 Office 2013 或 2016 上运行它时 它不会加载树视图控件并在以下位置给出错误 私有 SelectedNod
  • 如何防止Excel单元格更新?

    我有一个相当大的范围 10 000 行 10 列 我每天都会逐行填充它 我还有一个较小的范围 366 行 5 列 其中 对于每个单元格 我运行一个宏 该宏的作用与 DSUM 或 SUMIF 的作用几乎相同 但具有多个条件 问题是 在实现了这
  • 如何使用 VBA 或 Powershell 将列表从具有 NTLM 身份验证的 Sharepoint 服务器导出到 Excel

    我的雇主要求我找到一种从使用 NTLM 身份验证的 SharePoint 2013 Server 自动下载 更新 SharePoint 列表的方法 执行此操作的可能方法是 VBA 或 Powershell 我想要提取的列表属于我公司的业务合
  • 如何在 VBA 中的 Outlook-2007 中获取“已发送邮件”文件夹中的邮件 ID 或标头

    这是这个问题的一个子问题main https stackoverflow com questions 14418643 in ms outlook report all sent messages that havent received
  • 如何使用单元格内的十六进制颜色值突出显示单元格?

    我有一个符号和匹配的十六进制颜色的电子表格 我想用单元格内的十六进制颜色填充单元格本身 或其旁边的单元格 我读过一些有关 条件格式 的内容 我认为这就是实现的方法 我怎样才能达到我想要的结果 条件格式无法实现所有颜色 假设 Row1 包含数
  • 查找使用连接的位置 Excel VBA

    我有大量需要优化的 Excel 2013 工作簿 每个工作簿都有多个工作表和多个数据连接 我正在寻找一种快速列出的方法 连接名称 连接字符串 使用连接的位置 工作表名称或范围很有用 我可以在连接对话框中看到所有这些信息 但无法以编程方式跟踪
  • 更新 SQL MS Access 2010

    这已经让我绞尽脑汁了 4 个小时了 我有一个名为 BreakSked 的表 我使用此按钮来使用此 sql 更新表的休息结束时间 strSQL1 UPDATE BreakSked SET BreakSked EndTime Me Text41
  • 每次更改工作表时运行宏

    我对宏还很陌生 每次更新 更改或其他任何操作时 我都需要在工作表上运行一些代码 这是我需要运行的代码 我怎样才能做到这一点 Sub UnMergeFill Dim cell As Range joinedCells As Range For
  • 如何在 VBA 中克隆范围对象

    我正在使用 Excel Visual Basic 编辑器在 VBA 中编写 Excel 宏 我不知道如何复制 克隆范围对象 而不是创建对同一对象的第二个引用 MemberwiseClone 函数似乎不可用 我认为它将针对内置类型实现 我需要
  • 为什么从 Evaluate 调用时 VBA Find 循环失败?

    当使用 Application Evaluate 或 ActiveSheet Evaluate 方法调用例程时 我在子例程内运行查找循环时遇到一些问题 例如 在下面的代码中 我定义了一个子例程 FindSub 它在工作表中搜索字符串 xxx
  • Excel VBA 将工作表保存到具有唯一名称的多个文件夹

    感谢您的所有意见 下面的代码是收到的输入的最终结果 我已经对这些错误进行了评论 这些错误直接关系到保存到数组中定义的文件夹中的总体预期结果 Option Explicit Public EngName As String TeamNum A
  • VBA COM 库中的这些 _B_var_Xxxxx 和 _B_str_Xxxxx 成员到底是什么?

    想象一下以下函数调用 foo UCase bar 我正在解析这段代码 并确定UCase是一个函数调用 现在我想将该函数调用解析为定义它的 COM 库中函数的声明 这个想法是实现一个代码检查来确定何时Variant当使用内置函数时String
  • 如何使用 VBA 将符号/图标格式化为单元格而不使用条件格式

    我使用 VBA 代码放置条件格式以覆盖大型表格中的值 每个单元格使用 2 个公式来确定使用 3 个符号中的哪一个 我需要根据列使用不同的单元格检查每个单元格的值 因此据我了解 我必须将条件格式规则单独放置在每个单元格上 以确保每个单元格中的
  • Javascript 链接在 selenium excel vba 中没有响应

    我正在尝试做这样一行点击 javascript 链接的操作 FindElementById ctl00 ContentPlaceHolder1 LinkButton4 WaitDisplayed True 3000 Click 这条线没有任
  • 查询不可更新

    我正在尝试使用 BE SQL Server 2012 Express 中的记录更新本地 Access 2007 表 我的步骤在这里 SQL Server中存在带有4个参数的存储过程来获取所需的记录 Access VBA中有调用SP并进行临时
  • Excel VBA:通过快捷键运行打开文档后宏挂起,但从 VB 编辑器运行完美

    我遇到了一个奇怪的问题 我决定分配一个键盘快捷键Ctrl Shift P我的 VBA 例程之一 该例程假设打开一个现有的 Excel 工作簿 复制一些信息并 SaveAs另一个名字 当我在 Visual Basic 编辑器中点击 播放 时
  • VBA中工作表变化的递归调用

    我已经创建了包含多个工作表的工作簿 我正在尝试使用 WorkSheet ChangeSheet1 即工作表 1 上的某些更改正在复制到工作表 2 中 同样 如果有任何改变Sheet2我想做出类似的改变Sheet1以及 这样做时 两张表上都会
  • 使用 VBA 清除 Excel 单元格格式而不清除 NumberFormat

    是否可以在不改变 的情况下清除Excel单元格格式和内容 使用VBA NumberFormat 给定的单元格 我尝试过 ClearContents ClearFormats 但 ClearFormats 删除了数字格式细胞也 请建议 你可以
  • 通过vba在每个空间范围之间添加求和公式

    我试图进行自动化 但我被困在这里 我需要在空间范围之间动态添加总和公式 我完全迷失了使用 VBA 添加公式的能力 任何人都可以帮助我 先感谢您 我假设您想要的是 如果单元格中有空白 您希望将所有其他元素相加并将结果放置在该空白中 可能有很多
  • 按日期计算 Outlook 中的电子邮件

    我有以下代码来计算 Outlook 文件夹中的电子邮件数量 Sub HowManyEmails Dim objOutlook As Object objnSpace As Object objFolder As Object Dim Ema

随机推荐

  • 如何离线存储密码

    虽然这是针对Windows Phone 7的 但我想这个原理是通用的 我想在我的应用程序中设置一个密码保护区 但是 我的应用程序完全离线 因此我必须在手机上存储凭据详细信息 我最初的想法是存储密码和盐的哈希值 这是最好的方法吗 如果是这样
  • 更改特定索引而不在 Vuejs 中重新渲染整个数组

    In a Vuejs项目 我有一个array in my 数据对象并将其呈现在视图中v for指示 现在 如果我更改该数组中的特定索引 Vue 会在视图中重新渲染整个数组 有没有办法在不重新渲染整个数组的情况下查看视图的变化 这个问题背后的
  • 如何处理 JSON 字符串中的 unicode 值?

    我正在用 C 编写 JSON 解析器 在解析 JSON 字符串时遇到问题 JSON 规范规定 JSON 字符串可以包含以下形式的 unicode 字符 here comes a unicode character u05d9 我的 JSON
  • 如何获取要执行的 PTX 文件

    我知道如何生成 ptx文件来自 cu以及如何生成 cubin文件来自 ptx 但我不知道如何获得最终的可执行文件 更具体地说 我有一个sample cu文件 编译为sample ptx 然后我使用 nvcc 来编译sample ptx to
  • 如何在Oracle中查找模式名称?当您使用只读用户连接到 SQL 会话时

    我使用只读用户连接到 Oracle 数据库 并且在 sql Developer 中设置连接时使用了服务名称 因此我不知道 SID 架构 如何找到我连接到的架构名称 我正在寻找这个 因为我想要生成 ER 图 https stackoverfl
  • 按方案中的第一个元素对列表列表进行排序

    例如 我正在研究按第一个元素对列表列表进行排序 排序 列表 2 1 6 7 4 3 1 2 4 5 1 1 预期输出 gt 1 1 2 1 6 7 4 3 1 2 4 5 我使用的算法是冒泡排序 我修改了它来处理列表 但是 该代码无法编译
  • jQuery Mobile 范围滑块响应不够灵敏

    各位互联网界的好心人 大家好 我正在尝试使用 jQuery Mobile 滑块 范围 虽然它们工作得相当好并且在桌面浏览器上响应良好 但它们似乎在实际手机 例如 Android 与互联网网页交互时 Android 上使用触摸屏的滑块交互非常
  • Facebook SDK:ApiException:代理应用程序在未事先安装的情况下无法请求发布权限

    我正在努力使用 Android facebook SDK 3 5 riigth ow 我的账户一切都很完美 现在我把这个应用程序给了我的一个朋友 当他登录时 他并没有因为这个失败而被卡住 ApiException The proxied a
  • Azure 表存储将数据导出到 SQL 的平面或 XML 文件

    I am looking for capability to Export data from SQL Azure Azure Table Storage to Some Flat file or XML file so that we c
  • 如何将我的表单放在 css/html 中的图像之上?

    开发者们好 我想问一下如何才能让我的表单出现在我的图片之上 问题是我的表格出现在底部 这是我的屏幕截图 这是我的代码 HTML div class container align center div img src assets img
  • Fabric 不断要求输入密码

    我有 fab 文件 其中包含 env hosts localhost env user code env password searce def mk dirtree sudo mkdir s PROJECT DIR sudo chown
  • Java中int是如何实现的?

    根据文档Integer class Integer 类将基本类型 int 的值包装在对象中 Integer 类型的对象包含一个类型为 int 的字段 和文档int 默认情况下 int 数据类型是 32 位有符号二进制补码整数 其最小值为 2
  • 在组件安装之前反应设置滚动位置

    我有下面的反应组件 它本质上是一个聊天框 render const messages this props messages return div h1 this props project 0 project h1 div div div
  • 如何在 XCode4 中复制项目目标

    我想为测试环境创建一个具有不同捆绑 ID 的目标 我尝试使用 复制 功能来克隆目标并更改捆绑 ID 发现原始目标也发生了更改 感谢您的任何提示 更新 解决复制目标后的链接错误 这是一个xcode bug 搜索路径中的引号字符 更改为 目标的
  • PostgreSQL bigserial 和 nextval

    我有一个 PgSQL 9 4 3 服务器设置 之前我只使用公共模式 例如我创建了一个如下表 CREATE TABLE ma accessed by members tracking reference bigserial NOT NULL
  • 给定一个 4x4 齐次矩阵,我如何获得 3D 世界坐标?

    所以我有一个正在旋转然后再次平移和旋转的对象 我将这些翻译的矩阵存储为对象成员 现在 当我进行对象拾取时 我需要知道该对象的 3D 世界坐标 目前我已经能够像这样获得物体的位置 coords 0 finalMatrix 12 坐标 1 最终
  • h2o.saveModel 在 Windows 8 上抛出目录异常

    我在 R 中使用 h2o 版本 3 0 0 22 并尝试保存我的模型 但我似乎无法弄清楚预期的格式 我尝试了各种变化 但遇到了各种不同的异常 h2o saveModel model dir c temp name my model ERRO
  • Python - 基于 LSTM 的 RNN 需要 3D 输入?

    我正在尝试构建一个基于 LSTM RNN 的深度学习网络 这是尝试过的 from keras models import Sequential from keras layers import Dense Dropout Activatio
  • "message":"没有活动连接","node_env":"生产"

    我正在尝试在我的计算机上安装 Kibana 4 但出现以下错误 timestamp 2015 04 15T06 25 50 688Z level error node env production error Request error r
  • Win 10 Excel 2016 无法解释的 PixelsToPoints 系数来定位用户窗体

    序言 当尝试将用户窗体定位在特定像素位置 存储在POINTAPI类型结构 必须将 Pixel 坐标转换为 Point 坐标才能设置UserForm Left and UserForm TopVBA 属性 我们称这个系数为K 从我的测试中 我