墨迹缩放示例
此示例程序演示如何缩放和滚动墨迹。 具体而言,它允许用户以增量放大和缩小墨迹。 它还演示如何使用缩放矩形放大特定区域。 最后,此示例演示如何以不同的缩放比例收集墨迹,以及如何在缩放的绘图区域内设置滚动。
在此示例中, Renderer 对象的视图和对象转换用于执行缩放和滚动。 视图转换适用于点和笔宽度。 对象转换仅适用于点。 用户可以通过更改“模式”菜单上的“缩放笔宽度”项来控制使用哪个转换。
注意
(InkRenderer.SetViewTransform 和 InkRenderer.SetObjectTransform 的某些接口方法执行某些 COM 调用是有问题的,例如,在发送消息时) 。 当消息已发送时,需要将其封送至 POST 消息队列。 若要解决此情况,请通过调用 InSendMesssageEx 来测试是否正在处理来自 POST 的消息,如果消息已发送,则向自己 POST 发送消息。
此示例使用以下功能:
- InkCollector 对象
- Renderer 对象的 SetViewTransform 方法
- Renderer 对象的 SetObjectTransform 方法
初始化窗体
首先,此示例引用了 Windows Vista 或 Windows XP Tablet PC Edition 软件开发工具包 (SDK) 中提供的平板电脑自动化接口。
using Microsoft.Ink;
此示例声明 了 InkCollector 和 myInkCollector
一些专用成员,以帮助进行缩放。
// 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;
然后,该示例在窗体的 Load 事件处理程序中创建并启用 InkCollector。 此外,还设置了 InkCollector 对象的 DefaultDrawingAttributes 属性的 Width 属性。 最后,定义滚动条范围并调用应用程序的 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
,转换矩阵用于缩放和平移窗口中的墨迹收集器。
注意
Renderer 对象的 SetViewTransform 方法将转换应用于笔划和笔宽,而 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 中正确使用当前窗口大小、缩放设置和滚动位置。 此方法计算垂直滚动条和水平滚动条的大变化和小变化值。 它还计算滚动条的当前值以及它们是否应可见。
Renderer 对象的 PixelToInkSpace 方法处理从像素到缩放坐标空间的转换,并考虑通过视图和对象转换应用的任何缩放和滚动。
// 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
事件处理程序管理将矩形绘制到窗口。 如果在“模式”菜单上选中“缩放到 Rect”命令,则 MouseUp 事件处理程序将调用应用程序的 ZoomToRectangle
方法。 方法 ZoomToRectangle
计算矩形的宽度和高度,检查边界条件,更新滚动条值和比例系数,然后调用应用程序的 UpdateZoomAndScroll
方法来应用新设置。
关闭窗体
窗体的 Dispose 方法释放 InkCollector 对象。