Excel的Application.Hwnd属性能在64位VBA中使用吗?

4 浏览
0 Comments

Excel的Application.Hwnd属性能在64位VBA中使用吗?

我需要从在电子表格中运行的64位VBA代码中获取Excel 2013 x64窗口句柄。有几种方法可以做到这一点:

Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _

ByVal lpClassName As String, _

ByVal lpWindowName As String) As LongPtr

问题是,Application.Hwnd返回的是一个Long,即32位(我在64位环境中使用MsgBox TypeName(Application.Hwnd)进行了验证),而FindWindow返回的是一个LongPtr,在Office x64中是64位长。

这是否意味着在64位环境中无法始终相信Application.Hwnd属性是正确的?

0
0 Comments

Excel的Application.Hwnd属性在64位VBA中可用吗?

这个问题的出现是因为在64位版本的Office 2010中,LongPtr是一个变量数据类型,它在32位版本上是一个4字节的数据类型,在64位版本上是一个8字节的数据类型。LongPtr的介绍可以在这里阅读。

如果上述链接失效...

LongPtr(32位系统上的Long整数,64位系统上的LongLong整数)变量被存储为有符号32位(4字节)数字,其值范围为-2,147,483,648到2,147,483,647,64位系统上的有符号64位(8字节)数字,其值范围为-9,223,372,036,854,775,808到9,223,372,036,854,775,807。

注意

LongPtr不是一个真正的数据类型,因为它在32位环境中转换为Long,在64位环境中转换为LongLong。使用LongPtr可以编写可在32位和64位环境中运行的可移植代码。对于指针和句柄,请使用LongPtr。

建议进一步阅读:

兼容性:32位和64位Office 2010版本之间的兼容性

从评论中的跟进

然而,我担心由于FindWindow可能返回一个较大的值,窗口句柄可能会超过32位的值。如果是这样,那么Application.Hwnd将无法返回正确的值。或者你是说窗口句柄永远不会超过32位?

以下链接很好地解释了这个问题。

32位和64位应用程序之间的进程间通信

非常感谢您的回答。让我确定一下:FindWindow返回64位,这表明窗口句柄可以超过32位的值。然而,Application.Hwnd只返回32位。所以如果一个窗口句柄的值超过32位的最大值,Application.Hwnd会发生什么?

我不确定是否理解您的意思。如果应用程序hwnd为11872538,则Findwindow将返回相同的值。您还可以使用Spy++来检查。64位的Findwindow使用LongPtr进行兼容性处理,因为某些应用程序可能具有更大的hwnd。

感谢您的回复。我了解如果句柄的值介于-2,147,483,648和2,147,483,647之间,那么两种方式都会返回相同的值。然而,我担心由于FindWindow可以返回一个较大的值,窗口句柄可能会超过32位的值。如果是这样,那么Application.Hwnd将无法返回正确的值。或者你是说窗口句柄永远不会超过32位?

“或者你是说窗口句柄永远不会超过32位?”对于这个我不确定,所以我不会对此发表评论。我可以确定的是,对于同一个窗口,Findwindow和Application.Hwnd不会给出不同的值。这也可以使用Spy++来验证。

刚刚发现这个链接。

-rout - 回答很好,但我不知道Microsoft在编译器中实际上对PtrSafe声明和LongPtr数据类型做了什么,除了在32位和64位互操作性方面进行运行时检查之外:我会猜测LongPtr地址和内存的垃圾回收方式与普通整数不同,因为“安全指针”概念不仅仅是32位兼容性实现。

0