0

FindFirstFileA(ANSI) 可以正常工作,而FindFirstFileW(Unicode) 则不能。Wide 版本总是返回 -1 (INVALID_HANDLE_VALUE),但为什么呢?

'Declarations:
Option Explicit

Private Const MAX_PATH  As Long = 260
Private Const ALTERNATE As Long = 14
Private Const INVALID_HANDLE_VALUE As Long = -1

Private Type FILETIME
    dwLowDateTime  As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
        dwFileAttributes As Long
        ftCreationTime As FILETIME
        ftLastAccessTime As FILETIME
        ftLastWriteTime As FILETIME
        nFileSizeHigh As Long
        nFileSizeLow As Long
        dwReserved0 As Long
        dwReserved1 As Long
        cFileName As String * MAX_PATH
        cAlternate As String * ALTERNATE
End Type

Private Declare Function FindFirstFileW Lib "kernel32" _
    (ByVal lpFileName As String, _
    ByRef lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function FindFirstFileA Lib "kernel32" _
    (ByVal lpFileName As String, _
    ByRef lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function FindClose Lib "kernel32" _
    (ByVal hFindFile As Long) As Long

Public Declare Function GetLastError Lib "kernel32" () As Integer

'Test Functions:
Public Function TestA(ByVal sf As String) As Long
    If Len(sf) < 3 Then Exit Function
    Dim wfd As WIN32_FIND_DATA
    TestA = FindFirstFileA(sf, wfd)
    'Debug.Print "AE:" & GetLastError()
    If TestA <> INVALID_HANDLE_VALUE Then FindClose TestA
End Function

Public Function TestW(ByVal sf As String) As Long
    If Len(sf) < 3 Then Exit Function
    Dim wfd As WIN32_FIND_DATA
    TestW = FindFirstFileW(sf, wfd)
    'Debug.Print "WE:" & GetLastError()
    If TestW <> INVALID_HANDLE_VALUE Then FindClose TestW
End Function

'Example test
Private Sub Command1_Click()
    Dim sDir As String
    sDir = "C:\new"
    MsgBox "A: " & TestA(sDir) & vbCrLf _
         & "W: " & TestW(sDir)
End Sub

PS感谢 Carey Gregory,但我仍然需要一些帮助来翻译 Wide 版本。WCHARVB6中的 C/C++ 等价物是什么?

//WinBase.h
typedef struct _WIN32_FIND_DATAA {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    CHAR   cFileName[ MAX_PATH ];
    CHAR   cAlternateFileName[ 14 ];
#ifdef _MAC
    DWORD dwFileType;
    DWORD dwCreatorType;
    WORD  wFinderFlags;
#endif
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
typedef struct _WIN32_FIND_DATAW {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    WCHAR  cFileName[ MAX_PATH ];    //WCHAR in VB6?
    WCHAR  cAlternateFileName[ 14 ]; //WCHAR in VB6?
#ifdef _MAC
    DWORD dwFileType;
    DWORD dwCreatorType;
    WORD  wFinderFlags;
#endif
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
4

2 回答 2

3

WIN32_FIND_DATA 有两个版本,就像使用它们的函数一样:ANSI 版本和 Unicode 版本。您需要定义 WIN32_FIND_DATAA 和 WIN32_FIND_DATAW 并将它们与“A”和“W”函数一起使用。

于 2013-03-29T00:43:57.970 回答
2

好吧,在重新阅读这篇文章后,我发现了我的错误。这不是关于单独的 WIN32_FIND_DATAW 类型,而是需要将FindFirstFileW参数声明为Longand ByVal

Private Declare Function FindFirstFileW Lib "kernel32" _
    (ByVal lpFileName As Long, _
    ByVal lpFindFileData As Long) As Long

并且还需要用StrPtrand来调用它们VarPtr

TestW = FindFirstFileW(StrPtr(sf), VarPtr(wfd))
于 2013-03-29T04:16:15.437 回答