| 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 | < Назад | Оглавление | Далее > |