Am having problems converting from ANSI to Unicode and back. The following code snip describes what I am doing. I am getting 0x57 errors..
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
Some more args need to be passed with the BYVAL keyword:
Aside from that, the length of
STRING * 260
is always 260, regardless of any value stored. This meansFilename = Filename + CHR$(0)
won't work as intended, not that either ofMultiByteToWideChar
orWideCharToMultiByte
require null-terminated input (that's why thebyteCount
andccWideChar
params exist; sometimes you only want to operate on a part of a string).Worse, even if you use
_MEMFILL
to set all bytes ofFilename
to 0 to allow you to deal with things using ASCIIZ strings,INPUT
andLINE INPUT
will fill any remaining bytes not explicitly entered intoFilename
withCHR$(32)
(i.e. a blank space as if you pressed the spacebar). For example, if you enter "Hello", there would be 5 bytes for the string entered and 255 bytes of character code 32 (or&H20
if you prefer hexadecimal).To save yourself this terrible headache ("hello world.bas" is a valid filename!), you'll want to use
STRING
, notSTRING * 260
. If the length is greater than 260, you should probably print an error message. Whether you allow a user to enter a new filename or not after that is up to you.You'll also want to use the return value of
MultiByteToWideChar
since it is the number of characters inNewFilename
: