使用windows的GetOpenFileNameW是可以解決問題,但前提是手動一個一個檔案去選擇
FileHwnd = CreateFile(VarPtr(UnicodeFileName(0)), GENERIC_READ, FILE_SHARE_READ, SA, OPEN_EXISTING, 0, 0)
得到句柄后再用ReadFile吸出任天堂紅白機ROM檔案里的游戲資料,然后就可以玩魂斗羅了。
但現在我目錄里有3000多個游戲,我要做個CRC校驗,不能每個游戲去選擇一次然后點擊。VB的內置函式全線崩潰,DIR、OPEN、這些都不支持Unicode。
看到過論壇有篇文章參考物件“Fso”轉短檔案名去解決的,這個可以使用,但這樣我的代碼要重寫了。因為在我的代碼中,掃描檔案、打開檔案、校驗CRC,三個功能全寫在了一個Function上,加上有些游戲是破解過的,我還手動寫了一種演算法,抽取魂斗羅里面的部份資料作特征碼驗證,所以這個Function要改起來工程很大。
我現在只能想到的方法只能是改動掃描檔案那部份代碼,將原來的DIR掃描換成FindFirstFileW,但我找個不到關于這個API的任何示例,外國人很牛逼的,他們反映FindFirstFileA不行,然后回貼那提示一下改成FindFirstFileW可以,然后那人就自己去改了,很牛逼,但我不牛逼啊,我只想讓我的小伙伴們快活地活下去而已,如何修改達到目的?我不是程式員啊,不要給我太高深的暗示,給我一點明示。我一會還得上社保局交社保。
uj5u.com熱心網友回復:
看你說了這么一大堆回答一下吧其實vb是很適合用w系列的函式的
Declare Function CreateFile Lib "kernel32" Alias "CreateFileW" (ByVal lpFileName As long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
dim s as string
FileHwnd = CreateFile(strptr(s), GENERIC_READ, FILE_SHARE_READ, SA, OPEN_EXISTING, 0, 0)
這樣傳進去的就是unicode了根本不用轉換,記得原來宣告的byval xx as string改為as long就行了
uj5u.com熱心網友回復:
很感激在我說了這么一大堆之后會有人看,但就是看了個標題D盤有個檔案“????????????????.txt”
dim s as string
s=dir("d:\")
你覺得這時候s變數的值是什么?答案是"????????????????????????????????
.txt"
于是乎我再用strptr("????????????????????????????????
".txt)得出變數的指標,傳進去引數
FileHwnd = CreateFile(strptr(s), GENERIC_READ, FILE_SHARE_READ, SA, OPEN_EXISTING, 0, 0)
雖然我現在沒條件測驗,但我覺得FileHwnd一定會等于“-1”
就那樣,算了當我什么都沒說
uj5u.com熱心網友回復:
請大家嘗試著耐心一次,看完我的貼子,然后想想“如何將一個Unicode檔案名傳入引數/變數”,而不是“傳入一個變數如何轉為Unicode”,更加不會是“傳入一個變數需不需要轉為Unicode”。
uj5u.com熱心網友回復:
先用 W 系列api獲取這個檔案的 unicode 檔案名,然后再傳給 createfileW 就行了uj5u.com熱心網友回復:
自己搞定了,CopyMemory但還有一個小細節,除了這樣賦值外還有什么好方法?
dim buff(512) as byte
游戲目錄 = "C:\"
buff(0) = &H43&
buff(1) = &H0&
buff(2) = &H3A&
buff(3) = &H0&
buff(4) = &H5C&
buff(5) = &H0&
我想達到的效果是,根據不同的目錄,賦入陣列相應的十六進制數值。(要對應unicode,每個字符占兩個Byte)
uj5u.com熱心網友回復:
樓主這個問題,無非就是列舉與讀取UNICODE檔案.那先要找一個支持UNICODE的DIR,這個的話就要API自己寫了,或使用VB.NET.
API方面正好我有一個ANSI版本的,改一下就可以列舉出UNICODE檔案名:
Option Explicit
'列舉指定目錄下的檔案.
'
'By 嗷嗷叫的老馬
'http://www.m5home.com/
Private Const INVALID_HANDLE_VALUE As Long = -1&
Private Const MAX_PATH As Long = 260&
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(MAX_PATH - 1) As Byte
cShortFileName(14 - 1) As Byte
End Type
Public Type byteFileName
bFileName() As Byte
End Type
Private Declare Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As Long) As Long
Private Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileW" ( _
ByVal lpFileName As Long, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileW" ( _
ByVal hFindFile As Long, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private WFD As WIN32_FIND_DATA
Dim m_isSearch As Boolean, isStop As Boolean
Dim m_outFiles() As byteFileName, m_outCount As Long
Public Function ListFileW(ByVal sourceDir As String, ByRef outFiles() As byteFileName, Optional ByVal isCheckSub As Boolean = True) As Long
'列出指定目錄下所有檔案
'
ReDim m_outFiles(1000)
m_outCount = 0
m_isSearch = True
isStop = False
Call Dir_Api(sourceDir, isCheckSub)
If m_outCount > 0 Then
ReDim Preserve m_outFiles(m_outCount - 1)
outFiles() = m_outFiles()
End If
ListFileW = m_outCount
End Function
Public Function isSearch() As Boolean
'查詢是否正在搜索中
'
isSearch = m_isSearch
End Function
Public Sub StopSearch()
'中斷搜索程序
'
isStop = True
DoEvents
End Sub
Private Sub Dir_Api(ByVal strPath As String, Optional ByVal isCheckSub As Boolean = True)
'遞回程序
'
Dim dirCount As Long, Dirs() As String, hItem As Long
Dim I As Long, J As Long, K As Long, II As Long, strTmp As String
Static tmpCount As Long
On Error GoTo errH
If isStop Then Exit Sub
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
hItem = FindFirstFile(StrPtr(strPath & "*.*"), WFD)
If hItem <> INVALID_HANDLE_VALUE Then
Do
tmpCount = tmpCount + 1
If tmpCount Mod 20 = 0 Then DoEvents
'檢查是不是目錄
If (WFD.dwFileAttributes And vbDirectory) Then
' 檢查是不是 "." or ".."
If Left(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1) <> "." And Left(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1) <> ".." Then
ReDim Preserve Dirs(0 To dirCount)
Dirs(dirCount) = Left(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)
dirCount = dirCount + 1
End If
Else
For I = 0 To UBound(WFD.cFileName) - 1
If WFD.cFileName(I) = 0 And WFD.cFileName(I + 1) = 0 Then
m_outFiles(m_outCount).bFileName = strPath '引發錯誤
m_outFiles(m_outCount).bFileName = strPath
K = UBound(m_outFiles(m_outCount).bFileName) + 1
ReDim Preserve m_outFiles(m_outCount).bFileName(1000)
II = -1
For J = K To K + I
II = II + 1
m_outFiles(m_outCount).bFileName(J) = WFD.cFileName(II)
Next
ReDim Preserve m_outFiles(m_outCount).bFileName(J)
m_outCount = m_outCount + 1
Exit For
End If
Next
End If
Loop While FindNextFile(hItem, WFD)
Call FindClose(hItem)
End If
If Not isCheckSub Then Exit Sub
For I = 0 To dirCount - 1
If isStop Then m_isSearch = False: Exit For
Dir_Api strPath & Dirs(I) & "\", isCheckSub
Next
Exit Sub
errH:
If Err.Number = 9 Then '下標越界,則擴大陣列.
ReDim m_outFiles(m_outCount + 1000)
Resume Next '擴大后繼續下一句.
End If
MsgBox "出現錯誤:" & Err.Description
isStop = True
End Sub
這代碼本來以前是回傳String的,現在改成byteFileName型別了,直接是位元組陣列,防止VB自作主張地轉換.
剩下打開并讀寫之類的,這個好象你已經用CreateFileW搞定了,那就沒啥問題了.
uj5u.com熱心網友回復:
抽了幾行有用的出來,其余的我刪掉了。
Option Explicit
'打開小伙伴指定的游戲.
'
'By 繳社保的老頭
'http://www.cug.net/~anonB/dj/djview.cgi?0628#joker2
Dim 檔案句柄, 搜索句柄 As Long
Dim 游戲目錄 As String
Dim 打比流愛撫弟 As WIN32_FIND_DATA
游戲目錄 = "c:\"
搜索句柄 = FindFirstFileW(StrPtr(游戲目錄 & "*.nes"), VarPtr(打比流愛撫弟))
FindClose 搜索句柄
ReDim 游戲目錄緩沖區(512) As Byte
Call StrConvUnicode(游戲目錄)
CopyMemory 游戲目錄緩沖區(Len(游戲目錄) * 2), 打比流愛撫弟.cFileName(0), 512 - Len(游戲目錄) * 2
檔案句柄 = CreateFile(VarPtr(游戲目錄緩沖區(0)), GENERIC_READ, FILE_SHARE_READ, SA, OPEN_EXISTING, 0, 0)
DrawTextW Me.hDC, VarPtr(游戲目錄緩沖區(0)), UBound(游戲目錄緩沖區) / 2, R, DT_CENTER
整出來才想起win98不支持unicode,我需要花點時間說服我的老伙伴們轉用win2000
uj5u.com熱心網友回復:
我上面給你的函式是取指定路徑下所有檔案名的,能支持子目錄,呼叫后就會回傳一個UNICODE格式的BYTE陣列.你這么一改,難道是只需要加載一個么.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/134054.html
標籤:API
