4

セットアップは次のとおりです。

  1. TRichEdit コントロールを含む新しい Delphi 7 アプリケーションを作成します。ここでは、Unicode 以外のアプリケーションについて説明します。
  2. Windows の [地域と言語のオプション] で新しい入力言語をインストールします。これは、非 Unicode プログラム用の既定の言語のエンコーディングとは異なるエンコーディング (ギリシャ語など) です。
  3. アプリケーションにボタンを追加し、そのOnClickハンドラーに add を追加し、インストールしたばかりの入力言語の文字セットにButton1.Caption := RichEdit1.Text;設定します (この例に固執する場合)。Font.CharsetGREEK_CHARSET
  4. アプリケーションを実行し、新しい (ギリシャ語) 入力言語に切り替えて、RichEdit に数文字入力し、ボタンを押します。ボタンのキャプション????には、ギリシャ文字の代わりに記号が表示されます。

  5. 現在、非 Unicode プログラムのデフォルトの言語をギリシャ語に設定すると (Windows の再起動が必要)、この問題は解消され、ギリシャ語の文字が正しく表示されるようになります。非 Unicode プログラムのデフォルトの言語を以前の状態に戻すと、問題が再び発生します。

したがって、Font.Charset 値を変更しても何も変わらないため、TRichEdit は内部で Unicode と連携していると推測できます。RichEdit は、インストールされている入力言語を適切に受け入れます。また、異なる文字セットを使用する 2 つの異なる非ラテン言語 (ギリシャ語 / GREEK_CHARSET/ およびロシア語RUSSIAN_CHARSETの // たとえば) Font.Charset を変更せずに両方を受け入れます。

.Textまた、TRichEdit の(または) 値を取得すると、非 Unicode プログラム用.Lines[i]の Windws の既定の言語に基づいて、内部の Unicode テキストが ANSI に変換されると思います。

さらに.Text、WideString または UnicodeString への値の割り当ても適切に機能しません (適切な文字の代わりにテキストが再び挿入され????ます)。これは、文字列 (AnsiString) に割り当てる場合だけではありません。

だからここに質問があります:

非 Unicode プログラム用のシステムの既定の言語ではなく、選択した文字セットに基づいて、リッチエディットのテキストを文字列 (ANSI) に適切に変換できるようにしたいと考えています。どうやってやるの?サード パーティ製のコンポーネントを使用しないソリューションを希望しますが、もちろん、それが不可能な場合は何でも構いません。

ありがとう!

PS: Delphi 2009 以降への切り替えは、受け入れられるソリューションではありません。

4

1 に答える 1

5

基になるリッチ エディット ウィンドウにEM_GETTEXTEXメッセージを送信します。GETTEXTEXコード ページを指定する構造体を渡します。

したがって、次のようなものは、テキストを UTF-16 でエンコードされたものに引き出しますWideString

function GetRichEditText(RichEdit: TRichEdit): WideString;
var
  GetTextLengthEx: TGetTextLengthEx;
  GetTextEx: TGetTextEx;
  Len: Integer;
begin
  GetTextLengthEx.flags := GTL_DEFAULT;
  GetTextLengthEx.codepage := 1200;
  Len := SendMessage(RichEdit.Handle, EM_GETTEXTLENGTHEX, 
    WPARAM(@GetTextLengthEx), 0);
  if Len=E_INVALIDARG then
    raise Exception.Create('EM_GETTEXTLENGTHEX failed');
  SetLength(Result, Len);
  if Len=0 then
    exit;
  GetTextEx.cb := (Length(Result)+1)*SizeOf(WideChar);
  GetTextEx.flags := GTL_DEFAULT;
  GetTextEx.codepage := 1200;
  GetTextEx.lpDefaultChar := nil;
  GetTextEx.lpUsedDefChar := nil;
  SendMessage(RichEdit.Handle, EM_GETTEXTEX, WPARAM(@GetTextEx), 
    LPARAM(PWideChar(Result)));
end;

次に、その UTF-16 文字列を任意のコード ページに変換できます。特定のコードページで直接引き出したい場合は、次のようにします。

function GetRichEditText(RichEdit: TRichEdit; AnsiCodePage: UINT): AnsiString;
var
  GetTextLengthEx: TGetTextLengthEx;
  GetTextEx: TGetTextEx;
  Len: Integer;
begin
  GetTextLengthEx.flags := GTL_DEFAULT;
  GetTextLengthEx.codepage := AnsiCodePage;
  Len := SendMessage(RichEdit.Handle, EM_GETTEXTLENGTHEX, 
    WPARAM(@GetTextLengthEx), 0);
  if Len=E_INVALIDARG then
    raise Exception.Create('EM_GETTEXTLENGTHEX failed');
  SetLength(Result, Len);
  if Len=0 then
    exit;
  GetTextEx.cb := (Length(Result)+1)*SizeOf(AnsiChar);
  GetTextEx.flags := GTL_DEFAULT;
  GetTextEx.codepage := AnsiCodePage;
  GetTextEx.lpDefaultChar := nil;
  GetTextEx.lpUsedDefChar := nil;
  SendMessage(RichEdit.Handle, EM_GETTEXTEX, WPARAM(@GetTextEx), 
    LPARAM(PWideChar(Result)));
end;
于 2013-04-01T10:41:57.323 に答える