本帖最后由 bcrun 于 2014-04-28 08:12:32 编辑

解决方案 »

  1.   

    忘记说了,GetFileCopyExCallBackPtr获取类模块函数地址指针的方法改进自PctGL的无崩溃回调函数,有相似也有不同,PctGL大神勿怪!
      

  2.   

    首先感谢【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
      

  3.   

    public static void main(String[] args) {

    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();        } 
         
       }
    这不是更简单