回 帖 发 新 帖 刷新版面

主题:[讨论]关于API声明时的参数类型的问题

以FindWindow为例,
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

也可以改成
Private Declare Function FindWindowString Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowLong Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As String) As Long

参数的类型都可以适当地改变。
但在以前使用GetSaveFileName()时,仅仅时由于声明OPENFILENAME结构时的元素的顺序不一致,就导出了IDE崩溃。真是无语了~~~

回复列表 (共1个回复)

沙发

Private Type Struct
    a As Long
    b As Long
End Type
最终名字都会被去掉,编译成某个地址.
a: 41001000
b: 41001004
mov eax, [41001004]
...
人家原本想取b值的,你却给个a值,不崩溃才怪.
所以结构位置是按字节位置明确严格定义好的,没有换位置这个概念.

API声明,真正定位函数地址是靠Alias后面那个名字的(如果有),所以你前面那个改的天花乱坠也没关系.
ByVal xx As String的本质是一个字符串指针,所以可以声明为ByVal xx As Long,但使用后者须要小心区别ANSI和UNICODE.
[code=c]

Private Declare Function FindWindowLongA Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowLongW Lib "user32" Alias "FindWindowW" (ByVal lpClassName As Long, ByVal lpWindowName As String) As Long

Private Sub Form_Click()
    '正确的用法
    Debug.Print "FindWindowLongA: " & FindWindowLongA(StrPtr(StrConv("Notepad", vbFromUnicode)), vbNullString)
    Debug.Print "FindWindowLongW: " & FindWindowLongW(StrPtr("Notepad"), vbNullString)
    
    '错误的用法
    Debug.Print "FindWindowLongA(WRONG WAY): " & FindWindowLongA(StrPtr("Notepad"), vbNullString)
    Debug.Print "FindWindowLongW(WRONG WAY): " & FindWindowLongW(StrPtr(StrConv("Notepad", vbFromUnicode)), vbNullString)
End Sub
[/code]

如果需要在缓冲区接收API返回的字符串,情况就更复杂了,你自己思考一下应该怎么做(例如GetWindowTextA GetWidowTextW)

我来回复

您尚未登录,请登录后再回复。点此登录或注册