netlib.narod.ru | < Назад | Оглавление | Далее > |
Как замечено выше, одна из сложных задач включает определение позиции курсора в тексте, набранном пропорциональным шрифтом. В целом для решения этой задачи нужно несколько раз вызвать метод MeasureString, чтобы изучить текст, по которому щелкнул мышью пользователь (точнее, выяснить расстояние между символами этого текста).
В программе TypeAway из главы 6 я показал, как дублировать вводимые с клавиатуры символы в виде строки текста на экране. В ней была каретка, которую пользователь мог перемещать при помощи стрелок. Давайте добавим к TypeAway интерфейс, который бы позволил с помощью мыши устанавливать позицию каретки на основе значения свойства X объекта MouseEventArgs, передаваемого как аргумент метода OnMouseDown. (В случае обработки нескольких строк пришлось бы задействовать в программе и свойство Y, чтобы определить строку текста, которую указал пользователь.)
HitTestText.cs
//-------------------------------------------- // HitTestText.cs (C) 2001 by Charles Petzold //-------------------------------------------- using System; using System.Drawing; using System.Windows.Forms; class HitTestText: TypeAway { public new static void Main() { Application.Run(new HitTestText()); } public HitTestText() { Text += " with Hit-Testing"; Cursor = Cursors.IBeam; } protected override void OnMouseDown(MouseEventArgs mea) { if (strText.Length == 0) return; Graphics grfx = CreateGraphics(); float xPrev = 0; int i; for (i = 0; i < strText.Length; i++) { SizeF sizef = grfx.MeasureString(strText.Substring(0, i + 1), Font, Point.Empty, StringFormat.GenericTypographic); if (Math.Abs(mea.X - xPrev) < Math.Abs(mea.X - sizef.Width)) break; xPrev = sizef.Width; } iInsert = i; grfx.Dispose(); PositionCaret(); } }
Обратите внимание, что конструктор устанавливает свойство Cursor формы как Cursors.IBeam, чтобы сделать программу похожей на настоящий текстовый редактор.
Метод OnMouseDown включает цикл for, параметром которого является количество символов в строке текста. При сравнении используется вызов Math.Abs (вычисление модуля числа), который определяет расстояние между символами, ближайшими к курсору мыши по горизонтали. После этого метод заносит в поле iInsert новый индекс символа и вызывает PositionCaret, чтобы преобразовать этот новый индекс в новую позицию каретки, выраженную в пикселах.
К сожалению, как и исходная версия TypeAway, эта программа не может корректно работать с текстом, который читается (и пишется) справа налево.
netlib.narod.ru | < Назад | Оглавление | Далее > |