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 バージョンの 2 つのバージョンがあります。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

また、 and でそれらを呼び出す必要がStrPtrありVarPtrます。

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