2

내 delphi 2009 앱에는 GNUGetText를 사용하는 기본 번역 시스템이 있습니다. 일부 win API 호출을 사용하여 글꼴을 준비했습니다. 몰타에서 온 누군가가 내 앱에 문제가있어이 분야에서 정확하게 실패 할 때까지 제대로 작동하고 있다고 생각했습니다. 내 앱은 전 세계적으로 사용됩니다. 이 코드 중 일부는 d2009가 유니 코드를 사용하므로 쓸모 없게 될 수도 있습니다.사용할 문자 집합을 결정합니다.

내 앱이 모든 로케일에서 작동하려면이 모든 것이 정말로 필요합니다.

TForm.Font.Charset는

내 이해 i는 사용자의 로케일에 따라 TForm의 인스턴스의 Font.Charset를 설정해야합니다이었다. 이 올바른지?

TranslateCharsetInfo() 승리 API 함수

델파이 2009의 windows.pas는 말한다 :

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

델파이 5의 windows.pas 말한다 : 마이크로 소프트의 MSDN에서

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

:

BOOL TranslateCharsetInfo(
    __inout DWORD FAR *lpSrc, 
    __out LPCHARSETINFO lpCs, 
    __in  DWORD dwFlags 
); 
이 코드는 (다시 델파이 5 일간) 작성되었습니다

다시는 단어는 함수의 인포가 잘못이었다 올바른 방법이었다

은 D2009의 windows.pas 파일 복사가
function TranslateCharsetInfo(lpSrc: Pointer; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; stdcall; external gdi32; 

통지 것을 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이이 중 대부분/전부를 자동으로 수행하지 않습니까? 내 직감은 내가이 일에 너무 열심히 일하고 있다고 말해. ...

당신의 도움에 감사드립니다!

답변

1

사실, 난 델파이 2009에 대해 잘 모르겠지만, MSDN 말한다 : DEFAULT_CHARSET 실제 캐릭터 세트 아니라고

참고; 오히려 NULL에 상수는 "사용할 수있는 문자 집합에 문자를 표시합니다"라는 의미입니다.

제 생각에 여러분이 언급 한 코드를 모두 제거하면됩니다.

+0

의견을 보내 주셔서 감사합니다. Lars D! 나는 로케일에서 내 앱을 사용해 볼 것을 누군가에게 요청할 것이다. –

0

이 질문에 대한 답변은 아니지만 D2009 +에서이 코드를 사용하면 가능한 메모리 손상에 대해 '작은'메모가 표시됩니다.함수 GetLocaleInfo "MSDN : 로케일 데이터 버퍼에서 검색된 문자 수를 반환합니다 ..."BYTES가 아니므로 D2009 +에서 각 문자 당 2 바이트를 할당해야합니다. 당신이 너무 작은 버퍼를 할당했기 때문에 예상치 못한 AVS (D2009의 +)로 이어질 수있는이없이

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

이 기능 GetLocaleInfo은, 당신의 기억을 덮어 쓸 수 있습니다 :이 작업을 수행하는 가장 좋은 방법은 쓰기입니다.

또한 왜 사용자 로케일 하나를 변경하려고 시도하지 않는지, 사용자가 사용자의 대상 변환 (예 : 러시아어로 번역하도록 설정되어 있지만 실행중인 영어 OS 인 경우 charset을 ANSI_CHARSET이 아닌 RUSSIAN_CHARSET로 변경해야합니다. 그리고 D2009 +가 필요한지 확실하지 않지만 잘못된 것일 수 있습니다.

+0

좋은 지적. 고맙습니다. –

관련 문제