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

时间:2008-11-04 22:34:38

标签: c++ mfc

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


目标: 我有点自己创建RichEdit工具栏(粗体,斜体,字体类型,字体大小等)。我希望模仿MS Word在选择的文本跨越选择时具有多个字体大小时所执行的操作。

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


到目前为止我做了什么: 当选择在CRichEditCtrl内部发生变化时,我收到了必要的通知。此外,如果选择中只有一个字体大小,我能够计算出来

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

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

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

2 个答案:

答案 0 :(得分: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”。

答案 1 :(得分:0)

一直在玩杂耍,但我终于能够工作了。 这就是我最终能够编译和运行的所有内容:

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;