HLine := tm.tmHeight + tm.tmExternalLeading;
Sender.Perform(EM_GETRECT,0, R);
WLine := R.Right - R.Left+1;
Brush.Color := clBlack;
FrameRect(TRect.Create(0, NLine*HLine+l, WLine+1, (NLine+1)*HLine+l));
end;
end;
procedure TForml.UnSelectText(Sender: TCustomMemo);
begin if NLine >
-1 then with MyCanvas do begin Brush.Color := Sender.Brush.Color;
FrameRect(TRect.Create(0, NLine*HLine+l, WLine+1, (NLine+1)*HLine+l));
NLine := -1;
end;
end;

Приведенные варианты процедур годятся для любых окон редактирования типа ТМешо и TRichEdit.

Во всех приведенных примерах выделение строки портится, как только начинается редактирование этой строки. Это можно исправить, введя в соответствующие моменты восстановление выделения. Особенно легко это сделать для выделения рамкой. Достаточно в обработчик события OnKeyUp окна редактирования в приложении VCL Win32 вставить оператор:

if (NLine = (Sender as TMemo).CaretPos.Y) then MyCanvas.FrameRect(Rect(0, NLine*HLine+l, WLine+1, (NLine+1)*HLine+l));

В приложении VCL .NET аналогичный оператор имеет вид:

if (NLine = (Sender as TMemo).CaretPos.Y) then MyCanvas.FrameRect(TRect.Create(0, NLine*HLine+l, WLine+1, (NLine+1)*HLine+l));

Приведенные примеры работают, если текст в окне не прокручивается. Но при прокрутке выделение сбивается. Чтобы ликвидировать этот последний недостаток, можно ввести новую глобальную переменную:

var FirstLine: longint;

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

FirstLine := Sender.Perform(EM_GETFIRSTVISIBLELINE,0,0);

Кроме того, надо заменить все операторы вызовов процедуры FrameRect в приложении VCL Win32 операторами:

FrameRect(Rect(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l));

а в приложении VCL .NET заменить их операторами:

FrameRect(TRect.Create(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l));

В этих операторах местоположение строки определяется как разность номера строки и значения FirstLine.

В класс формы надо добавить еще одну процедуру UpdateSelectText, которая обновляет выделение. В приложении VCL Win32 она может иметь вид:

procedure TForml.UpdateSelectText(Sender: TCustomMemo); var NewFirstLine: longint; begin if NLine > -1 then begin

NewFirstLine := Sender.Perform(EM_GETFIRSTVISIBLELINE, 0,0) ;
if NewFirstLine <>
FirstLine then with MyCanvas do begin Brush.Color := Sender.Brush.Color;
FrameRect(Rect(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l));
FirstLine := NewFirstLine;
Brush.Color := clBlack;
FrameRect(Rect(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l));

end

else if (NLine = Sender.CaretPos.Y) then

MyCanvas.FrameRect(Rect (1, (NLine-FirstLine) *HLine+l, WLine, (NLine-FirstLine-rl) * HLine+1) ) ;
end;
end;

В приложениях VCL .NET аналогичный код имеет следующий вид (жирным шрифтом выделены операторы, отличающиеся от приведенных выше):

procedure TForml.UpdateSelectText(Sender: TCustomMemo); var NewFirstLine: longint; begin if NLine > -1 then begin

NewFirstLine := Sender.Perform(EM_GETFIRSTVIoIBLELINE,0, C) ;
if NewFirstLine FirstLine then with MyCanvas do begin Brush.Color := Sender.Brush.Color;
FrameRect(TRect.Create(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l) ) ;
FirstLine := NewFirstLine;
Brush.Color := clBlack;
FrameRect(TRect.Create(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l) ) ;

end

else if (NLine = Sender.CaretPos.Y) then

MyCanvas.FrameRect(TRect.Create(1, (NLine-FirstLine)*HLine+l, WLine, (NLine-FirstLine+1)*HLine+l));
end;
end;

В обработчики событий окна OnKeyUp и OnMouseUp надо вести вызов этой процедуры:

UpdateSelectText(Sender as TCustomMemo);
SelectText(Sender as TCustomMemo);

При этом описанный ранее оператор в обработчике OnKeyUp надо удалить.

Полный текст этого варианта выделения строки вы найдете в примере PMess-RichEdit на приложенном к книге диске. Там подобное выделение строки реализовано для окна Memol.

5.8.4 Информация о текущем состоянии текста || Оглавление || 5.8.6 Управление видимостью курсора окна редактирования


⇐ Предыдущая страница|

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



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

  • Июнь
    2020
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31