如何获取/设置 unicode (utf8/utf16) 格式的 TTNTRichEdit RTF 内容?我使用 TStringStreams 的 TRichEdit.loadFromStream/saveToStream 方法来设置 RTF 内容。但它只对非标准 ASCII 字符使用依赖于语言环境的 ANSI 代码。(4x : \`f5
) 但是如果用户将他/她的项目带到另一台具有不同语言环境的计算机上,我会遇到麻烦。民族特色将消失。EM_STREAMIN/EM_SREAMOUT 消息 SF_UNICODE 标志只能与 SF_TEXT 结合,而不是 SF_RTF。
2 回答
你没有问题。您正在使用符合 Unicode 的组件。您不会遭受数据丢失。来自关于 RTF 的维基百科文章:
标准 RTF 文件只能包含 7 位 ASCII 字符,但可以通过转义序列对 ASCII 以外的字符进行编码。字符转义有两种类型:代码页转义和从 RTF 1.5 开始的 Unicode 转义。在代码页转义中,反斜杠和打字机撇号后面的两个十六进制数字用于表示取自 Windows 代码页的字符。例如,如果代码页设置为 Windows-1256,则序列
\'c8
将编码阿拉伯字母 bāʼ (ب)。对于 Unicode 转义,使用控制字 \u,后跟一个 16 位有符号十进制整数,给出 Unicode UTF-16 代码单元编号。对于不支持 Unicode 的程序,它后面必须跟在指定代码页中该字符的最接近的表示。例如,\u1576? 将给出阿拉伯字母 bāʼ ب,指定不支持 Unicode 的旧程序应将其呈现为问号。
您正在观察代码页转义。但这没关系。就是这样\`f5
。该字符位于文档的代码页中,因此可以使用代码页转义。如果您在文档的代码页之外包含字符,则控件将使用 Unicode 转义。
使用 Borland C++ 6解决(必须)。相同的代码模式适用于 Borland Delphi。(注意:TTntRichEdit 仅在明确具有 BOM 标头“\357\273\277”或 [0xEF, 0xBB, 0xBF] 时将 UTF-8 文本加载为 UTF-8)
// This only works with BOM explicit files
// (it will fail on BOM-less UTF-8 files)
TTntRichEdit *myTntRichEdit = ...{some init code}...
myTntRichEdit->Lines->LoadFromFile(UTF8_filename);
所以这是我的工作生产代码:(注意:TRESource 声明是 TTntRichEdit *TRESource;)
void TFormMyExample::LoadJavascriptFromFile(AnsiString myFile) {
// This method will load a UTF-8 text file (with or without BOM)
// // // TRESource->Lines->LoadFromFile(myFile);
TMemoryStream *JSMemoryStream;
TMemoryStream *JSBOM_MemoryStream;
AnsiString BOM = "\357\273\277"; // [0xEF, 0xBB, 0xBF]
try {
JSMemoryStream = new TMemoryStream();
JSMemoryStream->LoadFromFile(myFile);
// check for BOM
char BOMHeader[4];
JSMemoryStream->Seek(0, soFromBeginning);
JSMemoryStream->ReadBuffer(BOMHeader, 3);
JSMemoryStream->Seek(0, soFromBeginning); // reset
BOMHeader[3] = 0;
if (strcmp(BOM.c_str(), BOMHeader) == 0) {
// We have BOM header, so load it.
TRESource->Lines->LoadFromStream(JSMemoryStream);
} else {
// We need the BOM header, so add it.
try {
JSBOM_MemoryStream = new TMemoryStream;
JSBOM_MemoryStream->Write(BOM.c_str(), BOM.Length());
JSBOM_MemoryStream->Seek(0,soFromEnd);
JSBOM_MemoryStream->CopyFrom(JSMemoryStream, 0);
JSBOM_MemoryStream->Seek(0, soFromBeginning);
TRESource->Lines->LoadFromStream(JSBOM_MemoryStream);
}
__finally
{
delete JSBOM_MemoryStream;
}
}
}
__finally
{
delete JSMemoryStream;
}
}
当我编写处理后的文件时,它就是以这种方式完成的。(注意:TREProcessed 声明为 TTntRichEdit *TREProcessed;也:AnsiString outputFileName;)
ofstream SaveFile(outputFileName.c_str());
TREProcessed->PlainText = true;
SaveFile << "\357\273\277"; // Add UTF8 BOM [0xEF, 0xBB, 0xBF]
for (int i = 0, max = TREProcessed->Lines->Count; i < max; i++) {
SaveFile << UTF8Encode(TREProcessed->Lines->Strings[i]).c_str();
if (i < max - 1) {
SaveFile << UTF8Encode(_WS "\n").c_str();
}
}
SaveFile.close();