-1

如何获取/设置 unicode (utf8/utf16) 格式的 TTNTRichEdit RTF 内容?我使用 TStringStreams 的 TRichEdit.loadFromStream/saveToStream 方法来设置 RTF 内容。但它只对非标准 ASCII 字符使用依赖于语言环境的 ANSI 代码。(4x : \`f5) 但是如果用户将他/她的项目带到另一台具有不同语言环境的计算机上,我会遇到麻烦。民族特色将消失。EM_STREAMIN/EM_SREAMOUT 消息 SF_UNICODE 标志只能与 SF_TEXT 结合,而不是 SF_RTF。

4

2 回答 2

1

你没有问题。您正在使用符合 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 转义。

于 2015-08-11T22:19:59.443 回答
0

使用 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();

于 2021-06-25T16:40:13.280 回答