Как я могу решить, если выделенный текст в CRichEditCtrl имеет несколько размеров шрифта? - PullRequest
1 голос
/ 05 ноября 2008

Проблема: Как я могу определить, содержит ли выделенный текст в CRichEditCtrl несколько размеров шрифта?


Цель: Я делаю свою собственную панель инструментов RichEdit (полужирный, курсив, тип шрифта, размер шрифта и т. Д.). Я хочу подражать тому, что делает MS Word, когда выделение текста имеет более одного размера шрифта, охватывающего выделение.

Пример - у вас есть строка текста с шрифтом из первых 10 символов 9 pt и шрифтом из следующих 15 символов 14 pt. Если вы выделите первые 5 символов, в раскрывающемся списке «Font Pt Selection» отобразится «9». Если затем вы выберете первые 20 символов, в этом же раскрывающемся списке должно появиться пустое / пустое отображение.


Что у меня так далеко: Я получаю необходимое уведомление, когда выбор меняется внутри CRichEditCtrl. Кроме того, если в выделении есть только один размер шрифта, я могу это выяснить

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

Это даст мне необходимую информацию для первого случая моего примера выше. К сожалению, то, что я получаю для второй части моего примера, возвращает мне только информацию о том, где заканчивается выбор (вместо всего выбора).

В заключение, есть ли какая-то информация, которую мне не хватает в CHARFORMAT или какой-либо другой структуре, которую я могу получить из CRichEditCtrl, или какой-то интересный расчет, который я могу сделать, чтобы принять решение о том, что в выборе есть несколько размеров? Пока что моя единственная идея состоит в том, чтобы пройтись по выделенному символу за раз и посмотреть, отличается ли текущий размер шрифта этого символа от любого из предыдущих символов. Я просто надеюсь, что информация, которая мне нужна, там есть, и я просто ее не вижу (аналогично тому, что член dwMask CHARFORMAT сообщает мне, что какие-либо или все Bold, Italic, Underline и т. Д. Включены).

Ответы [ 2 ]

1 голос
/ 05 ноября 2008

Как отмечается в ответе выше, самый простой способ сделать это - использовать объектную модель текста (TOM), доступ к которой осуществляется через интерфейс COM ITextDocument. Чтобы добиться этого с помощью расширенного элемента управления редактирования (код заметки не проверен, но должен работать):

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".

0 голосов
/ 07 ноября 2008

Жонглировал парой вещей, но я наконец-то смог работать. Вот как я наконец смог получить все для компиляции и запуска:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...