CSofAndy 发表于 2022-7-14 17:35:00

获取CAD2016应用程序句柄报错问题

如下图所示,代码在CAD2006里不报错,在64位CAD2016里报错,不知什么原因,哪位大神知道怎么获取64位CAD2016句柄。

baitang36 发表于 2022-7-15 09:22:00


是否是数据类型造成的,64位和32位不同。
以下是网上搜到的:
LongPtr (32 位系统上为 Long 整数,在 64 位系统上为 LongLong) 变量存储为:
在 32 位系统上,签名的 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
有关在 64 位 Office 中运行旧 VBA 代码的问题是,尝试将 64 位加载到 32 位数据类型中会截断 64 位数量。 这会导致内存溢出、代码中出现异常结果以及可能的应用程序失败。为了解决此问题并使 VBA 代码能够在 32 位和 64 位环境中正常工作,已向 VBA 中添加几种语言功能。 此文档底部的表对新的 VBA 语言功能进行了汇总。 三个重要的新增功能是 LongPtr 类型别名、LongLong 数据类型和 PtrSafe 关键字。
LongPtr。 VBA 现在包括变量类型别名 LongPtr。 LongPtr 解析为的实际数据类型取决于正在运行的 Office 版本;LongPtr 在 32 位版本的 Office 中解析为 Long,LongPtr 在 64 位版本的 Office 中解析为 LongLong。 将 LongPtr 用于指针和句柄。
LongLong。 LongLong 数据类型是仅在 64 位版本的 Office 中可用的带符号的 64 位整数。 对 64 位整数使用 LongLong。 转换函数必须用于为更小整型显式分配 LongLong(包括 64 位平台上的 LongPtr)。 不允许“LongLong”到更小的整数的隐式转换。
PtrSafe。 PtrSafe 关键字断言 Declare 语句可在 64 位版本的 Office 中安全运行。
重要现在,所有 Declare 语句在 64 位版本的 Office 中运行时,都必须包括 PtrSafe 关键字。 请务必了解,只将 PtrSafe 关键字添加到 Declare 语句只是表示 Declare 语句显式面向 64 位。 语句中需要存储 64 位的所有数据类型(包括返回值和参数)仍必须进行修改,以保留 64 位数量。
备注建议的语法是,将 Declare 语句与 PtrSafe 关键字一起使用。 包括 PtrSafe 的 Declare 语句可在 32 位和 64 位平台上的 VBA7 开发环境中正常运行。若要确保在 VBA7 及早期版本中实现向后兼容性,请使用以下构造:VB复制
#If VBA7 ThenDeclare PtrSafe Sub...#ElseDeclare Sub...#EndIf
请考虑以下 Declare 语句示例。 在 64 位版本的 Office 中运行未修改的 Declare 语句将导致出现一个错误,该错误指示 Declare 语句不包括 PtrSafe 限定符。 修改后的 VBA 示例包含 PtrSafe 限定符,但请注意,返回值(指向活动窗口的指针)将返回 Long 数据类型。 在 64 位 Office 中,这是一种错误情况,因为指针必须是 64 位。 PtrSafe 限定符告知编译器 Declare 语句面向的是 64 位,这样语句在执行时就不会出现错误。 不过,由于返回值尚未更新为 64 位数据类型,因此,截断返回值会导致返回不正确的值。下面是未修改的旧版 VBA Declare 语句示例:VB复制
Declare Function GetActiveWindow Lib "user32" () As Long下面的 VBA Declare 语句示例已修改为包括 PtrSafe 限定符但仍使用 32 位返回值:VB复制
Declare PtrSafe Function GetActiveWindow Lib "user32" () As Long若要重做,必须将 Declare 语句修改为包括 PtrSafe 限定符,并且必须更新语句中需要保留 64 位数量的所有变量,以使这些变量使用 64 位数据类型。下面是一个 VBA Declare 语句示例,它已修改为包括 PtrSafe 关键字,并已更新为使用适当的 64 位 (LongPtr) 数据类型:VB复制
Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr总之,为了让代码在 64 位版本的 Office 中运行,您需要找到所有现有 Declare 语句并将其修改为使用 PtrSafe 限定符。 还需要找到并修改这些 Declare 语句中所有引用句柄或指针的数据类型以使用新的 64 位兼容的 LongPtr 类型别名,以及需要保留 64 位整型和新的 LongLong 数据类型的类型。 此外,必须更新包含指针或句柄的所有用户定义类型 (UDT) 和 64 位整型,以使用 64 位数据类型,并确认所有变量赋值是正确的,以阻止出现类型不匹配错误。编写适用于 32 位和 64 位 Office 的代码若要编写可在 32 位版本和 64 位版本的 Office 之间移植的代码,只需对所有指针和句柄值使用新的 LongPtr 类型别名即可,而不是 Long 或 LongLong。 LongPtr 类型别名将被解析为正确的 Long 或 LongLong 数据类型,具体取决于运行的是哪个 Office 版本。请注意,如果需要执行不同的逻辑(例如,需要在大型 Excel 项目中操作 64 位值),则可以使用 Win64 条件编译常量,如以下部分所示。

CSofAndy 发表于 2022-7-18 14:37:00

谢谢了!试了下,没成功,具体还不知道应该怎么改。

CSofAndy 发表于 2022-7-19 09:25:00

PtrSafe和LongPtr在VB6.0里不认,vb6.0不支持。

CSofAndy 发表于 2022-7-19 09:31:00

PtrSafe和LongPtr在CAD的VBA环境里是可以,但是vb6.0里不支持,我用的是VB6.0,也没有VB7.0。

mikewolf2k 发表于 2022-7-19 10:18:00

VBA有64位版,VB没有64位版

CSofAndy 发表于 2022-7-19 11:02:00

哦,好的,谢谢!VB6.0获取64位CAD应用程序有什么办法呢?

chixun99 发表于 2022-7-19 11:34:00

VB6要配套64位开发是个硬伤,没法弄。

AndyWang 发表于 2022-7-21 22:54:00

我当时从32位平台移到64位平台时,也遇到这个问题。当时是大佬提示,64位平台不一定有那个hwnd,给出了获取hwnd的api,才编译运行成功的。不知道vb上能不能适用这个解决逻辑。
页: [1]
查看完整版本: 获取CAD2016应用程序句柄报错问题