如何在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实例:
- 在窗体
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
相关产品推荐
相关产品推荐

