Delphi:TRichEdit非默认非Unicode系统语言中的文本为字符串(ANSI)



因此设置如下:

  1. 制作一个带有TRichEdit控件的新Delphi7应用程序。我们在这里谈论的是非Unicode应用程序
  2. 在Windows的"区域和语言选项"中安装一种新的输入语言,该语言的编码与非Unicode程序的默认语言的编码不同,例如希腊语
  3. 在应用程序中添加一个按钮,在其OnClick处理程序中添加Button1.Caption := RichEdit1.Text;,并将其Font.Charset设置为您刚刚安装的输入语言的字符集(如果我们坚持这个示例,则为GREEK_CHARSET(
  4. 运行应用程序,切换到新的(希腊语(输入语言,在RichEdit中键入几个字母,然后按下按钮-按钮的标题现在有????符号,而不是希腊字符。

  5. 现在,如果您将非Unicode程序的默认语言设置为希腊文(需要重新启动Windows(,则此问题将消失-希腊文字符将正确显示。将非Unicode程序的默认语言设置回以前的语言,问题再次出现。

因此,我猜测TRichEdit在内部与Unicode配合使用,因为更改其Font.Charset值永远不会改变任何东西——RichEdit正确地接受任何安装的输入语言,如果你安装了两种不同的非拉丁语言,它们使用不同的字符集(例如希腊语/GREEK_CHARSET/和俄语/RUSSIAN_CHARSET/(,它会在不更改Font.Charset.的情况下接受这两种语言

我还猜测,当您获得TRichEdit的.Text(或.Lines[i](值时,它会根据Windws的非Unicode程序的默认语言将其内部Unicode文本转换为ANSI。

此外,将.Text值分配给WideString或UnicodeString也无法正常工作(文本再次出现在????中,而不是正确的字符(,这不仅仅是当您将其分配给String(AnsiString(时。

所以问题来了:

我希望能够正确地将RichEdit的文本转换为字符串(ANSI(,这是基于我选择的字符集,而不是系统的非Unicode程序的默认语言。我该怎么做?我更喜欢一个不涉及第三方组件的解决方案,但当然,如果不可能的话,任何事情都可以。

谢谢!

附言:切换到Delphi 2009或更高版本是不可接受的解决方案。

向底层富编辑窗口发送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;

相关内容

  • 没有找到相关文章

最新更新