2013-03-29 7 views
0

FindFirstFileA (ANSI) работает как следует, а FindFirstFileW (Unicode) нет. Широкая версия всегда возвращает -1 (INVALID_HANDLE_VALUE), но почему?Почему FindFirstFileW всегда возвращает -1?

'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 

P.S. Благодаря Carey Gregory, но мне по-прежнему нужно немного помочь перевести версию Wide. Что эквивалентно C/C++ WCHAR в VB6?

//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; 

ответ

2

WIN32_FIND_DATA имеет две версии так же, как функции, которые их используют: версии ANSI и Unicode версии. Вам необходимо определить WIN32_FIND_DATAA и WIN32_FIND_DATAW и использовать их соответственно с функциями «A» и «W».

+0

Можете ли вы уточнить, как W-версия вам понравится? –

+0

Как вы, очевидно, понимаете из-за своих функций 'TestA' и' TestW', существуют отдельные функции API Win32 для ANSI и Unicode-текста. Эти функции требуют отдельной структуры WIN32_FIND_DATA, так как эта структура содержит текстовые данные. Взгляните на определение WIN32_FIND_DATA в winbase.h, и должно быть очевидно, что вам нужно делать. –

+0

Спасибо за ответ! Мне все еще нужна помощь. См. Мой обновленный вопрос. –

2

Ну, после повторного чтения this article Я нашел свою ошибку. Речь идет не о отдельном типе WIN32_FIND_DATAW, но необходимо объявить FindFirstFileW аргументами как Long и ByVal.

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

А также нужно вызвать их StrPtr и .

TestW = FindFirstFileW(StrPtr(sf), VarPtr(wfd)) 
+0

Вам все равно нужно определить две отдельные структуры WIN32_FIND_DATA, потому что Unicode-версия FindFirstFile вернет структуру WIN32_FIND_DATAW. Я не эксперт VB, но я понимаю, что вы можете определить WCHAR в VB, используя ChrW. –

+0

@CareyGregory - Я думаю, что версия VB WIN32_FIND_DATAW невозможна, и, конечно, если кто-то знает дорогу, я буду признателен за исправления. –

+0

Это совсем не возможно. Просто объявляйте cFileName и cAlternateFileName как байт с длиной MAX_PATH * 2 и 14 * 2 соответственно. Примеры использования типов WCHAR в VB6 находятся по всему Интернету. Например, [здесь] (http://www.vbforums.com/showthread.php?365738-Classic-VB-Does-Visual-Basic-6-support-Unicode). –

Смежные вопросы