Excel 的 Application.Hwnd 属性是不是可用于 64 位 VBA?
Posted
技术标签:
【中文标题】Excel 的 Application.Hwnd 属性是不是可用于 64 位 VBA?【英文标题】:Is Excel's Application.Hwnd property usable from 64 bit VBA?Excel 的 Application.Hwnd 属性是否可用于 64 位 VBA? 【发布时间】:2015-08-04 12:16:47 【问题描述】:我需要从在电子表格中运行的 64 位 VBA 代码获取 Excel 2013 x64 窗口句柄。有几个选项可以做到这一点:
阅读Application.Hwnd
(MSDN Application.Hwnd Property (Excel))
调用 FindWindow,从 user32 导入,例如如此处接受的答案所述:What are the differences between VBA 6.0 and VBA 7.0?:
声明 PtrSafe 函数 FindWindow Lib "user32" Alias "FindWindowA" (_
ByVal lpClassName 作为字符串,_
ByVal lpWindowName As String) As LongPtr
问题在于Application.Hwnd
返回一个Long
,即32 位(我已经在64 位环境中使用MsgBox TypeName(Application.Hwnd)
验证了这一点),而FindWindow
返回一个LongPtr
,即64 位在 Office x64 中长。
这是否意味着不能相信 Application.Hwnd
属性在 64 位环境中始终正确?
【问题讨论】:
没关系,窗口句柄在 64 位代码中仍然可以作为 32 位值工作。无论如何,高 32 位始终为 0。 true@HansPassant。 Msdn Ref:我帖子中的最后一个链接。 【参考方案1】:这是否意味着不能相信
Application.Hwnd
属性在 64 位环境中始终正确?
不,那不是真的。 LongPtr
只是一个可变数据类型,在 32 位版本上为 4 字节数据类型,在 64 位版本的 Office 2010 上为 8 字节数据类型。
你可以阅读更多关于LongPtr
Here的信息
万一上面的链接失效了……
LongPtr
(32 位系统上的长整数,64 位系统上的长整数)变量存储为带符号的 32 位(4 字节)在 32 位系统上,数值范围为 -2,147,483,648 to 2,147,483,647
;和有符号的 64 位(8 字节)数字,在 64 位系统上的值范围为 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
。
注意
LongPtr
不是真正的数据类型,因为它在 32 位环境中转换为 Long,在 64 位环境中转换为 LongLong
。使用LongPtr
可以编写可在 32 位和 64 位环境中运行的可移植代码。使用LongPtr
作为指针和句柄。
建议进一步阅读:
Compatibility Between the 32-bit and 64-bit Versions of Office 2010
来自 cmets 的跟进
但是,我担心由于 FindWindow 可以返回更大的值,因此窗口句柄在某些阶段可能会超过 32 位。如果这是真的,那么 Application.Hwnd 将无法返回正确的值。还是说窗口句柄永远不会超过 32 位?
下面的链接很好地解释了它。 Interprocess Communication Between 32-bit and 64-bit Applications
【讨论】:
非常感谢您的回答。让我确保我们在同一页面上:FindWindow
返回 64 位,这表明窗口句柄可以超过 32 位的值。但是,Application.Hwnd
只返回 32 位。因此,如果窗口句柄可以超过 32 位可能的最大值,Application.Hwnd
会发生什么?
我不确定我是否理解你。如果应用程序hwnd
是11872538
,那么Findwindow
将返回相同的值。您也可以使用 Spy++ 进行检查。 Findwindow
64 位使用 LongPtr
兼容性,因为某些应用程序可能有更大的 hwnds
感谢您的回复。我知道如果句柄是介于 -2,147,483,648 和 2,147,483,647 之间的值,那么两种方式都会返回相同的值。但是,我担心由于 FindWindow 可以 返回更大的值,窗口句柄 可能 在某个阶段会超过 32 位。如果这是真的,那么Application.Hwnd
将无法返回正确的值。还是说窗口句柄永远不会超过 32 位?
Or are you saying that a window handle will never exceed 32 bits?
我不确定,所以我不会对此发表评论。我可以肯定地说Findwindow
和Application.Hwnd
永远不会为同一个窗口提供不同的值。这也可以使用 Spy++ 进行验证
@siddharth-rout - 很好的答案,但我不知道微软实际上对编译器中的 PtrSafe 声明和 LongPtr 数据类型做了什么,除了对 32- 和 64- 进行运行时检查位互操作性:我推测 LongPtr 地址和内存不会像普通整数那样被垃圾收集,因为“安全指针”概念不仅仅是一个 32 位兼容性实现。以上是关于Excel 的 Application.Hwnd 属性是不是可用于 64 位 VBA?的主要内容,如果未能解决你的问题,请参考以下文章