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 字节数据类型。

你可以阅读更多关于LongPtrHere的信息

万一上面的链接失效了……

LongPtr32 位系统上的长整数,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 会发生什么? 我不确定我是否理解你。如果应用程序hwnd11872538,那么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? 我不确定,所以我不会对此发表评论。我可以肯定地说FindwindowApplication.Hwnd 永远不会为同一个窗口提供不同的值。这也可以使用 Spy++ 进行验证 @siddharth-rout - 很好的答案,但我不知道微软实际上对编译器中的 PtrSafe 声明和 LongPtr 数据类型做了什么,除了对 32- 和 64- 进行运行时检查位互操作性:我推测 LongPtr 地址和内存不会像普通整数那样被垃圾收集,因为“安全指针”概念不仅仅是一个 32 位兼容性实现。

以上是关于Excel 的 Application.Hwnd 属性是不是可用于 64 位 VBA?的主要内容,如果未能解决你的问题,请参考以下文章

c# winform 向用户显示具有指定所有者的窗体

Excel表格自动排序的方法

如何在网页中嵌入excel控件,实现excel的在线编辑?

excel宏怎么删除啊?

excel文件加密怎么解密(excel文件加密怎么解除)

Java操作excel的问题