Text formatting with RichEdit
[2]
Информацията тук е изцяло взаимствана от статията "Faster rich edit syntax highlighting" на Robert Dunn
Да започваме направо. За да форматираме
текста максимално бързо, трябва да изключим всякакви ненужни обработки на събития,
които забавят работата ни. Това става като изпратим едно EM_SETEVENTMASK на
нашия RichEdit. То се използва за задаване кои съобщения да изпраща RichEdit-а
към програмата. Значи казваме на RichEdit-а да не се занимава изобщо с изпращане
на MouseMove, MouseClick и т.н. докато работим. Освен това ще кажем на RichEdit-а
и да не се прерисува (WM_SETREDRAW) през това време. Ето как изглежда инициализиращия
код:
procedure Format(AHandle:
THandle);
var
eventMask: Integer;
begin
eventMask := SendMessage(AHandle, EM_SETEVENTMASK, 0, 0); //запазваме
предишната event mask
SendMessage(AHandle, WM_SETREDRAW, 0, 0); //изключваме redraw
ParseAllText(AHandle); //форматиране
SendMessage(AHandle, WM_SETREDRAW, 1, 0); //включваме redraw
InvalidateRect(AHandle, nil, true); //прересувай RichEdit-а
SendMessage(AHandle, EM_SETEVENTMASK, 0, eventMask);//възстановяваме
предишната event mask
end;
Когато форматираме текста е най-добре да забравим свойствата на TRichEdit компонента (пр. SelAttributes) и да ползваме съобщения. Така постигаме още по-голямо бързодействие. Ще ви покажа малко примерен код. За съжаление не можах да измисля точно какво да прави и няма някаква реална цел. Поне ще видите как се ползват съобщенията и общата идея на този метод за форматиране на текст.
Процедурата ParseAllText проверява дали селектирания текст е "then" и ако е сменя цвета му на син. Тази процедура е доста безмислена, но ви демонстрира работата с SetTokenColor, която можете да ползвате направо във вашата програма. SetTokenColor прави същинското форматиране. Тя получава Handle към RichEdit-а, участъка от текст и цвета, който трябва да се зададе. Тя наглася нова селекция (текста за форматиране), променя форматирането й и връща началната селекция.
procedure ParseAllText(AHandle:
THandle);
var
chrgSave, chrgSet: TCharRange;
str: string;
begin
SendMessage(AHandle, EM_EXGETSEL, 0, LongInt(@chrgSave)); //
взимаме размера на селекцията
SetLength(str, chrgSave.cpMax - chrgSave.cpMin); // инициализираме
str
SendMessage(AHandle, EM_GETSELTEXT, 0, LongInt(PChar(str)));
// слагаме селекцията в str
if str = 'then' then
begin
chrgSet.cpMin := chrgSave.cpMin; // инициализираме
chrgSet
chrgSet.cpMax := chrgSave.cpMax;
SetTokenColor(AHandle, chrgSet, clBlue); // задаваме
смяна на цвета
end;
end;
procedure SetTokenColor(AHandle:
THandle; ACharRange: TCharRange; AColor: TColor);
var
chrgSave: TCharRange;
cf: TCharFormat;
begin
SendMessage(AHandle, EM_EXGETSEL, 0, LongInt(@chrgSave)); //
запазваме текущата селекция
SendMessage(AHandle, EM_EXSETSEL, 0, LongInt(@ACharRange)); //
нагласяме участъка за промяна
cf.dwMask := CFM_COLOR; // инициализираме cf
cf.crTextColor := AColor;
cf.dwEffects := CFM_BOLD;
cf.cbSize := SizeOf(cf);
SendMessage(AHandle, EM_SETCHARFORMAT, SCF_SELECTION, LongInt(@cf));
// задаваме новия формат
SendMessage(AHandle, EM_EXSETSEL, 0, LongInt(@chrgSave)); //
връщаме селекцията
end;
Е надявам се разбрахте как оптимално можете да форматирате текст в RichEdit. Вече можете да се пробвате да направите собствен parser :-)
Ако имате някакви коментари или въпроси, ми изпратете един мейл.
Copyright
© 2002 Wise Guy
wise_guybg@yahoo.com
Last revised: 06.06.2002