определение набора символов для использования

В моем приложении delphi 2009 есть базовая система перевода, использующая GNUGetText. Я использовал несколько вызовов Win API для подготовки шрифтов. Я думал, что он работает правильно до недавнего времени, когда у кого-то с Мальты возникла проблема с моим приложением, которое не работает именно в этой области. мое приложение используется во всем мире. часть этого кода могла быть устаревшей, так как d2009 использует юникод.

действительно ли все это необходимо для работы моего приложения во всех регионах?

TForm.Font.Charset

Насколько я понимаю, я должен установить Font.Charset экземпляра TForm в соответствии с локалью пользователя. это правильно?

TranslateCharsetInfo () выигрывает функцию API

delphi 2009 windows.pas говорит:

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

delphi 5 windows.pas говорит:

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

из Microsoft MSDN:

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

назад, когда этот код был написан (еще в delphi 5 дней), слово было inport функции было неверным, и правильный путь был:

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

обратите внимание, что копия файла d2009 windows.pas не является стандартным вызовом. какое объявление TranslateCharsetInfo мне следует использовать?

Код

Помимо этого, по сути, я делал следующее:

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;

я просто недостаточно знаю об этом ... как ни странно, много лет назад, когда я писал это, я был убежден, что это работает правильно. результаты ... неспособности проверить код возврата вызова API ...

разве нет более разумного способа сделать все это? разве RTL / VCL не делает большую часть / все это автоматически? мои инстинкты говорят мне, что я слишком много над этим работаю ...

Спасибо за помощь!


person X-Ray    schedule 13.11.2009    source источник


Ответы (2)


На самом деле я не уверен насчет Delphi 2009, но MSDN говорит:

Обратите внимание, что DEFAULT_CHARSET не является настоящей кодировкой; скорее, это константа, похожая на NULL, что означает «показывать символы в любых доступных наборах символов».

Я предполагаю, что вам просто нужно удалить весь упомянутый код, и он должен работать.

person Lars D    schedule 13.11.2009
comment
спасибо за ваш комментарий Lars D! Я попрошу кого-нибудь попробовать мое приложение в таком регионе. - person X-Ray; 24.11.2009

Не совсем ответ на этот вопрос, но «небольшое» примечание о возможном повреждении памяти этим кодом в D2009 +. Функция GetLocaleInfo «MSDN: возвращает количество символов, извлеченных в буфере данных локали ...», а не БАЙТЫ, поэтому в D2009 + вы ДОЛЖНЫ выделить 2 байта для каждого символа. Лучший способ сделать это - написать:

GetMem(Buffer, iSize * SizeOf(Char)); //This will be safe for all delphi versions

Без этого вы можете привести к непредсказуемым AV (D2009 +), функция GetLocaleInfo может перезаписать вашу память, потому что вы выделили слишком маленький буфер.

Также я не понимаю, почему вы пытаетесь изменить кодировку на локаль пользователя, я думаю, что вам следует изменить кодировку на перевод места назначения (например, ваша программа настроена на перевод на русский язык, но работает в английской ОС, тогда вам нужно изменить кодировку на RUSSIAN_CHARSET, а не ANSI_CHARSET). А под D2009 + я не уверен, нужно ли это, но могу ошибаться.

person Krystian Bigaj    schedule 14.11.2009