Поделиться через


Пример масштаба рукописного ввода

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

В примере представление объекта Renderer и преобразования объектов используются для масштабирования и прокрутки. Преобразование представления применяется к точкам и ширине пера. Преобразование объекта применяется только к точкам. Пользователь может управлять используемым преобразованием, изменяя элемент Ширина пера масштабирования в меню Режим.

Примечание

Выполнение некоторых com-вызовов с определенными методами интерфейса (например, InkRenderer.SetViewTransform и InkRenderer.SetObjectTransform) проблематично, если сообщение отправлено. Если сообщения отправлены, их необходимо маршалировать в очередь сообщений POST. Чтобы решить этот сценарий, проверьте, обрабатываете ли вы сообщение из POST, вызвав InSendMesssageEx и POST сообщение себе, если сообщение было отправлено.

 

В этом примере используются следующие функции:

Инициализация формы

Во-первых, пример ссылается на интерфейсы автоматизации планшетного компьютера, которые предоставляются в пакете sdk для Windows Vista или Windows XP Tablet PC Edition.

using Microsoft.Ink;

В примере объявляется InkCollectormyInkCollector и некоторые частные члены, которые помогают с масштабированием.

// Declare the Ink Collector object
private InkCollector myInkCollector = null;
...
// The starting and ending points of the zoom rectangle
private Rectangle zoomRectangle = Rectangle.Empty;

// The current zoom factor (1 = 100% zoom level)
private float zoomFactor = 1;

// Declare constants for the width and height of the 
// drawing area (in ink space coordinates).
private const int InkSpaceWidth = 50000;
private const int InkSpaceHeight = 50000;
...
// Declare constant for the pen width used by this application
private const float MediumInkWidth = 100;

Затем пример создает и включает InkCollector в обработчике событий Load формы. Кроме того, задано свойство Width объекта InkCollector DefaultDrawingAttributes . Наконец, определяются диапазоны полосы прокрутки и вызывается метод приложения UpdateZoomAndScroll .

private void InkZoom_Load(object sender, System.EventArgs e)
{
   // Create the pen used to draw the zoom rectangle
    blackPen = new Pen(Color.Black, 1);

    // Create the ink collector and associate it with the form
    myInkCollector = new InkCollector(pnlDrawingArea.Handle);

    // Set the pen width
    myInkCollector.DefaultDrawingAttributes.Width = MediumInkWidth;

    // Enable ink collection
    myInkCollector.Enabled = true;

    // Define ink space size - note that the scroll bars
    // map directly to ink space
    hScrollBar.Minimum = 0;
    hScrollBar.Maximum = InkSpaceWidth;
    vScrollBar.Minimum = 0;
    vScrollBar.Maximum = InkSpaceHeight;

    // Set the scroll bars to map to the current zoom level
    UpdateZoomAndScroll();
}

Обновление значений масштаба и прокрутки

На область рисования сборщика рукописного ввода влияет множество событий. В методе UpdateZoomAndScroll матрица преобразования используется для масштабирования и преобразования сборщика рукописного ввода в окне.

Примечание

Метод SetViewTransform объекта Renderer применяет преобразование как к штрихам, так и к ширине пера, а метод SetObjectTransform применяет преобразование только к штрихам.

 

Наконец, вызывается метод приложения UpdateScrollBars и форма принудительно обновляется.

// Create a transformation matrix
Matrix m = new Matrix();

// Apply the current scale factor
m.Scale(zoomFactor,zoomFactor);

// Apply the current translation factor - note that since 
// the scroll bars map directly to ink space, their values
// can be used directly.
m.Translate(-hScrollBar.Value, -vScrollBar.Value);

// ...
if (miScalePenWidth.Checked)
{
    myInkCollector.Renderer.SetViewTransform(m);
}
else
{
    myInkCollector.Renderer.SetObjectTransform(m);
}

// Set the scroll bars to map to the current zoom level
UpdateScrollBars();

Refresh();

Управление полосами прокрутки

Метод UpdateScrollBars настраивает полосы прокрутки для правильной работы с текущим размером окна, параметрами масштабирования и расположением прокрутки в InkCollector. Этот метод вычисляет значения больших и малых изменений для вертикальных и горизонтальных полос прокрутки. Он также вычисляет текущее значение полос прокрутки и должны ли они быть видимыми. Метод PixelToInkSpace объекта Renderer обрабатывает преобразование пикселей в увеличенное координатное пространство и учитывает любое масштабирование и прокрутку, применяемые через преобразования представления и объекта.

// Create a point representing the top left of the drawing area (in pixels)
Point ptUpperLeft = new Point(0, 0);

// Create a point representing the size of a small change
Point ptSmallChange = new Point(SmallChangeSize, SmallChangeSize);

// Create a point representing the lower right of the drawing area (in pixels)
Point ptLowerRight = new Point(hScrollBar.Width, vScrollBar.Height);

using (Graphics g = CreateGraphics())
{
    // Convert each of the points to ink space
    myInkCollector.Renderer.PixelToInkSpace(g, ref ptUpperLeft);
    myInkCollector.Renderer.PixelToInkSpace(g, ref ptLowerRight);
    myInkCollector.Renderer.PixelToInkSpace(g, ref ptSmallChange);
}

// Set the SmallChange values (in ink space)
// Note that it is necessary to subract the upper-left point
// value to account for scrolling.
hScrollBar.SmallChange = ptSmallChange.X - ptUpperLeft.X;
vScrollBar.SmallChange = ptSmallChange.Y - ptUpperLeft.Y;

// Set the LargeChange values to the drawing area width (in ink space)
// Note that it is necessary to subract the upper-left point
// value to account for scrolling.
hScrollBar.LargeChange = ptLowerRight.X - ptUpperLeft.X;
vScrollBar.LargeChange = ptLowerRight.Y - ptUpperLeft.Y;

// If the scroll bars are not needed, hide them
hScrollBar.Visible = hScrollBar.LargeChange < hScrollBar.Maximum;
vScrollBar.Visible = vScrollBar.LargeChange < vScrollBar.Maximum;

// If the horizontal scroll bar value would run off of the drawing area, 
// adjust it
if(hScrollBar.Visible && (hScrollBar.Value + hScrollBar.LargeChange > hScrollBar.Maximum)) 
{
    hScrollBar.Value = hScrollBar.Maximum - hScrollBar.LargeChange;
}

// If the vertical scroll bar value would run off of the drawing area, 
// adjust it
if(vScrollBar.Visible && (vScrollBar.Value + vScrollBar.LargeChange > vScrollBar.Maximum))
{
    vScrollBar.Value = vScrollBar.Maximum - vScrollBar.LargeChange;
}

Масштабирование до прямоугольника

Обработчики pnlDrawingArea событий панели управляют рисованием прямоугольника в окно. Если в меню Режим установлен флажок Увеличить до прямоугольника, обработчик событий MouseUp вызывает метод приложения ZoomToRectangle . Метод ZoomToRectangle вычисляет ширину и высоту прямоугольника, проверяет условия границ, обновляет значения полосы прокрутки и коэффициент масштабирования, а затем вызывает метод приложения UpdateZoomAndScroll для применения новых параметров.

Закрытие формы

Метод Dispose формы удаляет объект InkCollector .