切换到64位Excel后如何解决VBA“类型不匹配”错误

问题描述

运行32位版本的Excel时,我使用的代码运行正常。切换到64位版本后,宏中断了。我更新了dll调用,以便在所有地方而不是LongPtr处使用Long
是否有任何方法可以确定对于特定的Declare Function需要为VBA7更改哪些参数和返回类型,而不必更改?

这是我已更新的一些“声明函数”的示例(实际上还有更多)。

#If VBA7 Then
    Private Declare PtrSafe Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String,ByVal lpDeviceName As String,ByVal lpOutput As String,lpInitData As LongPtr) As LongPtr
    Private Declare PtrSafe Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As LongPtr,ByVal nWidth As LongPtr,ByVal nHeight As LongPtr) As LongPtr
    Private Declare PtrSafe Function DeleteDC Lib "gdi32.dll" (ByVal hdc As LongPtr) As LongPtr
    Private Const LOGPIXELSY As Long = 90
#Else
    Private Declare CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String,lpInitData As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long,ByVal nWidth As Long,ByVal nHeight As Long) As Long
    Private Const LOGPIXELSY As Long = 90
#End If

此代码改编自以下问题的答案: vb macro string width

相关代码段复制如下:

Private Function GetLabelSize(text As String,font As StdFont) As SIZE
    Dim tempDC As Long
    Dim tempBMP As Long
    Dim f As Long
    Dim lf As LOGFONT
    Dim textSize As SIZE

    tempDC = CreateDC("DISPLAY",vbNullString,ByVal 0)
    tempBMP = CreateCompatibleBitmap(tempDC,1,1)

我得到一个运行时错误,上面仅显示“编译错误:类型不匹配”。对CreateDC的函数调用突出显示,调试器在函数GetLabelSize上中断。我不知道哪个变量现在导致错误。我还假设一旦解决了第一个错误,我也会遇到其他错误。

我是否需要将最后一个参数(ByVal 0)的值作为显式类型的变量传递?如果可以,怎么办?

解决方法

我更新了dll调用,以在各处使用LongPtr而不是Long

您不应该那样做。

通过将PtrSafe添加到函数声明中,您promise to the compiler已将LongPtr放置在需要放置的所有位置,而没有其他地方。

LongPtr是一个指针大小的整数。它必须用于与指针大小相同的事物。

要了解哪种Windows API类型应描述为LongPtr,您必须查看原始函数签名,请查阅https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types,向下跟踪所有typedef中使用的数据类型基本类型,并使用LongPtr表示事物的指针。

对于您所显示的功能,应该是

#If VBA7 Then
    Private Declare PtrSafe Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String,ByVal lpDeviceName As String,ByVal lpOutput As String,ByVal lpInitData As LongPtr) As LongPtr
    Private Declare PtrSafe Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As LongPtr,ByVal nWidth As Long,ByVal nHeight As Long) As LongPtr
    Private Declare PtrSafe Function DeleteDC Lib "gdi32.dll" (ByVal hdc As LongPtr) As Long
#Else
    Private Declare Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String,ByVal lpInitData As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long,ByVal nHeight As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
#End If

声明变量以保存LongPtr结果时,也需要使用#If VBA7

#If VBA7 Then
    Dim tempDC As LongPtr
    Dim tempBMP As LongPtr
#Else
    Dim tempDC As Long
    Dim tempBMP As Long
#End If

如果您不必支持Office 2007 and older,则可以放弃#If VBA7,而只使用LongPtr分支。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...