VB程序员博客
10 5th, 2008
VB中定义的函数使用数组作为返回值
请将语法结构写一下
谢谢
dim Myarray
Myarray=array("辣椒","生姜","大蒜","茄子","土豆")
那Myarray(0)就会等于“辣椒”了
谢谢各位大哥大姐
09 30th, 2008
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal Point As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Sub Form_Click()
Sleep 4000
Dim hwnd As Long '句柄
Dim pid As Long '进程pid
Dim pHandle As Long '进程句柄
Dim str As Long '内存中的值
Dim Point As POINTAPI
GetCursorPos Point
hwnd = WindowFromPoint(ByVal Point.X, ByVal Point.Y)
GetWindowThreadProcessId hwnd, pid
Print pid
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
ReadProcessMemory pHandle, ByVal &H1C228A0, str, 4, 0&
Print str
End Sub
输出pid正常,输出str就总是零,哪出问题了?
被拦截了吧
用法对么?
ReadProcessMemory的第三个参数应该是str变量的地址吧~!~!
用法没错
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal Point As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
'—————————-
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED + SYNCHRONIZE + &HFFF
'———————————————————
Private Sub Form_Click()
Sleep 4000
Dim hwnd As Long '句柄
Dim pid As Long '进程pid
Dim pHandle As Long '进程句柄
Dim str As Long '内存中的值
Dim Point As POINTAPI
GetCursorPos Point
hwnd = WindowFromPoint(ByVal Point.X, ByVal Point.Y)
GetWindowThreadProcessId hwnd, pid
Print pid
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
ReadProcessMemory pHandle, ByVal &H1C228A0, str, 4, 0&
Print str
End Sub
看下 readprocessmemory 的返回值是什么,或者把最后一个参数补上,看看他的值是多少
这2个任意一个为0,则说明执行错误,看看那个地址是否正确,是否可以读
我也是遇到这个问题~~偶是新手~~~
传址问题 声明LONG 型 然后传BYVAR VARPTR
08 31st, 2008
Set cmd.ActiveConnection = conn
cmd.CommandText = "sp_GS_AA "
cmd.CommandType = adCmdStoredProc
set rs= cmd.Execute
以上是返回一个记录集的写法,如果返回多个记录集呢?该如何写,在线等待
什么都不用改
几个记录合在一个记录对象中,
NextRecordset是下个记录
08 21st, 2008
最好用conn.execute实现。
exec sp_GetID @RemoteId = default, @cAcc_Id = '010 ', @cVouchType = 'sfc_optransform ', @iAmount = 1, @iFatherId = @P1 output, @iChildId = @P2 output
在sql里,如上可以得到结果,我怎么在VB里执行,并得到@p1,@p2的值吗?
要得到存储过程返回值和输出参数需要用command对象,并且存储过程返回值需要作为command对象的第一个参数。
Dim adoComm As Object
Set adoComm = CreateObject( "ADODB.Command ")
Set rs2 = New ADODB.Recordset
Set cmd = New ADODB.Command
cmd.ActiveConnection = SQLConn
cmd.CommandText = "FTYBYDAILY "
cmd.CommandType = adCmdStoredProc
cmd.Parameters( "@s_date ") = Format(DTPicker1.Value, "YYYY-MM-DD ")
cmd.Parameters( "@model ") = Trim(Text1.Text)
Set rs2 = cmd.Execute
Set MSHFlexGrid1.Recordset = rs2
事情是这样的,我的数据库是SQL SERVER2000
连接代码为:
"Provider=SQLOLEDB.1;Password=asp600;Persist Security Info=True;User ID=sa;Initial Catalog=LABEL;Data Source=172.17.1.21;Connect Timeout=30 "
基本代码如下:
Dim rstobj As New ADODB.Recordsetrst
obj.Open cmdObj, , adOpenStatic, adLockOptimistic
但我的rstobj.RecordCount老是返回-1阿(数据库有相应数据),请问各位为什么啊,要怎样解决阿?
在open之前使用客户端游标
rstobj.CursorLocation = adUseClient
看看ado最基本的书籍或msdn
rstobj.CursorLocation = adUseClient
rstobj.CursorLocation = adUseClient
不一定用客户端游标
不一定用客户端游标
———————
默认情况下recordset是服务器游标,它不返还recordcount。要使用recordcount属性,还有其它方法?
07 12th, 2008
新建了一个模块,里面定义了
Public Conn As New ADODB.Connection
在一个按钮的单击事件中:
Dim chaxun1, chaxun2, jigelv As String
chaxun1 = "select count(*) as bjg from 学生 where Stu_Score>80"
chaxun2 = "select count(*) as total from 学生"
jigelv = chaxun1 & chaxun2
Conn.RecordSource = jigelv
Conn.Refresh
Label1.Caption = CStr(Conn.Recordset(1))
错误提示:
实时错误:446
对象不支持命名参数
怎么办?
Label1.Caption = Conn.Execute(chaxun1)(0) & Conn.Execute(chaxun2)(0)
Conn.RecordSource = jigelv是错的,只有recordset才有recordsource这个属性.
晕了
chaxun1 = "select count(*) as bjg from 学生 where Stu_Score>80"
chaxun2 = "select count(*) as total from 学生"
jigelv = chaxun1 & chaxun2
Conn.RecordSource = jigelv
相当于
Conn.RecordSource ="select count(*) as bjg from 学生 where Stu_Score>80select count(*) as total from 学生"
这能行吗?
Conn.RecordSource
一般不会出现这种问题吧,没有提示吗
06 18th, 2008
程序如下,请看看哪里出错?
Private Sub Command1_Click()
If SaveKey(HKEY_CLASSES_ROOT, "ServoWorksS100M", "s100m.txt") = True Then
MsgBox "save!"
End If
End Sub
Public Function SaveKey(KeyRoot As KeyRoot, KeyName As String, FileName As String) As Boolean
On Error Resume Next
Dim lpAttr As SECURITY_ATTRIBUTES ' 注册表安全类型
lpAttr.nLength = 50 ' 设置安全属性为缺省值…
lpAttr.lpSecurityDescriptor = 1 ' …
lpAttr.bInheritHandle = True ' …
If EnablePrivilege(SE_BACKUP_NAME) = False Then
SaveKey = False
Exit Function
End If
Success = RegOpenKeyEx(KeyRoot, KeyName, 0&, KEY_ALL_ACCESS, hKey)
If Success <> 0 Then
SaveKey = False
Success = RegCloseKey(hKey)
Exit Function
End If
Success = RegSaveKey(hKey, FileName, lpAttr)
If Success = 0 Then SaveKey = True Else SaveKey = False
Success = RegCloseKey(hKey)
End Function
每次都是红色字体处 返回87(参数错误),但是错在哪里?
Private Declare Function RegSaveKey Lib "advapi32.dll" Alias "RegSaveKeyA" (ByVal hKey As Long, ByVal lpFile As String, lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long
都是这样的声明, 问题到底在哪里呢?
我看网上的帖子都是说regsavekey这样那样的问题,就没有看见一个正常使用的例子,而我用的也都是别人封装好的注册表操作程序,为什么regsavekey会让无数的人一直反复的烦恼呢?
没有人了解吗?
05 26th, 2008
在vba中调用vc开发的dll,返回参数的字符值超过64K,在vba中如何接收?
这么长的字符串…..少见啊
VBA中用下面的方法写文件
Open Filename For Output As #1
Print #1, ReturnString
Close #1
C中也使用OPEN CLOSE的方法
那你定义这样的接口就不合适
返回的Byte()?
再用strConv转换到字符串
05 16th, 2008
- VB.NET code
-
Private Declare Function SHFileExists Lib "shell32" Alias "#45" (ByVal szPath As String) As Long
无论参数如何,该函数总会返回0,为什么呢????
这个函数怎么用?
- VB.NET code
-
Private Declare Function SearchTreeForFile Lib "dbghelp.dll" (ByVal RootPath As String, ByValputPathName As String, ByValputPathBuffer As String) As Long
因为我测试了也是 0 = =!
不知道怎么做。。。
为什么不直接用Dir来测试档案的存在啊???
因为我听别人说,SHFileExists比Dir$快~~~~~
SHFileExists(strconv("123",64))
从国外网站得知, 看下图说明吧.
Dir 很好用, 查找一个文件, 速度又能差到那里 ? 几几几毫秒 ? 在乎吗?
4F 竟然管用, 不错.
问题解决~结帖~~~~~~~
被人骗了~~~~~~
刚才用SHFileExists与Dir进行测试,各进行10000次
发现Dir比SHFileExists还要快半秒以上~~~~
05 15th, 2008
在VC中我是这样定义的
#define DLLExport extern "C" __declspec(dllexport)
BYTE bStr[100];
DLLExport BYTE * VBQueryS()
{
bStr[0] = 48;
bStr[1] = 49;
bStr[2] = '\0';
return bStr;
}
结果返回的是一个BYTE数组,其实就是一个字符串
我想在VB中调用此函数并且将返回值给VB中的STRING 变量
VB中我该怎么样调用这个DLL并且返回bStr数组
我现在是这么做的
Private Declare Function VBQueryS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" () As Byte
string str
str = VBQueryS???
然后将数组第一个元素传进去
具体怎么写?
我试过了
Dim bbb(50) As Byte
bbb(0) = VBQueryS
但是我在调试的过程中发现
Expression value
bbb(0) 80
bbb(1) 0
bbb(2) 0
…
结果不对啊
俺习惯用这种用法
query( char *s ); //设置s的内容
vb中这样声明(大概)
function query( s() as byte ) as xxxxx
vb中这样调用
dim s(0 to 10) as byte
query s(0)
//记不清了,直接返回char *的俺没试过。
难道VB就不能调用返回类型为BYTE*的VCDLL函数吗
VB 就得不到DLL返回的字符串吗?
1:首先你要传BYTE的话,要转换
2:VC不建议返回对象
3:往这个指针里填写数据会比返回字符串要好
3:最好用BSTR * VBQueryS()
楼上的我没听明白
我其实是想用VC返回字符串
但是VC中的字符串和VB中的字符串类型不同
所以就用返回BYTE这种通用类型然后再转换成字符串
难道这样就不行吗?
- VB.NET code
-
Private Declare Function VBQueryS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" () As long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long) dim s as string dim b(100) as byte copymemory b(0),VBQueryS ,100 …..‘是否需要转换编码 s=b
楼上的代码我调试过了
但是b中的值和以前的值不一样
以前
b(0)=48
b(1)=49
b(2)=0
…
b(n)=0 3 <=n <=99
现在
b(0)=80
b(1)=152
b(2)=125
b(3)=3
…
b(n)=其他值,乱七八糟的值
怎么回事?
VC中的BYTE和VB中的BYTE不一样
不可能吧
还是我哪里出错了?
不推荐你这样返回字符串,最好是象下面这样来
- C/C++ code
-
DLLExport int __stdcall VBQueryS(char s[],size_t bufferSize) { if (bufferSize<=0) return 0; char bStr[]="012345"; size_t strLen=strlen(bStr); if (strLen<=bufferSize) strLen=bufferSize; strncpy(s,bStr,strLen); return strLen; }
- VB.NET code
-
Private Declare Function VBQueryS Lib "mydll.dll" (ByVal s As String, ByVal bufferSize As Long) As Long Private Sub Form_Load() Dim s As String, lLen As Long s = Space$(10) lLen = VBQueryS(s, Len(s)) If lLen > 0 Then s = Left$(s, lLen) End If Debug.Print s End Sub
楼上10楼正解,混合语言编程切忌让 DLL 函数返回非32位整数的返回值。
所要获得的其他一切东西均要从参数中取得。
如果真的需要迎合VB6的编程习惯让被调用函数返回VB6的类型,那就要通过 ATL COM 工程建立 COM 对象,还要将COM对象注册后给VB6调用。那就麻烦多了,决不像做DLL这么简洁。
我不能通过函数的返回值来得到我要的数吗?
为什么一定要在参数中实现呢?
1. VB中并不支持指针,你返回一个指针已经是错了
2. 你在DLL中分配字符串的内存,然后再将其指针返回,试想,如果你的DLL函数返回后,那个DLL被卸载了,那么调用者得到的会是什么呢?很有可能只是一个指向垃圾内存的指针而已
所以,像这种情况,应该是由函数的调用者负责分配缓冲区,被调用的函数负责将值存放到这个缓冲区
请问上面回答我问题的高手
我返回的字符串中可能有字母也有可能有汉字
所以我不想用CHAR
我想用BYTE数组来存放
我该怎么写啊?
哦
我明白了
所以必须给DLL传递参数
等于DLL在参数中填写需要返回的值
然后调用者再从给予的参数中读出DLL填写好的值
是不是这样?
是的。另外,用char还是byte,并无大碍,因为VB自己会进行转换的。
假设我这样定义DLL
DLLExport int VBQuerySS(BYTE s[],int bufferSize)
我在VB中该如何申明调用函数?
Private Declare Function VBQuerySS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" (???, ByVal bufferSize As Long) As Long
你用Visual studio中的工具API Text Viewer和MSDN中API声明对照着看,
就知道怎么一回事了。
ByVal s As String 一样的
想了解更多IT技术,请登陆: