В данном разделе приведено несколько примеров получения информации о текущем состоянии текста в окне редактирования. Примеры чисто демонстрационные, но используемые в них приемы могут быть полезны при решении различных задач обработки текстов.

Оператор

Labeil.Caption := IntToStr(RichEditl.Perform(

EM_GETFIRSTVISIBLELINE, 0,0) + 1);

отображает в метке Labeil номер первой видимой в окне строки. Номер, возвращаемый сообщением EM_GETFIRSTVISIBLELINE, увеличен на 1, чтобы номера строк отсчитывались от нуля, что более привычно пользователю.

Ниже приведен оператор, который отображает в строке состояния StatusBarl текст вида "Строка ... из ...". В нем вместо первого многоточия записывается строка, в которой расположен курсор, а вместо второго - общее число строк в тексте.

StatusBarl.SimpleText := 'Строка ' +

IntToStr(RichEditl.Perform(

EM_LINEFROMCHAR, RichEditl.SelStart, 0)+l) + ' из ' +

IntToStr(RichEditl.Perform(EMJ3ETLINECOUNT, 0, 0));

Строка месторасположения курсора получается сообщением EM_LINEFROM-CHAR, в которое передается позиция курсора - SelStart. А полное число строк возвращается сообщением EM_GETLINECOUNT. Приведенный оператор надо поместить в обработчики событий OnKeyDown, OnKeyUp и OnMouseDown компонента RichEditl. Тогда при любых манипуляциях пользователя с текстом в окне, находящемся в фокусе, в строке состояния будут отображаться сведения о строках. Аналогичные операторы полезно также вставить и в события тех управляющих элементов (кнопок, разделов меню), которые связаны со вставкой или удалением текста. Пример использования подобного оператора вы найдете на диске, приложенном к книге, в проекте PMessRichEdit в каталоге RichEdit (окно RichEdit3).

Следует отметить, что число строк, возвращаемое сообщением EM_GET-LINECOUNT, более правильное, чем число строк, возвращаемое свойством RichEditl.Lines.Count. Дело в том, что если текст кончается пустой строкой, то сообщение EM__GETLINECOUNT ее учитывает, а свойство Lines.Count не учитывает.

Оператор

Labeil.Caption := IntToStr(RichEditl.Perform(

EM_LINELENGTH, StrToInt CEditl.Text), 0) ) ;

отображает в метке Labeil число символов в строке, содержащей символ, индекс которого задан в окне редактирования Editl. В число символов включаются 2 заключительных символа "#13#10", если в тексте введен конец строки. Если в качестве первого параметра сообщения, взятого из Editl, задать -1, то в метку будет заноситься не число параметров в строке, а число невыделенных символов в строках, захватываемых выделением. Например, если в строке выделены все символы, кроме первого и двух завершающих символов перехода на новую строку, то сообщение вернет число 3 - один первый символ и два завершающих. Если выделение захватывает символы перехода на новую строку, то в подсчет невыделенных символов включается и следующая строка. Например, если выделено целиком несколько строк, включая завершающие символы последней, то сообщение вернет число символов в следующей строке.

Следующий обработчик события OnMouseMove окна RichEditl отображает в метке Label 1 символ, над которым перемещается курсор мыши:

procedure TForml.RichEditlMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
var p:TPoint;
ind: integers-begin p:=Point(x,y);

ind := RichEditl.Perform(EM_CHARFROMPOS,0,LongInt (@p)); if ind > 0

then Labell.Caption := RichEditl.Text[ind];
end;

Приведенный код относится к приложению VCL Win32. В приложении VCL .NET он может выглядеть так:

uses Types;
procedure TForml.RichEditlMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
var p:TPoint;
ind: integers-begin p:=Point(x,у);

ind := RichEditl.Perform(EM_CHARFROMPOS,0, p); if ind > 0

then Labell.Caption := RichEditl.Text[ind];
end;

Подключение модуля Types требуется для использованной в данном примере функции Point. Впрочем, можно обойтись без этой функции, а использовать конструктор записи TPoint. Тогда ссылку на Types можно убрать и создавать объект р оператором:

р := TPoint.Create(х,у);

Рассмотренный обработчик события OnMouseMove можно, конечно, использовать для более серьезных целей, например, для выделения цветом символа или содержащего его слова. Пример выделения слова см. в разд. 5.8.3.2. А ниже рассмотрен вариант выделения строки, над которой перемещается курсор мыши. Вы найдете этот пример на диске, приложенном к книге, в проекте PMessRichEdit в каталоге RichEdit (окно RichEdit3).

var OldLine: longint = -1;
procedure TForml.RichEditlMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
var p:TPoint;

ind, indline: longint; begin

// вариант приложения VCL Win32 p:=Point(x,у);
ind := RichEditl.Perform(EM_CHARFROMPOS, 0, Longint(@p) ) ;
// вариант приложения VCL .NET // p := TPoint.Create(x,y) ;

// ind := RichEditl.Perform(EM_CHARFROMPOS,0, p); if ind > 0 then begin

indline := RichEditl.Perform(EM_LINEFROMCHAR, ind, 0); if OldLine <> indline then begin

OldLine := indline;
RichEditl.SelStart := RichEditl.Perform(EM_LINEINDEX, indline, 0);
RichEditl.SelLength := RichEditl.Perform(EM_LINELENGTH, ind, 0);
end;
end;
end;

Глобальная переменная OldLine введена в этом коде только для того, чтобы предотвратить мерцание при перемещении курсора вдоль строки. Новое выделение производится только тогда, когда курсор мыши перемещается на другую строку. В коде использовано четыре типа сообщений. Сообщение EM_CHARFROMPOS указывает, как было описано ранее, позицию символа, над которым перемещается курсор. Сообщение EM__LINEFROMCHAR возвращает номер строки, содержащей этот символ. Сообщение EM_LINEINDEX возвращает индекс первого символа этой строки. Это значение задается как начало выделения - SelStart. А сообщение EM_LINELENGTH возвращает длину строки, содержащей символ. Это значение задается как длина выделения - SelLength.

5.8.3.3 Выделение и использование гиперссылок || Оглавление || 5.8.5 Использование канвы в окнах редактирования


Приемы программирования в Delphi на основе VCL



Новости за месяц

  • Март
    2020
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс