You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi 11.1.5中切换至RichEdit 4.1以解决RTF编码问题?

Delphi 11.1.5 TRichEdit 多语言字符编码问题及RichEdit 4.1切换方案

问题描述

使用Delphi 11.1.5自带的TRichEdit组件时,切换匈牙利语/英语键盘输入特殊字符(ő/ű/²),输出的RTF存在编码兼容问题:

  • 仅在全局\ansicpgN中设置一个代码页,未在字体表项\fN\cpgN中对应设置各字体的代码页
  • 特殊字符采用\'NN格式的ANSI编码,而非\uNNNN的UTF-16编码,导致跨环境解析时需手动匹配不同代码页才能得到正确字符(比如\'F5/\'fb需用1250码页,\'b2需用1252码页才能解析为ő²ű)

问题RTF示例

{\rtf1\ansi\ansicpg1250\deff0\nouicompat\deflang1038{\fonttbl{\f0\fnil\fcharset238 Arial;}{\f1\fnil\fcharset0 Arial;}{\f2\fnil\fcharset238 Times New Roman;}}
{\colortbl ;\red255\green0\blue0;}
{\*\generator Riched20 10.0.19041}\viewkind4\uc1 
\pard\f0\fs24\'f5\f1\lang1033\'b2\cf1\f2\lang1038\'fb\f0\par
}

该示例中,不同字体对应的特殊字符依赖不同代码页,但字体表未声明\cpgX,仅靠全局ansicpg1250会导致英语特殊字符²解析错误。

切换到RichEdit 4.1的正确方法

此前Bing给出的SetWindowLong用法错误,正确操作是在窗体创建时销毁默认RichEdit句柄,重新创建RichEdit 4.1实例:

  1. 在窗体OnCreate事件中添加以下代码:
procedure TForm1.FormCreate(Sender: TObject);
var
  ClassName: array[0..255] of Char;
begin
  // 确认当前控件为旧版本RichEdit
  GetClassName(RichEdit1.Handle, ClassName, SizeOf(ClassName));
  if CompareText(ClassName, 'RICHEDIT20W') = 0 then
  begin
    // 销毁旧控件句柄
    RichEdit1.Perform(WM_DESTROY, 0, 0);
    // 重新创建RichEdit 4.1控件(类名RICHEDIT50W对应4.1版本)
    RichEdit1.Handle := CreateWindowEx(
      0,
      'RICHEDIT50W',
      nil,
      WS_CHILD or WS_VISIBLE or ES_MULTILINE or ES_WANTRETURN or WS_VSCROLL,
      RichEdit1.Left, RichEdit1.Top, RichEdit1.Width, RichEdit1.Height,
      Self.Handle,
      0,
      HInstance,
      nil
    );
    // 恢复控件基础样式
    RichEdit1.Font.Assign(Self.Font);
    RichEdit1.Color := clWindow;
  end;
end;

关键说明

  • Windows系统中RichEdit 4.1的宽字符类名为RICHEDIT50W,而非RICHEDIT41
  • 重新创建句柄后需手动恢复字体、颜色等属性,避免样式丢失
  • 切换后特殊字符会以\uNNNN的UTF-16格式存储,无需依赖代码页设置,彻底解决多语言字符兼容问题

内容的提问来源于stack exchange,提问作者SOLID Developper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:10:23