WideCharToMultiByte в 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
1 ответ
Еще несколько аргументов необходимо передать с помощью ключевого слова 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
требуется нулевой ввод (вот почему byteCount
а также ccWideChar
параметры существуют; иногда вы хотите оперировать только частью строки).
Хуже, даже если вы используете _MEMFILL
установить все байты Filename
на 0, чтобы позволить вам иметь дело с вещами, используя строки ASCIIZ, INPUT
а также LINE INPUT
заполнит все оставшиеся байты, явно не введенные в Filename
с CHR$(32)
(т.е. пробел, как будто вы нажали пробел). Например, если вы введете "Hello", будет 5 байт для введенной строки и 255 байт кода символа 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)
...