R – determining the character set to use

delphidelphi-2009globalizationlocalizationtranslation

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta had a problem with my app failing precisely in this area. my app is used globally. some of this code may have become obsolete since d2009 uses unicode.

is all of this truly necessary in order for my app to work in all locales?

TForm.Font.Charset

it's been my understanding i must set the TForm instance's Font.Charset according to the user's locale. is this correct?

TranslateCharsetInfo( ) win API function

delphi 2009's windows.pas says:

function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; 

delphi 5's windows.pas says:

function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; stdcall;

from microsoft's MSDN:

BOOL TranslateCharsetInfo(
  __inout  DWORD FAR *lpSrc,
  __out    LPCHARSETINFO lpCs,
  __in     DWORD dwFlags
);

back when this code was written (back in delphi 5 days), the word was the inport of the function was incorrect and the correct way was:

function TranslateCharsetInfo(lpSrc: Pointer; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; stdcall; external gdi32;

notice that the d2009 windows.pas file copy is not stdcall. which declaration of TranslateCharsetInfo should i be using?

The code

that aside, essentially i've been doing the following:

var
  Buffer : PChar;
  iSize, iCodePage : integer;
  rCharsetInfo: TCharsetInfo;
begin
  // SysLocale.DefaultLCID = 1802
  iSize := GetLocaleInfo(SysLocale.DefaultLCID, LOCALE_IDefaultAnsiCodePage, 
              nil, 0);
  // size=14
  GetMem(Buffer, iSize);
  try
    if GetLocaleInfo(SysLocale.DefaultLCID, LOCALE_IDefaultAnsiCodePage, Buffer,
      iSize)=0 then
        RaiseLastOSError;

    // Buffer contains 0 so codepage = 0
    iCodePage:=Result := StrToInt(string(Buffer));
  finally
    FreeMem(Buffer);
  end;

  // this function is not called according to MSDN's directions for 
  // TCI_SRCCODEPAGE and the call fails.
  if not TranslateCharsetInfo(Pointer(iCodePage), rCharsetInfo, 
    TCI_SRCCODEPAGE) then
      RaiseLastOSError;

  // acts upon the form
  Font.Charset:= rCharsetInfo.ciCharset;
end;

i just don't know enough about this…strangely enough, years ago when i wrote this, i was persuaded that it was working correctly. the results of…failing to check API call return code…

isn't there a smarter way to do all this? doesn't the RTL/VCL do most/all of this automatically? my instincts tell me i'm working too hard on this…

thank you for your help!

Best Answer

Actually, I'm not sure about Delphi 2009, but MSDN says:

Note that DEFAULT_CHARSET is not a real charset; rather, it is a constant akin to NULL that means "show characters in whatever charsets are available."

So my guess is that you just need to remove all the code that you mentioned, and it should work.

Related Topic