В предыдущем разделе рассмотрены способы выделения последовательностей символов в текстах окон Rich Edit. Ниже рассмотрен пример, обеспечивающий выделение в тексте окна RichEdit слова, над которым перемещается курсор мыши. Выделение происходит, если при перемещении курсора мыши нажата клавиша Alt. Вы можете посмотреть этот пример в проекте PMessRichEdit в каталоге RichEdit на приложенном к книге диске (окна RichEditl и RichEdit2). Окно этого проекта во время выполнения представлено на рис. 5.15.

Рис 5.15

Примеры выделения элементов текста

5.8.3.2 Выделение слова под курсором мыши

В примере, помимо рассмотренного в предыдущем разделе сообщения EM_FIND-WORDBREAK, используются еще одно сообщение любых окон редактирования - EM_CHARFROMPOS, вид которого в приложениях VCL Win32:

EM_CHARFROMPOS, 0, Longint(@Point а в приложениях VCL .NET:

EM_CHARFROMPOS, 0, Point

Сообщение возвращает номер позиции символа, ближайшего к указанным координатам (lParam типа TPoint) окна редактирования. В младших разрядах возвращается номер позиции символа, а в старших - номер строки. В качестве координат могут использоваться, например, координаты курсора мыши, передаваемые в обработчик события OnMouseDown.

Рассмотрим этот пример. Выделение слова в нем упрощено по сравнению с предыдущим разделом. Считается, что ничего страшного не будет, если границы слова будут определены не совсем точно.

Для выделения в тексте слова, над которым перемещается курсор мыши, в приложении VCL Win32 достаточно написать следующий обработчик события OnMouseMove окна RichEdit:

uses RichEdit;
procedure TForml.RichEditlMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
var p:TPoint;

ind, indbeg, 1: longint; begin

// уход, если не нажата клавиша Alt if not(ssAlt in Shift) then exit;
// определяется индекс символа ind, // ближайшего к координатам курсора X и Y р := Point(х,у);
ind := RichEditl.Perform(EM__CHARFROMPOS,0,Longint(@p));

// анализ символов в данной и предыдущей позициях if (RichEditl.Perform(EM_FINDWORDBREAK, WB_CLASSIFY, ind) or RichEditl.Perform(EM_FINDWORDBREAK,WB_CLASSIFY,ind-1)) and (WBF_BREAKLINE or WBF_ISWHITE) <> 0 then begin

// один из символов пробельный RichEditl.SelLength := 0;
exit;
end;

// индекс начала слова

indbeg := RichEditl.Perform(EM_FINDWORDBREAK, WB_MOVEWORDLEFT, ind); // длина слова

1 := RichEditl.Perform(EM_FINDWORDBREAK, WB_RIGHTBREAK, ind) - indbeg; // если слово прежнее, выход

if (indbeg = RichEditl.SelStart) and (1 = RichEditl.SelLength) then exit; // выделение слова

RichEditl.SelStart := indbeg;
RichEditl.SelLength := 1;
end;

В приложении VCL .NET текст должен быть несколько изменен. Во-первых, должен быть изменен оператор, задающий значение ind:

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

Кроме того, для распознавания функции Point, создающей структуру р, должна быть добавлена ссылка на модуль Types, в котором функция объявлена:

uses RichEdit, Types;

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


|Следующая страница ⇒

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



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

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