Hello,
Some time back I've recognize that the TCHAR support in the current SDK is insufficient. For example there are no macros for conversion between TCHAR <> Unicode and TCHAR <> Ascii. Also the conversion macros like udword$(),real4$(),... are not TCHAR aware.
Here are my suggestions:
WCharToAscii proc pBufferAscii:PCHAR,ccBuffer:DWORD,pszWChar:PWCHAR
LOCAL szCodePage[8]:CHAR
invoke GetLocaleInfoA,LOCALE_USER_DEFAULT,LOCALE_IDEFAULTANSICODEPAGE,ADDR szCodePage,SIZEOF szCodePage
.if eax
lea edx,szCodePage
xor eax,eax
.while CHAR ptr [edx]
movzx ecx,CHAR ptr [edx]
imul eax,eax,10
lea eax,[eax+ecx-'0']
lea edx,[edx+1]
.endw
.endif
invoke WideCharToMultiByte,eax,0,pszWChar,-1,pBufferAscii,ccBuffer,0,0
mov eax,pBufferAscii
ret
WCharToAscii endp
AsciiToWChar proc pBufferWChar:PWCHAR,ccBuffer:DWORD,pszAscii:PCHAR
LOCAL szCodePage[8]:CHAR
invoke GetLocaleInfoA,LOCALE_USER_DEFAULT,LOCALE_IDEFAULTANSICODEPAGE,ADDR szCodePage,SIZEOF szCodePage
.if eax
lea edx,szCodePage
xor eax,eax
.while CHAR ptr [edx]
movzx ecx,CHAR ptr [edx]
imul eax,eax,10
lea eax,[eax+ecx-'0']
lea edx,[edx+1]
.endw
.endif
invoke MultiByteToWideChar,eax,MB_PRECOMPOSED,pszAscii,-1,pBufferWChar,ccBuffer
mov eax,pBufferWChar
ret
AsciiToWChar endp
; TCHAR-macros
; pBuffer must not be pszTChar
tc2a macro pBuffer:req,ccBuffer:=<7fffffffh>,pszTChar:req
IFNDEF __UNICODE__
push pBuffer
fn szCopy,pszTChar,pBuffer
pop eax
ELSE
fn WCharToAscii,pBuffer,ccBuffer,pszTChar
ENDIF
EXITM <eax>
endm
; pBuffer must not be pszAscii
a2tc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszAscii:req
IFNDEF __UNICODE__
push pBuffer
fn szCopy,pszAscii,pBuffer
pop eax
ELSE
fn AsciiToWChar,pBuffer,ccBuffer,pszAscii
ENDIF
EXITM <eax>
endm
; pBuffer must not be pszTChar
tc2uc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszTChar:req
IFDEF __UNICODE__
push pBuffer
fn ucCopy,pszTChar,pBuffer
pop eax
ELSE
fn AsciiToWChar,pBuffer,ccBuffer,pszTChar
ENDIF
EXITM <eax>
endm
; pBuffer must not be pszWChar
uc2tc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszWChar:req
IFDEF __UNICODE__
push pBuffer
fn ucCopy,pszWChar,pBuffer
pop eax
ELSE
fn WCharToAscii,pBuffer,ccBuffer,pszWChar
ENDIF
EXITM <eax>
endm
;; TCHAR-macros
;tc2a macro pBuffer:req,ccBuffer:=<7fffffffh>,pszTChar:req
; IFNDEF __UNICODE__
; EXITM <pszTChar>
; ENDIF
; fn WCharToAscii,pBuffer,ccBuffer,pszTChar
; EXITM <eax>
;endm
;
;a2tc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszAscii:req
; IFNDEF __UNICODE__
; EXITM <pszAscii>
; ENDIF
; fn AsciiToWChar,pBuffer,ccBuffer,pszAscii
; EXITM <eax>
;endm
;
;tc2uc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszTChar:req
; IFDEF __UNICODE__
; EXITM <pszTChar>
; ENDIF
; fn AsciiToWChar,pBuffer,ccBuffer,pszTChar
; EXITM <eax>
;endm
;
;uc2tc macro pBuffer:req,ccBuffer:=<7fffffffh>,pszWChar:req
; IFDEF __UNICODE__
; EXITM <pszWChar>
; ENDIF
; fn WCharToAscii,pBuffer,ccBuffer,pszWChar
; EXITM <eax>
;endm
; declare TCHAR-strings
TCHR macro lbl,literals:VARARG
IFDEF __UNICODE__
UCSTR lbl,literals
ELSE
lbl db literals
ENDIF
endm
CTCHR macro lbl,literals:VARARG
IFDEF __UNICODE__
UCCSTR lbl,literals
ELSE
?cstr? lbl,literals
ENDIF
endm
; internal macro for converting integer and floating point values to strings
; _value = register or memory expression
; mname = name of convertion-macro
; pszTChrFrmt = pointer to format string (TCHAR)
; opr_size = size of type
; ccBufferSize = size of buffer in TCHARs
; _type = type-specifier: BYTE,SBYTE,...
; use_wsprintf = 0 => use crt_sprintf (CRT)
; != 0 => use wsprintf (user32.dll)
???To$ macro _value:req,mname:req,pszTChrFrmt:req,opr_size:req,ccBufferSize:req,_type:req,use_wsprintf:=<0>
LOCAL buffer,tmp,val
.data?
buffer TCHAR ccBufferSize dup(?)
.code
IFE issize(_value, opr_size)
echo ----------------------
echo mname - requires _type
echo ----------------------
.ERR
ENDIF
mov buffer[0], 0
IF opr_size EQ 1 OR opr_size EQ 2
IF type _type EQ type SBYTE OR type _type EQ type SWORD
movsx eax,_value
ELSE
movzx eax,_value
ENDIF
val TEXTEQU <eax>
ELSEIF opr_size EQ 4
IF type _type EQ type REAL4
sub esp,8
finit
fld _value
fstp REAL8 ptr [esp]
mov eax,DWORD ptr [esp]
mov edx,DWORD ptr [esp+4]
add esp,8
val TEXTEQU <edx::eax>
ELSE
val TEXTEQU <&_value>
ENDIF
ELSEIF opr_size EQ 8
IF @InStr(1,<_value>,<::>) EQ 0
mov eax,DWORD ptr (_value)
mov edx,DWORD ptr (_value)[4]
val TEXTEQU <edx::eax>
ELSE
val TEXTEQU <_value>
ENDIF
ELSEIF opr_size EQ 10 AND type _type EQ type REAL10
sub esp,8
finit
fld _value
fstp REAL8 ptr [esp]
mov eax,DWORD ptr [esp]
mov edx,DWORD ptr [esp+4]
add esp,8
val TEXTEQU <edx::eax>
ELSE
.err <invalid usage>
EXITM <0>
ENDIF
IF use_wsprintf EQ 0
IFNDEF __UNICODE__
invoke crt_sprintf, ADDR buffer, pszTChrFrmt, val
ELSE
invoke crt_swprintf, ADDR buffer, pszTChrFrmt, val
ENDIF
ELSE
invoke wsprintf,ADDR buffer, pszTChrFrmt, val
ENDIF
EXITM <OFFSET buffer>
endm
ubyte$ MACRO ubytevalue:req
IFNDEF ??ubfmt
.data
TCHR ??ubfmt,"%u",0
.code
ENDIF
EXITM ???To$(ubytevalue,<ubyte$>,ADDR ??ubfmt,1,4,BYTE)
endm
sbyte$ MACRO sbytevalue:req
IFNDEF ??sbfmt
.data
TCHR ??sbfmt,"%d",0
.code
ENDIF
EXITM ???To$(sbytevalue,<sbyte$>,ADDR ??sbfmt,1,5,SBYTE)
endm
xbyte$ MACRO xbytevalue:req
IFNDEF ??xbfmt
.data
TCHR ??xbfmt,"%X",0
.code
ENDIF
EXITM ???To$(xbytevalue,<xbyte$>,ADDR ??xbfmt,1,3,BYTE)
endm
uword$ MACRO uwordvalue:req
IFNDEF ??uwfmt
.data
TCHR ??uwfmt,"%u",0
.code
ENDIF
EXITM ???To$(uwordvalue,<uword$>,ADDR ??uwfmt,2,6,WORD)
endm
sword$ MACRO swordvalue:req
IFNDEF ??swfmt
.data
TCHR ??swfmt,"%d",0
.code
ENDIF
EXITM ???To$(swordvalue,<sword$>,ADDR ??swfmt,2,7,SWORD)
endm
xword$ MACRO xwordvalue:req
IFNDEF ??xwfmt
.data
TCHR ??xwfmt,"%X",0
.code
ENDIF
EXITM ???To$(xwordvalue,<xword$>,ADDR ??xwfmt,2,5,WORD)
endm
udword$ MACRO udwordvalue:req
IFNDEF ??udfmt
.data
TCHR ??udfmt,"%u",0
.code
ENDIF
EXITM ???To$(udwordvalue,<udword$>,ADDR ??udfmt,4,11,DWORD)
endm
sdword$ MACRO sdwordvalue:req
IFNDEF ??sdfmt
.data
TCHR ??sdfmt,"%d",0
.code
ENDIF
EXITM ???To$(sdwordvalue,<sdword$>,ADDR ??sdfmt,4,12,SDWORD)
endm
xdword$ MACRO xdwordvalue:req
IFNDEF ??xdfmt
.data
TCHR ??xdfmt,"%X",0
.code
ENDIF
EXITM ???To$(xdwordvalue,<xdword$>,ADDR ??xdfmt,4,9,DWORD)
endm
uqword$ MACRO uqwordvalue:req
IFNDEF ??uqwfmt
.data
TCHR ??uqwfmt,"%I64u",0
.code
ENDIF
EXITM ???To$(uqwordvalue,<uqword$>,ADDR ??uqwfmt,8,21,QWORD)
endm
sqword$ MACRO sqwordvalue:req
IFNDEF ??sqwfmt
.data
TCHR ??sqwfmt,"%I64d",0
.code
ENDIF
EXITM ???To$(sqwordvalue,<sqword$>,ADDR ??sqwfmt,8,22,QWORD)
endm
xqword$ MACRO xqwordvalue:req
IFNDEF ??xqwfmt
.data
TCHR ??xqwfmt,"%I64X",0
.code
ENDIF
EXITM ???To$(xqwordvalue,<xqword$>,ADDR ??xqwfmt,8,17,QWORD)
endm
real4$ MACRO r4value:req
LOCAL tmp
IFNDEF ??r8fmt
.data
TCHR ??r8fmt,"%f",0
.code
ENDIF
IFE (OPATTR r4value) AND 2
IF issize(r4value, 4)
push r4value
lea edx,[esp]
tmp TEXTEQU ???To$(REAL4 ptr [edx],<real4$>,ADDR ??r8fmt,4,32,REAL4)
add esp,4
EXITM tmp
ELSE
.err <real4$ - requires memory expression>
EXITM <0>
ENDIF
ENDIF
EXITM ???To$(r4value,<real4$>,ADDR ??r8fmt,4,32,REAL4)
ENDM
real8$ MACRO r8value:req
IFNDEF ??r8fmt
.data
TCHR ??r8fmt,"%f",0
.code
ENDIF
IFE (OPATTR r8value) AND 2
.err <real8$ - requires memory expression>
EXITM <0>
ENDIF
EXITM ???To$(r8value,<real8$>,ADDR ??r8fmt,8,32,REAL8)
ENDM
real10$ MACRO r10value:req
IFNDEF ??r8fmt
.data
TCHR ??r8fmt,"%f",0
.code
ENDIF
IFE (OPATTR r10value) AND 2
.err <real10$ - requires memory expression>
EXITM <0>
ENDIF
EXITM ???To$(r10value,<real10$>,ADDR ??r8fmt,10,32,REAL10)
ENDM
udb$ MACRO ubytevalue:req
IFNDEF ??ubfmt
.data
TCHR ??ubfmt,"%u",0
.code
ENDIF
EXITM ???To$(ubytevalue,<ubyte$>,ADDR ??ubfmt,1,4,BYTE,1)
endm
sdb$ MACRO sbytevalue:req
IFNDEF ??sbfmt
.data
TCHR ??sbfmt,"%d",0
.code
ENDIF
EXITM ???To$(sbytevalue,<sbyte$>,ADDR ??sbfmt,1,5,SBYTE,1)
endm
xdb$ MACRO xbytevalue:req
IFNDEF ??xbfmt
.data
TCHR ??xbfmt,"%X",0
.code
ENDIF
EXITM ???To$(xbytevalue,<xbyte$>,ADDR ??xbfmt,1,3,BYTE,1)
endm
udw$ MACRO uwordvalue:req
IFNDEF ??uwfmt
.data
TCHR ??uwfmt,"%u",0
.code
ENDIF
EXITM ???To$(uwordvalue,<uword$>,ADDR ??uwfmt,2,6,WORD,1)
endm
sdw$ MACRO swordvalue:req
IFNDEF ??swfmt
.data
TCHR ??swfmt,"%d",0
.code
ENDIF
EXITM ???To$(swordvalue,<sword$>,ADDR ??swfmt,2,7,SWORD,1)
endm
xdw$ MACRO xwordvalue:req
IFNDEF ??xwfmt
.data
TCHR ??xwfmt,"%X",0
.code
ENDIF
EXITM ???To$(xwordvalue,<xword$>,ADDR ??xwfmt,2,5,WORD,1)
endm
udd$ MACRO udwordvalue:req
IFNDEF ??udfmt
.data
TCHR ??udfmt,"%u",0
.code
ENDIF
EXITM ???To$(udwordvalue,<udword$>,ADDR ??udfmt,4,11,DWORD,1)
endm
sdd$ MACRO sdwordvalue:req
IFNDEF ??sdfmt
.data
TCHR ??sdfmt,"%d",0
.code
ENDIF
EXITM ???To$(sdwordvalue,<sdword$>,ADDR ??sdfmt,4,12,SDWORD,1)
endm
xdd$ MACRO xdwordvalue:req
IFNDEF ??xdfmt
.data
TCHR ??xdfmt,"%X",0
.code
ENDIF
EXITM ???To$(xdwordvalue,<xdword$>,ADDR ??xdfmt,4,9,DWORD,1)
endm
udq$ MACRO uqwordvalue:req
IFNDEF ??uqwfmt
.data
TCHR ??uqwfmt,"%I64u",0
.code
ENDIF
EXITM ???To$(uqwordvalue,<uqword$>,ADDR ??uqwfmt,8,21,QWORD,1)
endm
sdq$ MACRO sqwordvalue:req
IFNDEF ??sqwfmt
.data
TCHR ??sqwfmt,"%I64d",0
.code
ENDIF
EXITM ???To$(sqwordvalue,<sqword$>,ADDR ??sqwfmt,8,22,QWORD,1)
endm
xdq$ MACRO xqwordvalue:req
IFNDEF ??xqwfmt
.data
TCHR ??xqwfmt,"%I64X",0
.code
ENDIF
EXITM ???To$(xqwordvalue,<xqword$>,ADDR ??xqwfmt,8,17,QWORD,1)
endm
The two procedures, WCharToAscii and AsciiToWChar, are
using the user's current code page for conversion between Unicode and Ascii. Feedback about the macros and function would be great.
I've also discovered some bugs:
issize-macro: The macro uses the SIZE operator. This operator rejects valid, typecast expressions like DWORD pr [reg32]. The TYPE operator should be used instead, because it also return the number of bytes and does not reject typecast expressions. This was/is problem with conversion macros
type$():
issize MACRO var:req, bytes:req
LOCAL rval
rval = regsize(var)
IFE rval ; if not a register use TYPE <== previously: SIZE
IF TYPE var EQ bytes
EXITM <1>
ELSE
EXITM <0>
ENDIF
ELSE ; it's a register
IF rval EQ bytes
EXITM <1>
ELSE
EXITM <0>
ENDIF
ENDIF
ENDM
UCCSTR and ?cstr?:The macros emit
10, 13 instead of
13, 10 for "\n". This can easily fixed by replacing the strikingly line (the same in both macros):
Quote... SUBSTR < 5ch00h28h29h3ch3eh21h22h09h25h26h0ah,0dh>,...
==>
... SUBSTR < 5ch00h28h29h3ch3eh21h22h09h25h26h0dh,0ah>,...
regards, qWord
EIDT: add new version of a2tc,tc2a,uc2tc and tc2uc
Quote
Some time back I've recognize that the TCHAR support in the current SDK is insufficient. For example there are no macros for conversion between TCHAR, Unicode and Ascii
There is functions for that:
WideCharToMultiByte
MultiByteToWideChar
SysAllocString ......
Seems also you (or one another ) have made a macro for ascii >> unicode
Quote from: ToutEnMasm on September 10, 2012, 01:23:47 AM
Quote
Some time back I've recognize that the TCHAR support in the current SDK is insufficient. For example there are no macros for conversion between TCHAR, Unicode and Ascii
There is functions for that:
WideCharToMultiByte
MultiByteToWideChar
SysAllocString ......
Seems also you (or one another ) have made a macro for ascii >> unicode
you didn't look at the code?
A macro who can just interpret the masm natural syntax will be good for me.
(dw) "fghjkl",13,10,"56486',0
Why use \n ....
Quote from: ToutEnMasm on September 10, 2012, 01:53:17 AM
A macro who can just interpret the masm natural syntax will be good for me.
(dw) "fghjkl",13,10,"56486',0
there allready a macro in the SDK: UCSTR
... not to mention a wealth of Unicode support in MasmBasic ;-)
One BSTR is more often many BSTR and many useless lines to read.
A usefull tool for masm can be to create as many BSTR needed and just free them at the end.
Quote from: ToutEnMasm on September 10, 2012, 03:14:50 AM
One BSTR is more often many BSTR and many useless lines to read.
A usefull tool for masm can be to create as many BSTR needed and just free them at the end.
A screwdriver is a good tool! And what is useless? - Your posts in this thread!
Quote
A screwdriver is a good tool! And what is useless? - Your posts in this thread
Sorry,I leave you