определение набора символов для использования - PullRequest
2 голосов
/ 13 ноября 2009

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

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

TForm.Font.Charset

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

Функция API TranslateCharsetInfo () win *

В 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;

от MSDN от Microsoft:

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

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

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

обратите внимание, что копия файла d2009 windows.pas не является stdcall. какое объявление 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 не делает большинство / все это автоматически? мои инстинкты говорят мне, что я слишком усердно работаю над этим ...

спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 13 ноября 2009

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

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

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

0 голосов
/ 15 ноября 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...