был вопрос по использованию TOM
добрый человек AlexZu (
) помог
Вы не указали платформу пазработки (.NET, WinAPI, some else), поэтому буду указывать несколько вариантов:
1) Для получения уведомления об изменении текста в richedit'е (RichTextBox) используйте соотв. событие (TextChanged, EN_CHANGE).
2) для получения позиции каретки можно использовать или RichTextBox.SelectionStart, или ITextSelection.Start.
3) После получения позиции каретки можно получить слово, в которое каретка попадает: для этого необходимо получить ITextRange, у которого Start и End = позиции каретки, затем у полученного ITextRange вызвать метод Expand с параметром tomWord.
4) для подсветки слова (либо иных модификаций атрибутов текста) исп-те у полученного ITextRange св-во Font (ITextFont).
5) о морганиях при работе с TOM имеет смысл беспокоится только при массовой модификации атрибутов (цвет, шрифт) текста, для подавления отрисовки у ITextDocument есть методы Freeze\Unfreeze.
5) для поиска примеров поищите в форумах RSDN (напр. в .NET GUI, COM, WinAPI) по словам TOM, ITextRange, ITextDocument, также можете посмотреть использование TOM'а в исходниках Wordpad (искать в MSDN).
6) также вам необходимо озаботиться об изменении текста с пом. drag'n'drop, в этом случае могут изменится 2 участка текста...
7) лучше все обсуждения вести в форуме RSDN, и вопросы задавать более конкретно
согласно пункту 7 следующий вопрос хочу спросить на форуме
платформа WinApi
в общем пользуя мсдн всё получилось
спасибо за пункт 2) — сам бы не додумался.. (может ещё есть какой то хитрый способ получить Range в который бы входило только слово на котором стоит каретка?)
вопрос по ходу возник такой, при использовании TOM у меня возникают проблемы с перемещением каретки — я ввожу текст, а каретка перезжает не вперёд как обчно, а назад (или же стоит на месте, а текст уезжзает вперёд), это можно как то исправить? может я чтото делаю не так..
вот приблизительно код
ITextDocument *pDoc;
ITextRange *pRange;
IUnknown *pUnk = NULL;
ITextFont *pFontSel = NULL;
SendMessage(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&pUnk);
if(pUnk &&
pUnk->lpVtbl->QueryInterface(pUnk, &IID_ITextDocument, &pDoc) == NOERROR)
{
int i=0;
pDoc->lpVtbl->Freeze(pDoc, &i);
pDoc->lpVtbl->Range(pDoc, 0, 4, &pRange);
pRange->lpVtbl->GetFont(pRange, &pFontSel);
if(!pFontSel)
pout("error");
pFontSel->lpVtbl->SetBold(pFontSel, tomTrue);
pFontSel->lpVtbl->Release(pFontSel);
pRange->lpVtbl->ChangeCase(pRange, tomUpperCase);
pDoc->lpVtbl->Unfreeze(pDoc, &i);
pDoc->lpVtbl->Release(pDoc);
pUnk->lpVtbl->Release(pUnk);
}
Здравствуйте, romanian, Вы писали:
R>был вопрос по использованию TOM
R>добрый человек AlexZu ( ) помог
R>платформа WinApi
R>в общем пользуя мсдн всё получилось
R>спасибо за пункт 2) — сам бы не додумался.. (может ещё есть какой то хитрый способ получить Range в который бы входило только слово на котором стоит каретка?)
Вам нужно только слово, а кому-то нужно предложение, и т.д. Для все этогоу ITextRange есть методы Move[Start, End], Expand, позволяющие расширить диапазон как вам угодно в соотв. с переданными параметрами.
Еще раз, более детально:
Как вы уже знаете у ITextDocument есть св-во ITextSelection, которое представляет диапазон (range) выделенного текста. Когда этот диапазон вырожденный (Start==End), т.е. нет выделения, он и представляет собой позицию каретки. Если же есть выделенный текст, то позиция каретки совпадает или с началом, или с концом выделения, в зависимости от того как текст был выделен пользователем.
Ну а имея необходимую позицю нетрудно получить и слово, в которую она попадает, см. пункт 3).
R>вопрос по ходу возник такой, при использовании TOM у меня возникают проблемы с перемещением каретки — я ввожу текст, а каретка перезжает не вперёд как обчно, а назад (или же стоит на месте, а текст уезжзает вперёд), это можно как то исправить? может я чтото делаю не так..
R>вот приблизительно код
<skipped>
В этомт коде вы изменяете только
атрибуты текста, вполне ессно, что каретка остается на месте.
Здравствуйте, AlexZu, Вы писали:
AZ>Здравствуйте, romanian, Вы писали:
R>>был вопрос по использованию TOM
R>>добрый человек AlexZu ( ) помог
AZ>
AZ>Вам нужно только слово, а кому-то нужно предложение, и т.д. Для все этогоу ITextRange есть методы Move[Start, End], Expand, позволяющие расширить диапазон как вам угодно в соотв. с переданными параметрами.
о — вот расширение я и искал..
т.е. надо расширять в обе стороны пока не встречу пробел
AZ>В этомт коде вы изменяете только атрибуты текста, вполне ессно, что каретка остается на месте.
этот код был повешен на обработку WM_KEYUP — выполнялось оно следующим образом, я ввожу в рич эдит текст, он вводится, но каретка остаётся на месте, как оказалось на это оказывало влияние
pRange->lpVtbl->ChangeCase(pRange, tomUpperCase);
убрал — и всё заработало как следует
в общем — спасибо те мил человек
твои советы мне очень помогли!
Здравствуйте, AlexZu, Вы писали:
AZ>Вам нужно только слово, а кому-то нужно предложение, и т.д. Для все этогоу ITextRange есть методы Move[Start, End], Expand, позволяющие расширить диапазон как вам угодно в соотв. с переданными параметрами.
чёто не вкурил как пользоваться MoveEndWhile
msdn не помог
синтаксис такой
STDMETHODIMP MoveEndWhile( VARIANT *Cset,
long Count,
long *pDelta
);
пытаюсь выполнять вот так
MoveEndWhile(C1_SPACE, 1, NULL);
выдаёт ошибку что C1_SPACE неверный Cset
подскажите как правильно сделать
Здравствуйте, romanian, Вы писали:
R>чёто не вкурил как пользоваться MoveEndWhile
R>msdn не помог
R>синтаксис такой
R>STDMETHODIMP MoveEndWhile( VARIANT *Cset,
R> long Count,
R> long *pDelta
R>);
R>пытаюсь выполнять вот так
R>MoveEndWhile(C1_SPACE, 1, NULL);
Посмтотрите ремарку к методу
ITextRange::MoveWhile, там есть пример на C++. Также посмотрите что такое тип VARIANT и ка кс ним работать.