QB64 中的 WideCharToMultiByte
WideCharToMultiByte in QB64
在从 ANSI 转换为 Unicode 并返回时遇到问题。以下代码片段描述了我在做什么。我收到 0x57 错误..
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
需要使用 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)
不会按预期工作,而不是 MultiByteToWideChar
或 WideCharToMultiByte
中的任何一个都需要以 null 结尾的输入(这就是 byteCount
和 ccWideChar
参数的原因存在;有时您只想对字符串的一部分进行操作)。
更糟糕的是,即使你使用_MEMFILL
将Filename
的所有字节设置为0以允许你处理使用ASCIIZ字符串的事情,INPUT
和LINE INPUT
将用 CHR$(32)
填充任何未明确输入 Filename
的剩余字节(即空白 space,就好像您按下 space 栏一样)。例如,如果您输入 "Hello",输入的字符串将有 5 个字节和 255 个字节的字符代码 32(如果您喜欢十六进制,则为 &H20
)。
为了避免让您自己头疼("hello world.bas" 是一个有效的文件名!),您需要使用 STRING
,而不是 STRING * 260
。如果长度大于 260,您可能应该打印一条错误消息。之后是否允许用户输入新文件名由您决定。
您还需要使用 MultiByteToWideChar
的 return 值,因为它是 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)
...
在从 ANSI 转换为 Unicode 并返回时遇到问题。以下代码片段描述了我在做什么。我收到 0x57 错误..
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
需要使用 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)
不会按预期工作,而不是 MultiByteToWideChar
或 WideCharToMultiByte
中的任何一个都需要以 null 结尾的输入(这就是 byteCount
和 ccWideChar
参数的原因存在;有时您只想对字符串的一部分进行操作)。
更糟糕的是,即使你使用_MEMFILL
将Filename
的所有字节设置为0以允许你处理使用ASCIIZ字符串的事情,INPUT
和LINE INPUT
将用 CHR$(32)
填充任何未明确输入 Filename
的剩余字节(即空白 space,就好像您按下 space 栏一样)。例如,如果您输入 "Hello",输入的字符串将有 5 个字节和 255 个字节的字符代码 32(如果您喜欢十六进制,则为 &H20
)。
为了避免让您自己头疼("hello world.bas" 是一个有效的文件名!),您需要使用 STRING
,而不是 STRING * 260
。如果长度大于 260,您可能应该打印一条错误消息。之后是否允许用户输入新文件名由您决定。
您还需要使用 MultiByteToWideChar
的 return 值,因为它是 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)
...