2017-09-06 70 views
0

從ANSI轉換爲Unicode並返回時出現問題。以下代碼片段描述了我正在做的事情。我得到的0x57錯誤..QB64中的WideCharToMultiByte

DECLARE DYNAMIC LIBRARY "kernel32" 
    FUNCTION MultiByteToWideChar& (codePage~&, dwFlags~&, lpszMbstring$, byteCount&, lpwszWcstring$, wideCount&) 
    FUNCTION WideCharToMultiByte& (codePage~&, dwFlags~&, lpWideString$, BYVAL ccWideChar%, lpMultiByte$, BYVAL multibyte%, BYVAL defaultchar&, BYVAL usedchar&) 
    FUNCTION GetLastError&() 
END DECLARE 
DIM Filename AS STRING * 260, NewFilename AS STRING * 260, MultiByte AS STRING * 260 
PRINT "Enter filename";: INPUT Filename$: 'Filename$ = Filename$ + CHR$(0) 
x = MultiByteToWideChar(0, 0, Filename$, LEN(Filename$), NewFilename$, 260) 
IF x = 0 THEN 
    PRINT "Error 0x"; HEX$(GetLastError) 
ELSE 
    PRINT "Processing: "; NewFilename$ 
END IF 
' do unicode stuff here 
x = WideCharToMultiByte(65001, 0, NewFilename$, LEN(NewFilename$), MultiByte$, 0, 0, 0) 
' display processed filename 
IF x = 0 THEN 
    PRINT "Error 0x"; HEX$(GetLastError) 
ELSE 
    PRINT MultiByte$ 
END IF 

回答

1

一些更ARGS需要用ByVal關鍵字傳遞:

FUNCTION MultiByteToWideChar& (BYVAL codePage~&, BYVAL dwFlags~&, lpszMbstring$, BYVAL byteCount&, lpwszWcstring$, BYVAL wideCount&) 
FUNCTION WideCharToMultiByte& (BYVAL codePage~&, BYVAL dwFlags~&, lpWideString$, BYVAL ccWideChar%, lpMultiByte$, BYVAL multibyte%, BYVAL defaultchar&, BYVAL usedchar&) 

除此之外,中STRING * 260長度總是260,無論任何價值的存儲。這意味着Filename = Filename + CHR$(0)將無法​​按預期工作,而不是MultiByteToWideCharWideCharToMultiByte中的任一個都需要以空字符結尾的輸入(這就是爲什麼byteCountccWideChar參數存在;有時您只想操作字符串的一部分)。

更糟的是,即使你使用_MEMFILLFilename所有字節設置爲0,允許您使用ASCIIZ字符串處理的事情,INPUTLINE INPUT將填補任何剩餘的字節沒有明確訂立FilenameCHR$(32)(即空白就好像你按下了空格鍵一樣)。例如,如果輸入「Hello」,則輸入的字符串將爲5個字節,字符代碼爲32個字節(如果您更喜歡十六進制,則爲&H20)。

爲了節省您自己的這個可怕的頭痛(「hello world.bas」是一個有效的文件名!),您需要使用STRING而不是STRING * 260。如果長度大於260,則應該打印一條錯誤消息。無論您是否允許用戶輸入新文件名,或者在此之後由您決定。

你還需要使用的MultiByteToWideChar返回值,因爲它是一個字符在NewFilename數量:

DIM Filename AS STRING 
DIM NewFilename AS STRING * 260 
DIM MultiByte AS STRING * 260 
... 

' Note: LEN(NewFilename) = 260 (**always**) 
' This is why the number of wide chars written 
' is saved. 
NewFilenameLen = MultiByteToWideChar(0, 0, Filename, LEN(Filename), NewFilename, LEN(NewFilename)) 

... 

' Note: LEN(MultiByte) = 260 (**always**) 
x = WideCharToMultiByte(65001, 0, NewFilename, NewFilenameLen, MultiByte, LEN(MultiByte), 0, 0) 

... 
+0

好的,再次感謝。這應該只是做一段時間,因爲我把所有的代碼拼在一起.. – eoredson

+0

順便說一句:爲什麼FindFirstFileW返回.cAlternateFilename爲NUL? – eoredson

+1

文檔聲明DOS 8.3格式文件名將在'cAlternateFilename'中,除非'cFilename'已經是8.3文件名,在這種情況下'cAlternateFilename'是一個空字符串。例如,'foo.txt'會導致一個空的'cAlternateFilename'成員,而'HelloWorld.txt'和'foo.config'可能導致'HelloW〜1.txt'和'foo〜7.con'。 –

相關問題