首先感谢【bcrun】版主的推荐和加分,谢谢!同时感谢大家的支持! 在这里我再提供一份【VB 调用函数指针的方法实现,支持任意类型,任意个数参数(除Any类型)以及任意类型返回值】,对于Any,Optional,ParamArray,看你想传入什么类型就声明什么类型即可。以供大家学习参考: 具体更多的参数类型你可以自己试试,也可以到我的资源下载,参数类型可以是任意的,包括数组,用户自定义类型…… 代码下接,太长了无法提交,只能分割了…… 类模块: Option Explicit: Option Base 0Private Declare Function CallAsmCode Lib "user32" Alias "CallWindowProcA" (ByRef lpCode As Long, ByVal lpFunc As Long, ByRef lpParam As Long, ByVal nParam As Long, ByRef Result As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function IsBadReadPtr Lib "kernel32" (lp As Any, ByVal ucb As Long) As Long Private Declare Function IsBadWritePtr Lib "kernel32" (lp As Any, ByVal ucb As Long) As LongPrivate Const VT_BYREF = &H4000Private Type ParmData ByOf As String Type As String Data() As Byte End Type Private Type ParmsData Count As Long Param() As ParmData Ready As Boolean End TypePrivate Type FuncData FPtr As Long Type As String RPtr As Long End Type Private Type FuncsData Funcn As FuncData Ready As Boolean End TypePrivate Type CallsData ACode() As Long Count As Long Param() As Long End TypePrivate Type FunCallType Functn As FuncsData Params As ParmsData CallEx As CallsData End TypePrivate FunCall As FunCallTypePrivate Sub Class_Initialize() ReDim FunCall.CallEx.ACode(36): FunCall.CallEx.ACode(0) = &H53EC8B55 FunCall.CallEx.ACode(1) = &HE8: FunCall.CallEx.ACode(2) = &HEB815B00 FunCall.CallEx.ACode(3) = &H1000112C: FunCall.CallEx.ACode(4) = &H114A938D FunCall.CallEx.ACode(5) = &H64521000: FunCall.CallEx.ACode(6) = &H35FF FunCall.CallEx.ACode(7) = &H89640000: FunCall.CallEx.ACode(8) = &H25 FunCall.CallEx.ACode(9) = &H8B1FEB00: FunCall.CallEx.ACode(10) = &HE80C2444 FunCall.CallEx.ACode(11) = &H0: FunCall.CallEx.ACode(12) = &H53E98159 FunCall.CallEx.ACode(13) = &H8D100011: FunCall.CallEx.ACode(14) = &H119791 FunCall.CallEx.ACode(15) = &HB8908910: FunCall.CallEx.ACode(16) = &H33000000 FunCall.CallEx.ACode(17) = &H558BC3C0: FunCall.CallEx.ACode(18) = &H104D8B0C FunCall.CallEx.ACode(19) = &HEB8A148D: FunCall.CallEx.ACode(20) = &HFC528D06 FunCall.CallEx.ACode(21) = &HB4932FF: FunCall.CallEx.ACode(22) = &H8BF675C9 FunCall.CallEx.ACode(23) = &HD0FF0845: FunCall.CallEx.ACode(24) = &H58F64 FunCall.CallEx.ACode(25) = &H83000000: FunCall.CallEx.ACode(26) = &H4D8B04C4 FunCall.CallEx.ACode(27) = &H89018914: FunCall.CallEx.ACode(28) = &H51D90451 FunCall.CallEx.ACode(29) = &HC51DD08: FunCall.CallEx.ACode(30) = &H10C2C95B FunCall.CallEx.ACode(31) = &H58F6400: FunCall.CallEx.ACode(32) = &H0 FunCall.CallEx.ACode(33) = &H3304C483: FunCall.CallEx.ACode(34) = &H144D8BC0 FunCall.CallEx.ACode(35) = &HC95B0189: FunCall.CallEx.ACode(36) = &H900010C2 End SubPrivate Function GetTypeName(ByVal DataType As String) As String Select Case UCase(DataType) Case "", "NO", "SUB", "NONE": GetTypeName = "NONE" Case "BT", "BYT", "BYTE": GetTypeName = "BYTE" Case "BL", "BOL", "BOOLEAN": GetTypeName = "BOOLEAN" Case "IT", "INT", "INTEGER": GetTypeName = "INTEGER" Case "LG", "LNG", "LONG": GetTypeName = "LONG" Case "SI", "SNG", "SINGLE": GetTypeName = "SINGLE" Case "ST", "STR", "STRING": GetTypeName = "STRING" Case "OJ", "OBJ", "OBJECT": GetTypeName = "OBJECT" Case "EM", "ENM", "USERENUM": GetTypeName = "USERENUM" Case "TP", "TYP", "USERTYPE": GetTypeName = "USERTYPE" Case "DB", "DBL", "DOUBLE": GetTypeName = "DOUBLE" Case "DT", "DAT", "DATE": GetTypeName = "DATE" Case "CY", "CUR", "CURRENCY": GetTypeName = "CURRENCY" Case "VR", "VAR", "VARIANT": GetTypeName = "VARIANT" Case "BT()", "BYT()", "BYTE()": GetTypeName = "BYTE()" Case "BL()", "BOL()", "BOOLEAN()": GetTypeName = "BOOLEAN()" Case "IT()", "INT()", "INTEGER()": GetTypeName = "INTEGER()" Case "LG()", "LNG()", "LONG()": GetTypeName = "LONG()" Case "SI()", "SNG()", "SINGLE()": GetTypeName = "SINGLE()" Case "ST()", "STR()", "STRING()": GetTypeName = "STRING()" Case "OJ()", "OBJ()", "OBJECT()": GetTypeName = "OBJECT()" Case "EM()", "ENM()", "USERENUM()": GetTypeName = "USERENUM()" Case "TP()", "TYP()", "USERTYPE()": GetTypeName = "USERTYPE()" Case "DB()", "DBL()", "DOUBLE()": GetTypeName = "DOUBLE()" Case "DT()", "DAT()", "DATE()": GetTypeName = "DATE()" Case "CY()", "CUR()", "CURRENCY()": GetTypeName = "CURRENCY()" Case "VR()", "VAR()", "VARIANT()": GetTypeName = "VARIANT()" Case Else: GetTypeName = "ERROR" End Select End FunctionPrivate Function PointerIsNull(ByVal Pointer As Long) As Boolean Select Case FunCall.Functn.Funcn.Type Case "NONE": PointerIsNull = (Pointer <> 0) Case "BYTE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 1) Case "BOOLEAN": PointerIsNull = IsBadWritePtr(ByVal Pointer, 2) Case "INTEGER": PointerIsNull = IsBadWritePtr(ByVal Pointer, 2) Case "LONG": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) Case "SINGLE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) Case "STRING": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) Case "OBJECT": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) Case "USERENUM": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) Case "USERTYPE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 1) Case "DOUBLE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8) Case "DATE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8) Case "CURRENCY": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8) Case "VARIANT": PointerIsNull = IsBadWritePtr(ByVal Pointer, 16) Case Else: PointerIsNull = IsBadWritePtr(ByVal Pointer, 4) End Select End FunctionPublic Function CreateAnyFun(ByVal FunAddress As Long, Optional ByVal ReturnType As String, Optional ByVal ReturnAddress As Long) As Boolean FunCall.Functn.Funcn.FPtr = 0: FunCall.Functn.Funcn.RPtr = 0 FunCall.Functn.Funcn.Type = "": FunCall.Functn.Ready = False If CBool(IsBadReadPtr(ByVal FunAddress, 4)) Then Exit Function FunCall.Functn.Funcn.FPtr = FunAddress FunCall.Functn.Funcn.Type = GetTypeName(ReturnType) If FunCall.Functn.Funcn.Type = "ERROR" Then Exit Function If FunCall.Functn.Funcn.Type = "NONE" Then If ReturnAddress <> 0 Then Exit Function FunCall.Functn.Ready = True: CreateAnyFun = True: Exit Function End If If FunCall.Functn.Funcn.Type = "USERTYPE" Then If PointerIsNull(ReturnAddress) Then Exit Function FunCall.Functn.Funcn.RPtr = ReturnAddress FunCall.Functn.Ready = True: CreateAnyFun = True: Exit Function End If If ReturnAddress <> 0 Then If PointerIsNull(ReturnAddress) Then Exit Function FunCall.Functn.Funcn.RPtr = ReturnAddress End If FunCall.Functn.Ready = True: CreateAnyFun = True End FunctionPrivate Function VarIsString(ByRef VarData As Variant) As Boolean On Error GoTo ErrVarIsString VarData = CStr(VarData) VarIsString = True Exit Function ErrVarIsString: End FunctionPrivate Function GetByOfName(ByVal DataBy As String) As String Select Case UCase(DataBy) Case "R", "BR", "REF", "BYREF": GetByOfName = "BYREF" Case "V", "BV", "VAL", "BYVAL": GetByOfName = "BYVAL" Case Else: GetByOfName = "ERROR" End Select End FunctionPrivate Function TypeIsNull(ByRef DataList() As String) As Boolean If DataList(0) = "NONE" Then TypeIsNull = True: Exit Function If DataList(0) = "ERROR" Then TypeIsNull = True: Exit Function If DataList(1) = "ERROR" Then TypeIsNull = True: Exit Function If DataList(0) = "BYVAL" Then If DataList(1) = "USERTYPE" Then TypeIsNull = True: Exit Function If (InStr(DataList(1), "()") > 0) Then TypeIsNull = True: Exit Function End If End FunctionPrivate Function SetParamList(ByRef DataList() As String) As Boolean If UBound(DataList) <> 1 Then Exit Function DataList(0) = GetByOfName(DataList(0)) DataList(1) = GetTypeName(DataList(1)) SetParamList = Not TypeIsNull(DataList) If Not SetParamList Then Exit Function With FunCall.Params ReDim Preserve .Param(.Count) .Param(.Count).ByOf = DataList(0) .Param(.Count).Type = DataList(1) .Count = .Count + 1 End With End FunctionPublic Function CreateParams(ParamArray ParamDeclareList() As Variant) As Boolean Erase FunCall.Params.Param: FunCall.Params.Count = 0 If IsMissing(ParamDeclareList) Then FunCall.Params.Ready = True: CreateParams = True: Exit Function End If Dim iNx As Long, ParamList As String, Param() As String For iNx = 0 To UBound(ParamDeclareList) If VarIsString(ParamDeclareList(iNx)) Then ParamList = ParamDeclareList(iNx) Do While InStr(ParamList, Space(2)) > 0 ParamList = Replace(ParamList, Space(2), Space(1)) Loop Param = Split(Trim(ParamList), Space(1)) If SetParamList(Param) Then CreateParams = True End If Next FunCall.Params.Ready = CreateParams End Function
在这里我再提供一份【VB 调用函数指针的方法实现,支持任意类型,任意个数参数(除Any类型)以及任意类型返回值】,对于Any,Optional,ParamArray,看你想传入什么类型就声明什么类型即可。以供大家学习参考:
具体更多的参数类型你可以自己试试,也可以到我的资源下载,参数类型可以是任意的,包括数组,用户自定义类型……
代码下接,太长了无法提交,只能分割了……
类模块:
Option Explicit: Option Base 0Private Declare Function CallAsmCode Lib "user32" Alias "CallWindowProcA" (ByRef lpCode As Long, ByVal lpFunc As Long, ByRef lpParam As Long, ByVal nParam As Long, ByRef Result As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function IsBadReadPtr Lib "kernel32" (lp As Any, ByVal ucb As Long) As Long
Private Declare Function IsBadWritePtr Lib "kernel32" (lp As Any, ByVal ucb As Long) As LongPrivate Const VT_BYREF = &H4000Private Type ParmData
ByOf As String
Type As String
Data() As Byte
End Type
Private Type ParmsData
Count As Long
Param() As ParmData
Ready As Boolean
End TypePrivate Type FuncData
FPtr As Long
Type As String
RPtr As Long
End Type
Private Type FuncsData
Funcn As FuncData
Ready As Boolean
End TypePrivate Type CallsData
ACode() As Long
Count As Long
Param() As Long
End TypePrivate Type FunCallType
Functn As FuncsData
Params As ParmsData
CallEx As CallsData
End TypePrivate FunCall As FunCallTypePrivate Sub Class_Initialize()
ReDim FunCall.CallEx.ACode(36): FunCall.CallEx.ACode(0) = &H53EC8B55
FunCall.CallEx.ACode(1) = &HE8: FunCall.CallEx.ACode(2) = &HEB815B00
FunCall.CallEx.ACode(3) = &H1000112C: FunCall.CallEx.ACode(4) = &H114A938D
FunCall.CallEx.ACode(5) = &H64521000: FunCall.CallEx.ACode(6) = &H35FF
FunCall.CallEx.ACode(7) = &H89640000: FunCall.CallEx.ACode(8) = &H25
FunCall.CallEx.ACode(9) = &H8B1FEB00: FunCall.CallEx.ACode(10) = &HE80C2444
FunCall.CallEx.ACode(11) = &H0: FunCall.CallEx.ACode(12) = &H53E98159
FunCall.CallEx.ACode(13) = &H8D100011: FunCall.CallEx.ACode(14) = &H119791
FunCall.CallEx.ACode(15) = &HB8908910: FunCall.CallEx.ACode(16) = &H33000000
FunCall.CallEx.ACode(17) = &H558BC3C0: FunCall.CallEx.ACode(18) = &H104D8B0C
FunCall.CallEx.ACode(19) = &HEB8A148D: FunCall.CallEx.ACode(20) = &HFC528D06
FunCall.CallEx.ACode(21) = &HB4932FF: FunCall.CallEx.ACode(22) = &H8BF675C9
FunCall.CallEx.ACode(23) = &HD0FF0845: FunCall.CallEx.ACode(24) = &H58F64
FunCall.CallEx.ACode(25) = &H83000000: FunCall.CallEx.ACode(26) = &H4D8B04C4
FunCall.CallEx.ACode(27) = &H89018914: FunCall.CallEx.ACode(28) = &H51D90451
FunCall.CallEx.ACode(29) = &HC51DD08: FunCall.CallEx.ACode(30) = &H10C2C95B
FunCall.CallEx.ACode(31) = &H58F6400: FunCall.CallEx.ACode(32) = &H0
FunCall.CallEx.ACode(33) = &H3304C483: FunCall.CallEx.ACode(34) = &H144D8BC0
FunCall.CallEx.ACode(35) = &HC95B0189: FunCall.CallEx.ACode(36) = &H900010C2
End SubPrivate Function GetTypeName(ByVal DataType As String) As String
Select Case UCase(DataType)
Case "", "NO", "SUB", "NONE": GetTypeName = "NONE"
Case "BT", "BYT", "BYTE": GetTypeName = "BYTE"
Case "BL", "BOL", "BOOLEAN": GetTypeName = "BOOLEAN"
Case "IT", "INT", "INTEGER": GetTypeName = "INTEGER"
Case "LG", "LNG", "LONG": GetTypeName = "LONG"
Case "SI", "SNG", "SINGLE": GetTypeName = "SINGLE"
Case "ST", "STR", "STRING": GetTypeName = "STRING"
Case "OJ", "OBJ", "OBJECT": GetTypeName = "OBJECT"
Case "EM", "ENM", "USERENUM": GetTypeName = "USERENUM"
Case "TP", "TYP", "USERTYPE": GetTypeName = "USERTYPE"
Case "DB", "DBL", "DOUBLE": GetTypeName = "DOUBLE"
Case "DT", "DAT", "DATE": GetTypeName = "DATE"
Case "CY", "CUR", "CURRENCY": GetTypeName = "CURRENCY"
Case "VR", "VAR", "VARIANT": GetTypeName = "VARIANT"
Case "BT()", "BYT()", "BYTE()": GetTypeName = "BYTE()"
Case "BL()", "BOL()", "BOOLEAN()": GetTypeName = "BOOLEAN()"
Case "IT()", "INT()", "INTEGER()": GetTypeName = "INTEGER()"
Case "LG()", "LNG()", "LONG()": GetTypeName = "LONG()"
Case "SI()", "SNG()", "SINGLE()": GetTypeName = "SINGLE()"
Case "ST()", "STR()", "STRING()": GetTypeName = "STRING()"
Case "OJ()", "OBJ()", "OBJECT()": GetTypeName = "OBJECT()"
Case "EM()", "ENM()", "USERENUM()": GetTypeName = "USERENUM()"
Case "TP()", "TYP()", "USERTYPE()": GetTypeName = "USERTYPE()"
Case "DB()", "DBL()", "DOUBLE()": GetTypeName = "DOUBLE()"
Case "DT()", "DAT()", "DATE()": GetTypeName = "DATE()"
Case "CY()", "CUR()", "CURRENCY()": GetTypeName = "CURRENCY()"
Case "VR()", "VAR()", "VARIANT()": GetTypeName = "VARIANT()"
Case Else: GetTypeName = "ERROR"
End Select
End FunctionPrivate Function PointerIsNull(ByVal Pointer As Long) As Boolean
Select Case FunCall.Functn.Funcn.Type
Case "NONE": PointerIsNull = (Pointer <> 0)
Case "BYTE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 1)
Case "BOOLEAN": PointerIsNull = IsBadWritePtr(ByVal Pointer, 2)
Case "INTEGER": PointerIsNull = IsBadWritePtr(ByVal Pointer, 2)
Case "LONG": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
Case "SINGLE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
Case "STRING": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
Case "OBJECT": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
Case "USERENUM": PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
Case "USERTYPE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 1)
Case "DOUBLE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8)
Case "DATE": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8)
Case "CURRENCY": PointerIsNull = IsBadWritePtr(ByVal Pointer, 8)
Case "VARIANT": PointerIsNull = IsBadWritePtr(ByVal Pointer, 16)
Case Else: PointerIsNull = IsBadWritePtr(ByVal Pointer, 4)
End Select
End FunctionPublic Function CreateAnyFun(ByVal FunAddress As Long, Optional ByVal ReturnType As String, Optional ByVal ReturnAddress As Long) As Boolean
FunCall.Functn.Funcn.FPtr = 0: FunCall.Functn.Funcn.RPtr = 0
FunCall.Functn.Funcn.Type = "": FunCall.Functn.Ready = False
If CBool(IsBadReadPtr(ByVal FunAddress, 4)) Then Exit Function
FunCall.Functn.Funcn.FPtr = FunAddress
FunCall.Functn.Funcn.Type = GetTypeName(ReturnType)
If FunCall.Functn.Funcn.Type = "ERROR" Then Exit Function
If FunCall.Functn.Funcn.Type = "NONE" Then
If ReturnAddress <> 0 Then Exit Function
FunCall.Functn.Ready = True: CreateAnyFun = True: Exit Function
End If
If FunCall.Functn.Funcn.Type = "USERTYPE" Then
If PointerIsNull(ReturnAddress) Then Exit Function
FunCall.Functn.Funcn.RPtr = ReturnAddress
FunCall.Functn.Ready = True: CreateAnyFun = True: Exit Function
End If
If ReturnAddress <> 0 Then
If PointerIsNull(ReturnAddress) Then Exit Function
FunCall.Functn.Funcn.RPtr = ReturnAddress
End If
FunCall.Functn.Ready = True: CreateAnyFun = True
End FunctionPrivate Function VarIsString(ByRef VarData As Variant) As Boolean
On Error GoTo ErrVarIsString
VarData = CStr(VarData)
VarIsString = True
Exit Function
ErrVarIsString:
End FunctionPrivate Function GetByOfName(ByVal DataBy As String) As String
Select Case UCase(DataBy)
Case "R", "BR", "REF", "BYREF": GetByOfName = "BYREF"
Case "V", "BV", "VAL", "BYVAL": GetByOfName = "BYVAL"
Case Else: GetByOfName = "ERROR"
End Select
End FunctionPrivate Function TypeIsNull(ByRef DataList() As String) As Boolean
If DataList(0) = "NONE" Then TypeIsNull = True: Exit Function
If DataList(0) = "ERROR" Then TypeIsNull = True: Exit Function
If DataList(1) = "ERROR" Then TypeIsNull = True: Exit Function
If DataList(0) = "BYVAL" Then
If DataList(1) = "USERTYPE" Then TypeIsNull = True: Exit Function
If (InStr(DataList(1), "()") > 0) Then TypeIsNull = True: Exit Function
End If
End FunctionPrivate Function SetParamList(ByRef DataList() As String) As Boolean
If UBound(DataList) <> 1 Then Exit Function
DataList(0) = GetByOfName(DataList(0))
DataList(1) = GetTypeName(DataList(1))
SetParamList = Not TypeIsNull(DataList)
If Not SetParamList Then Exit Function
With FunCall.Params
ReDim Preserve .Param(.Count)
.Param(.Count).ByOf = DataList(0)
.Param(.Count).Type = DataList(1)
.Count = .Count + 1
End With
End FunctionPublic Function CreateParams(ParamArray ParamDeclareList() As Variant) As Boolean
Erase FunCall.Params.Param: FunCall.Params.Count = 0
If IsMissing(ParamDeclareList) Then
FunCall.Params.Ready = True: CreateParams = True: Exit Function
End If
Dim iNx As Long, ParamList As String, Param() As String
For iNx = 0 To UBound(ParamDeclareList)
If VarIsString(ParamDeclareList(iNx)) Then
ParamList = ParamDeclareList(iNx)
Do While InStr(ParamList, Space(2)) > 0
ParamList = Replace(ParamList, Space(2), Space(1))
Loop
Param = Split(Trim(ParamList), Space(1))
If SetParamList(Param) Then CreateParams = True
End If
Next
FunCall.Params.Ready = CreateParams
End Function
copyFolder(oldPath, newPath)
}
/**
* 复制整个文件夹内容
* @param oldPath String 原文件路径 如:c:/fqf
* @param newPath String 复制后路径 如:f:/fqf/ff
* @return boolean
*/
public static void copyFolder(String oldPath, String newPath) {
try {
(new File(newPath)).mkdirs(); //如果文件夹不存在 则建立新文件夹
File a=new File(oldPath);
String[] file=a.list();
File temp=null;
for (int i = 0; i < file.length; i++) {
if(oldPath.endsWith(File.separator)){
temp=new File(oldPath+file[i]);
}
else{
temp=new File(oldPath+File.separator+file[i]);
} if(temp.isFile()){
FileInputStream input = new FileInputStream(temp);
FileOutputStream output = new FileOutputStream(newPath + "/" +
(temp.getName()).toString());
byte[] b = new byte[1024 * 5];
int len;
while ( (len = input.read(b)) != -1) {
output.write(b, 0, len);
}
output.flush();
output.close();
input.close();
}
if(temp.isDirectory()){//如果是子文件夹
copyFolder(oldPath+"/"+file[i],newPath+"/"+file[i]);
System.out.println(temp.getName()+"拷贝成功");
}
}
}
catch (Exception e) {
System.out.println("复制整个文件夹内容操作出错");
e.printStackTrace(); }
}
这不是更简单