小弟之前做了一个小程序,用于VB6制作有输出函数的DLL文件.但自己在使用之中,发现在DLL里的函数的返回值如果是String类型,便无法返回.经人指点,使用了类似SendMessage返回的方法,就是采用事先定义一缓冲区,由函数把返回值写入缓冲区的方法来得到返回值.试了一下,返回值是到了,但是有点不对.具体情况如下: DLL内函数:Public Function GetPwd(Hwnd As Long, BuffLong As Long, Buff As String) As LongGetPwd = SendMessage(Hwnd, WM_GETTEXT, BuffLong, Buff)End Function 程序内调用部分的代码:Dim K as string * 255
Din M as longM=GetPwd(FormHwnd,len(K),K)Text1.Text=K 如果这样调用,程序就会非法操作.而对DLL内作如下改动后,侧可以返回返回值,但是值不正常:Public Function GetPwd(Hwnd As Long, BuffLong As Long, Buff As String) As LongDim M As LongM = Len(Buff)GetPwd = SendMessage(Hwnd, WM_GETTEXT, M, Buff)End Function 设Buff的值为"D:\kkk\mydate.exe",那么在程序内得到的值就是"D",也就是说返回值始终只有第一个字符.调用方法都是一样的,这让我很不明白.于是,在DLL内又添加了一句MsgBox语句,确认了DLL内的Buff的值是正常的:Public Function GetPwd(Hwnd As Long, BuffLong As Long, Buff As String) As LongDim M As LongM = Len(Buff)GetPwd = SendMessage(Hwnd, WM_GETTEXT, M, Buff)MsgBox M & " " & BuffEnd Function结果是,DLL内的值是非常正确,然后我又想到是不是在调用时的缓冲区出了问题,于是在程序内加入这样一句:Dim K as string * 255
Din M as longM=GetPwd(FormHwnd,len(K),K)MsgBox len(K)Text1.Text=K结果,程序内显示"255".这下,我真的晕了.最后,我把做DLL用的模块直接添加到工程里,把对自制DLL函数的声明先注释掉,然后运行程序,返回值就正常了!但是,由于不是在DLL内,无法达到我所期望的效果来.我现在真的是没有一点办法了.我想请教一下大家,这当中到底哪里出了问题呢?还烦请指点一二!
Din M as longM=GetPwd(FormHwnd,len(K),K)Text1.Text=K 如果这样调用,程序就会非法操作.而对DLL内作如下改动后,侧可以返回返回值,但是值不正常:Public Function GetPwd(Hwnd As Long, BuffLong As Long, Buff As String) As LongDim M As LongM = Len(Buff)GetPwd = SendMessage(Hwnd, WM_GETTEXT, M, Buff)End Function 设Buff的值为"D:\kkk\mydate.exe",那么在程序内得到的值就是"D",也就是说返回值始终只有第一个字符.调用方法都是一样的,这让我很不明白.于是,在DLL内又添加了一句MsgBox语句,确认了DLL内的Buff的值是正常的:Public Function GetPwd(Hwnd As Long, BuffLong As Long, Buff As String) As LongDim M As LongM = Len(Buff)GetPwd = SendMessage(Hwnd, WM_GETTEXT, M, Buff)MsgBox M & " " & BuffEnd Function结果是,DLL内的值是非常正确,然后我又想到是不是在调用时的缓冲区出了问题,于是在程序内加入这样一句:Dim K as string * 255
Din M as longM=GetPwd(FormHwnd,len(K),K)MsgBox len(K)Text1.Text=K结果,程序内显示"255".这下,我真的晕了.最后,我把做DLL用的模块直接添加到工程里,把对自制DLL函数的声明先注释掉,然后运行程序,返回值就正常了!但是,由于不是在DLL内,无法达到我所期望的效果来.我现在真的是没有一点办法了.我想请教一下大家,这当中到底哪里出了问题呢?还烦请指点一二!
activex dll工程:工程名pwd,只有一个class(名为test),编译为pwd.dll,类模块test代码如下:
Option ExplicitPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal Hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_GETTEXT = &HD
Public Function GetPwd(ByVal Hwnd As Long, ByVal BuffLong As Long, Buff As String) As Long
If BuffLong < 1 Then
GetPwd = 0
End If
Dim mbuff() As Byte
ReDim mbuff(BuffLong - 1)
Dim i As Long, j As Long
i = VarPtr(mbuff(0))
j = SendMessage(Hwnd, WM_GETTEXT, BuffLong, ByVal i&)
If j > 0 Then
Dim out() As Byte
ReDim out(j - 1)
CopyMemory out(0), mbuff(0), j
Erase mbuff
Buff = StrConv(out, vbUnicode)
GetPwd = j
Erase out
Else
Erase mbuff
GetPwd = 0
Buff = vbNullString
End If
End Function普通工程中,窗体上只有一个按钮
'首先要引用pwd.dll(工程 引用 浏览 找到pwd.dll,并点击确定,当然你先用regsvr32注册也行)
Option ExplicitPrivate Sub Command1_Click()
Dim myGetpwd As New pwd.test
Dim s As String
Dim i As Long
'不需要给字串预先分配缓冲区,直接调用即可,返回值为字串所占的字节数
i = myGetpwd.GetPwd(Text1.Hwnd, 255, s)
MsgBox s
Set myGetpwd = Nothing
End Sub
Public Function AddStr(s1 As String, s2 As String) As String
AddStr = s1 & s2
End Function测试的声明
Private Declare Function AddStr Lib "dll.dll" (s1 As String, s2 As String) As StringPrivate Sub Form_Load()
MsgBox AddStr("hello ", "world!")
End Sub
GetPwd = 0
End If修改一下:
If BuffLong < 1 Then
GetPwd = 0
Buff =vbnullstring
exit function
End If