RichEdit 2.0(Riched20.dll)加载RTF文本乱码及格式失效问题求助
问题原因与修复方案
1. 非拉丁文本乱码问题
RTF规范默认以ANSI编码解析内容,你直接在RTF串中嵌入西里尔字符时,RichEdit 2.0会按系统默认ANSI代码页解码,和你字符串实际使用的UTF-8编码不匹配,就会出现乱码。
修复方式:在RTF头部补充UTF-8编码声明,指定代码页为65001,匹配JSON默认的UTF-8编码格式:
{\\rtf1\\ansi\\ansicpg65001\\uc1 你的RTF内容 }
2. 加粗格式不生效问题
你当前的测试RTF串缺少必填的字体表定义,RichEdit解析时无法匹配到对应字重的字体资源,导致格式指令失效。
修复方式:在RTF头部补充基础字体表配置,明确指定渲染用的字体:
{\\rtf1\\ansi\\ansicpg65001\\uc1{\\fonttbl{\\f0\\fnil Microsoft Sans Serif;}}\\f0\\fs24 你的RTF内容 }
其中\fs24代表字号为12号(RTF字号单位为半磅),可根据需求调整。
后续需求适配建议
- 后续正式使用时如果RTF内容从WordPad导出,不需要手动拼接串,WordPad生成的RTF已经自带完整的编码声明、字体表等元信息,直接将JSON中取出的RTF内容喂给RichEdit即可,不会出现乱码和格式失效问题。
- 自定义TTF字体符号的渲染,只需要将自定义字体安装到系统,或者在RTF字体表中指定你的自定义字体名称即可正常识别。
- 超链接点击事件处理只需要给RichEdit控件添加
ENM_LINK事件掩码,响应EN_LINK通知消息即可,和当前RTF加载逻辑不冲突。
调整后的测试代码
DWORD CALLBACK EditStreamInCallback(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb) { std::stringstream* rtf = (std::stringstream*)dwCookie; *pcb = rtf->readsome((char*)pbBuff, cb); return 0; } // ... auto hwndEdit = CreateRichEdit(hWnd, 100, 100, 300, 300, hInstance); // 补充编码声明与字体表后的RTF测试串 std::stringstream rtf("{\\rtf1\\ansi\\ansicpg65001\\uc1{\\fonttbl{\\f0\\fnil Microsoft Sans Serif;}}\\f0\\fs24 Привет!\\par{ \\i This } is super {\\b text}.\\par}"); EDITSTREAM es = { 0 }; es.dwCookie = (DWORD_PTR)&rtf; es.pfnCallback = &EditStreamInCallback; SendMessage(hwndEdit, EM_STREAMIN, SF_RTF, (LPARAM)&es);
内容的提问来源于stack exchange,提问作者qloq
相关产品推荐
相关产品推荐

