如何确定 CRichEditCtrl 中的文本选择是不是具有多种字体大小?

Posted

技术标签:

【中文标题】如何确定 CRichEditCtrl 中的文本选择是不是具有多种字体大小?【英文标题】:How do I decide if a selection of text in CRichEditCtrl has multiple font sizes?如何确定 CRichEditCtrl 中的文本选择是否具有多种字体大小? 【发布时间】:2008-11-04 22:34:38 【问题描述】:

问题: 如何判断 CRichEditCtrl 中的选定文本是否有多种字体大小?


目标: 我正在制作自己的 RichEdit 工具栏(粗体、斜体、字体类型、字体大小等)。我想模仿 MS Word 在选择的文本具有多个跨越选择的单一字体大小时所做的事情。

Ex - 您有一行文本,前 10 个字符为 9 pt 字体,接下来的 15 个字符为 14 pt 字体。如果突出显示前 5 个字符,“字体点选择”下拉菜单将显示“9”。如果您随后选择前 20 个字符,则相同的下拉菜单应显示为空/空白。


到目前为止我做了什么: 当 CRichEditCtrl 中的选择发生变化时,我会收到必要的通知。另外,如果选择中只有一个字体大小,我可以弄清楚

CHARFORMAT cf;
cf.cbSize = sizeof(CHARFORMAT);
CRichEditCtrl ctrl;
ctrl.GetSelectionCharFormat( cf );
int nFontPtSize = cf.yHeight / 20;

这将为我上面示例的第一种情况提供所需的信息。不幸的是,我在示例的第二部分中得到的信息似乎只给了我选择结束位置的信息(而不是整个选择)。

总之,在 CHARFORMAT 或我可以从 CRichEditCtrl 获得的其他一些结构中是否缺少一些信息,或者我可以做一些有趣的计算来决定选择中有多种尺寸?到目前为止,我唯一的想法是一次选择一个字符,看看该字符的当前字体大小是否与之前的任何字符不同。我主要只是希望我需要的信息在那里,我只是看不到它(以类似的方式从 CHARFORMAT 的 dwMask 成员告诉我,任何或所有粗体、斜体、下划线等都已打开)。

【问题讨论】:

【参考方案1】:

正如上面的答案所述,我能想到的最简单的方法是使用文本对象模型 (TOM),它是通过 ITextDocument COM 接口访问的。要从您的富编辑控件中获取此信息(注意代码未经测试,但应该可以工作):

CComPtr<IRichEditOle> richOle;
richOle.Attach(edit.GetIRichEditOle());
CComQIPtr<ITextDocument> textDoc(richOle);

然后得到一个范围。这里是针对选定的文本,但 TOM 的优点之一是您可以对任何范围进行操作,而不仅仅是选定的内容。

CComPtr<ITextSelection> range;
textDoc->GetSelection(&range);

然后获取范围的字体,看看它的特征是什么,例如

CComPtr<ITextFont> font;
range->GetFont(&font);
long size;
font->GetSize(&size);

如果范围使用单一字体大小进行格式化,您将恢复为“大小”。如果有多种字体大小,您将获得值“tomUndefined”。

【讨论】:

【参考方案2】:

一直在处理一些事情,但我终于能够工作了。 这就是我最终能够编译和运行所有内容的方式:

HWND hwnd;
ITextDocument* pDoc;
IUnknown* pUnk = NULL;
float size = 0;
hwnd = GetSafeHwnd();
::SendMessage( hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pUnk );
   if ( pUnk && pUnk->QueryInterface( __uuidof(ITextDocument), (void**)&pDoc ) == NOERROR )
   
      CComPtr<ITextSelection> range;
      pDoc->GetSelection( &range );
      CComPtr<ITextFont> font;
      range->GetFont( &font );     
      // If there are multiple font sizes in the selection, "size" comes back as -9999 
      font->GetSize(&size);
   
return size;

【讨论】:

以上是关于如何确定 CRichEditCtrl 中的文本选择是不是具有多种字体大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CRichEditCtrl 中禁用 RTF 表格边框?

CRichEditCtrl 如何忽略按键?

如何将 Unicode 支持添加到 CRichEditCtrl?

如何在CRichEditCtrl控件中直接读如RTF格式的文件(这个是通过流的方式来读取文件)

如何确定Javascript中项目网格中的选择范围之间的重叠

如何确定在 SwiftUI 中的多词文本视图中点击的词