是Excel';s Application.Hwnd属性是否可从64位VBA使用?
我需要从电子表格中运行的64位VBA代码中获取Excel 2013 x64窗口句柄。有两个选项可以执行此操作:是Excel';s Application.Hwnd属性是否可从64位VBA使用?,vba,excel,64-bit,window-handles,Vba,Excel,64 Bit,Window Handles,我需要从电子表格中运行的64位VBA代码中获取Excel 2013 x64窗口句柄。有两个选项可以执行此操作: 阅读Application.Hwnd() 调用从user32导入的FindWindow,例如,如此处接受答案中所述: 声明PtrSafe函数findwindowlib“user32”别名“FindWindowA”(_ ByVal lpClassName作为字符串_ ByVal lpWindowName(作为字符串)作为LongPtr 问题是Application.Hwnd返回一个L
- 阅读
()Application.Hwnd
- 调用从user32导入的FindWindow,例如,如此处接受答案中所述:
Application.Hwnd
返回一个Long
,即32位(我已经在64位环境中用MsgBox TypeName(Application.Hwnd)
验证了这一点),而FindWindow
返回一个LongPtr
,在Office x64中为64位
这是否意味着不能相信Application.Hwnd
属性在64位环境中总是正确的
这是否意味着不能相信Application.Hwnd
属性在64位环境中总是正确的
不,那不是真的。LongPtr
只是一种可变数据类型,在32位版本上是4字节数据类型,在64位版本上是8字节数据类型
您可以阅读有关LongPtr
如果上面的链接死了
LongPtr
(32位系统上为长整数,64位系统上为长整数)变量存储为有符号32位(4字节)数字,在32位系统上的值范围为-2147483648到2147483647
;在64位系统上,有符号的64位(8字节)数字的值范围从-9223372036854775808到9223372036854775807
注意
LongPtr
不是真正的数据类型,因为它在32位环境中转换为Long,在64位环境中转换为LongLong
。使用LongPtr
可以编写可在32位和64位环境中运行的可移植代码。对指针和句柄使用LongPtr
建议进一步阅读:
评论的后续行动
然而,我担心由于FindWindow可以返回一个更大的值,窗口句柄在某个阶段可能会超过32位。如果这是真的,那么Application.Hwnd将无法返回正确的值。或者你是说窗口句柄永远不会超过32位
下面的链接很好地解释了这一点。
非常感谢您的回答。让我确保我们在同一页:
FindWindow
返回64位,这表明窗口句柄可以超过32位的值。但是,Application.Hwnd
仅返回32位。因此,如果窗口句柄可以超过32位的最大值,那么Application.Hwnd
会发生什么情况?我不确定是否理解您的意思。如果应用程序hwnd
是say11872538
,则Findwindow
将返回相同的值。您还可以使用Spy++来检查这一点<64位的code>Findwindow使用LongPtr
实现兼容性,因为某些应用程序可能具有更大的hwnds
,感谢您的回复。我知道如果句柄是一个介于-2147483648和2147483647之间的值,那么两种方法都将返回相同的值。然而,我担心由于FindWindow可以返回一个更大的值,窗口句柄在某个阶段可能会超过32位。如果这是真的,那么Application.Hwnd
将无法返回正确的值。或者你是说一个窗口句柄永远不会超过32位?或者你是说一个窗口句柄永远不会超过32位?
我不确定这一点,所以我将避免对此进行评论。我可以肯定的是,Findwindow
和Application.Hwnd
不会为同一窗口提供不同的值。这可以使用Spy++作为验证工具进行验证well@siddharth-rout-回答得很好,但我不知道Microsoft对PtrSafe声明和编译器中的LongPtr数据类型做了什么,除了对32位和64位互操作性进行运行时检查外:我推测LongPtr地址和内存不会像普通整数那样进行垃圾收集,因为“安全指针”概念不仅仅是32位兼容性实现。这很好,窗口句柄在64位代码中仍然作为32位值工作。高32位始终为0。true@HansPassant. Msdn参考:我文章中的最后一个链接。
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr