【问题标题】:Loading RTF text from database into TRichEdit将 RTF 文本从数据库加载到 TRichEdit
【发布时间】:2010-11-02 01:47:06
【问题描述】:

我目前正在将我们的软件解决方案从 Delphi 7 迁移到 2010。大部分更改都很简单,只剩下少量障碍。

在表单上,​​我们使用 TRichEdit 显示从 MSSQL 数据库中的 blob 字段抓取的 rtf 文本。这就是它在 Delphi 7 中的工作方式:

//Get RTF text from Blob field using TADOQuery
rtfStream := sql.CreateBlobStream(sql.FieldByName('rtftext'), BmRead) as TMemoryStream;

//Load into TRichEdit
RichEdit.PlainText := False;
RichEdit.Lines.LoadFromStream(rtfStream);

这将在 TRichEdit 组件中按预期显示 RTF,但 Delphi 2010 中的相同代码将 RTF 显示为纯文本,每个字符之间有制表符。我认为这与从 Ansi 到 Unicode 的变化有很大关系,但我没有任何运气来纠正这个问题。

任何帮助使它工作将不胜感激。谢谢

【问题讨论】:

    标签: delphi unicode delphi-2010 ansi richedit


    【解决方案1】:

    好吧,我想通了。

    用于加载 rtf 文本:

    //Get the data from the database as AnsiString
    rtfString := sql.FieldByName('rtftext').AsAnsiString;
    
    //Write the string into a stream
    stream := TMemoryStream.Create;
    stream.Clear;
    stream.Write(PAnsiChar(rtfString)^, Length(rtfString));
    stream.Position := 0;
    
    //Load the stream into the RichEdit
    RichEdit.PlainText := False;
    RichEdit.Lines.LoadFromStream(stream);
    
    stream.Free;
    

    用于保存 rtf 文本:

    //Save to stream
    stream := TMemoryStream.Create;
    stream.Clear;
    
    RichEdit.Lines.SaveToStream(stream);
    stream.Position := 0;
    
    //Read from the stream into an AnsiString (rtfString)
    if (stream.Size > 0) then begin
        SetLength(rtfString, stream.Size);
        if (stream.Read(rtfString[1], stream.Size) <= 0) then
            raise EStreamError.CreateFmt('End of stream reached with %d bytes left to read.', [stream.Size]);
    end;
    
    stream.Free;
    
    //Save to database
    sql.FieldByName('rtftext').AsAnsiString := rtfString;
    

    我花了很长时间才弄清楚 :) 我想我已经学到了一件事......如果 Delphi 2010 出现问题,它通常与 unicode 相关;)

    【讨论】:

    【解决方案2】:

    当 PlainText 为 False 时,LoadFromStream() 首先尝试加载 RTF 代码,如果失败,则 LoadFromStream() 再次尝试将流作为纯文本加载。在所有 Delphi 版本中都是如此。随着 Unicode 的引入,我想 LoadFromStream() 的 EM_STREAMIN 回调处理程序可能会出现问题。我建议您使用调试器进入 LoadFromStream() 的实际源代码,看看实际发生了什么。

    【讨论】:

    • 感谢您的提示。由于某种原因,我无法追踪到 LoadFromStream 代码,但这让我想到了正确的方法,从而导致了我的解决方案。
    • 传统上 Delphi 使用 RTDEdit v.1.0 而忽略了 v.2.0 和 v.3.0 *(被 RxLib、JediVCL、TRichView 等使用)。如果只有 Delphi 有 TAnsiStringStream 或使用更现代的 RTF 编辑控件,则可以通过msdn.microsoft.com/en-us/library/windows/desktop/bb774302.aspx 阅读 EM_STREAMIN 禁止使用 UNICODE
    • Unicode 不被 EM_STREAMIN 禁止,它可以使用,但只能与 SF_TEXT 标志一起使用,TRichEdit 就是这样使用它的。 SF_UNICODE 在 RE 1.0 中不受支持,但 TRichEdit 在最近的 VCL 版本(包括 2010)中显式加载 RE 2.0(在支持 3.0 的 Windows 版本上静默加载 RE 3.0)。
    • @RemyLebeau Mea 确实有过失。深入研究了临时 RTF 字符串生成器并与规范匹配,结果发现它是不正确的。因此,至少在 XE2 中,他们为 rtf 修复了 loadfromstream。它可能比 AnsiStringStream 效率低,但它确实有效。
    猜你喜欢
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2015-06-13
    相关资源
    最近更新 更多