Page 1 of 1

OemToChar Bug

Posted: Mon Oct 07, 2019 7:35 pm
by mk-soft
Problem with convert OEM to String... (OemToCharW not work correctly)

API or PB Bug with 'TAB'

Code: Select all


Import ""
  OemToCharA(*scr, *dst)
  OemToCharW(*scr, *dst)
EndImport

CompilerIf #PB_Compiler_Version < 550
  Procedure Ascii(Text.s)
    Protected *mem
    *mem = AllocateMemory(Len(text) + 1)
    PokeS(*mem, Text, -1, #PB_Ascii)
    ProcedureReturn *mem
  EndProcedure
CompilerEndIf


Procedure.s OemToString(in.s)
  Protected r1, out.s, *pScr, *pDst, i, cnt 
  
  *pScr = Ascii(in)
  *pDst = AllocateMemory(Len(in) * 2 + 2)
  r1 = OemToCharW(*pScr, *pDst)
  out = PeekS(*pDst, -1, #PB_Unicode)
  FreeMemory(*pScr)
  FreeMemory(*pDst)

  ProcedureReturn out
  
EndProcedure

Procedure.s OemToAscII(in.s)
  Protected r1, out.s, *pScr, *pDst, i, cnt 
  
  *pScr = Ascii(in)
  *pDst = AllocateMemory(Len(in) * 1 + 2)
  r1 = OemToCharA(*pScr, *pDst)
  out = PeekS(*pDst, -1, #PB_Ascii)
  FreeMemory(*pScr)
  FreeMemory(*pDst)

  ProcedureReturn out
  
EndProcedure

Procedure OemWriteStringN(File, Text.s)
  Protected r1, *pDst, len
  
  text + #CRLF$
  len = Len(text)
  *pDst = AllocateMemory(len + 2)
  CharToOem_(@Text, *pDst)
  r1 = WriteData(File, *pDst, len)
  FreeMemory(*pDst)
  ProcedureReturn r1
EndProcedure

; OEM String
a.s = "1808	  18	P„ck	PŽCK"

;ShowMemoryViewer(@a, 64)
b.s = OemToString(a)
c.s = OemToAscII(a)
Debug "Bug: " + b
Debug "Ok: " + c

ShowMemoryViewer(@b, 64)

Re: OemToChar Bug

Posted: Fri Oct 11, 2019 5:19 am
by Pierre Bellisle
Hey,
No bug. As we know, the OEM is used by Win32 console applications, it came with DOS CP437.
The misnomer ANSI is used for non-unicode GUI applications.
A Chr(9) TAB character appearance is a "white circle".
With OemToChar(), the TAB character is Chr(9) for both OEM and "Ansi", this is why you got good result.
With OemToCharW(), the TAB character is Chr(9) for OEM and Chr(0x25CB) for unicode "white circle".
Function see TAB as a printable character and not as a control character.

You may use CharToOem() and then convert to unicode with MultiByteToWideChar(%CP_ACP,...)
or use CharToOemW() and then replace unicode Chr(0x25CB) with Chr(0x0900).
Note that CR and LF will need the same kind of attention.