如何查找richit控件中粗体文本的运行

How to find runs of bold text inside of a RichEdit control?

本文关键字:文本 运行 控件 richit 何查找 查找      更新时间:2023-10-16

我显然可以使用EM_GETCHARFORMAT一次处理一个字符,但它非常慢。

一个想法是以某种方式使用ITextDocument/ITextFont接口,另一个是使用EM_STREAMOUT消息并手动解析RTF。但我不能决定哪种方法更好,我对实现细节非常模糊。将感谢任何帮助,谢谢!

我已经找到了一个让我满意的解决方案,我想和你分享一下:

ITextRange接口包含一个非常有用的方法Expand,它可以用来查找连续运行的常量字符(tomCharFormat)和段落(tomParaFormat)格式。

下面是一些示例代码(警告:代码是一个没有任何错误处理的概念验证面条,根据需要应用重构):

    // Get necessary interfaces
    IRichEditOle* ole;
    SendMessage(hwndRichEdit, EM_GETOLEINTERFACE, 0, (LPARAM)&ole);
    ITextDocument* doc;
    ole->QueryInterface(__uuidof(ITextDocument), (void**)&doc);
    long start = 0;
    // Get total length:        
    ITextRange* range;
    doc->Range(start, start, &range);
    range->Expand(tomStory, NULL);
    long eof;
    range->GetEnd(&eof);
    // Extract formatting:
    struct TextCharFormat { long start, length; DWORD effects; }
    std::vector<TextCharFormat> fs;
    while(start < eof - 1)
    {
        doc->Range(start, start, &range);
        long n;
        range->Expand(tomCharFormat, &n); // <-- Magic happens here
        ITextFont* font;
        range->GetFont(&font);
        DWORD effects = 0;
        long flag;
        font->GetBold(&flag);
        if (flag == tomTrue) effects |= CFE_BOLD;
        font->GetItalic(&flag);
        if (flag == tomTrue) effects |= CFE_ITALIC;
        font->GetUnderline(&flag);
        if (flag == tomSingle) effects |= CFE_UNDERLINE;
        font->GetStrikeThrough(&flag);
        if (flag == tomTrue) effects |= CFE_STRIKEOUT;
        if (effects)
        {
            TextCharFormat f = { start, n, effects };
            fs.push_back(f);
        }
        start += n;
    }