이 샘플 프로그램은 잉크를 확대/축소하고 스크롤하는 방법을 보여 줍니다. 특히 사용자가 잉크를 증분 단위로 확대 및 축소할 수 있습니다. 또한 확대/축소 사각형을 사용하여 특정 영역을 확대/축소하는 방법도 보여 줍니다. 마지막으로 이 샘플에서는 다양한 확대/축소 비율로 잉크를 수집하는 방법과 확대/축소된 드로잉 영역 내에서 스크롤을 설정하는 방법을 보여 줍니다.
샘플에서 렌더러 개체의 뷰 및 개체 변환은 확대/축소 및 스크롤을 수행하는 데 사용됩니다. 보기 변환은 포인트 및 펜 너비에 적용됩니다. 개체 변환은 점에만 적용됩니다. 사용자는 모드 메뉴에서 펜 너비 배율 항목을 변경하여 사용되는 변환을 제어할 수 있습니다.
메모
메시지가 전송되었을 때 특정 인터페이스 메서드(예: InkRenderer.SetViewTransform및 InkRenderer.SetObjectTransform)에서 일부 COM 호출을 수행하는 것은 문제가 있습니다. 메시지가 SENT이면 POST 메시지 큐에 마샬링되어야 합니다. 이 시나리오를 해결하려면 InSendMessageEx 호출하여 POST에서 메시지를 처리하는지 테스트하고 메시지가 전송된 경우 자신에게 메시지를 게시합니다.
이 샘플에서는 다음 기능이 사용됩니다.
- InkCollector 개체
- Renderer 개체의 SetViewTransform 메서드
- 렌더러의 객체에 대한 SetObjectTransform 메서드
양식 초기화
먼저 샘플은 Windows Vista 또는 Windows XP Tablet PC Edition SDK(소프트웨어 개발 키트)에서 제공되는 태블릿 PC 자동화 인터페이스를 참조합니다.
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 패널 이벤트 처리기는 창에 사각형 그리기를 관리합니다. [모드] 메뉴에서 [사각형으로 확대/축소] 명령이 활성화되어 있으면, MouseUp 이벤트 처리기가 애플리케이션의 ZoomToRectangle 메서드를 호출합니다.
ZoomToRectangle 메서드는 사각형의 너비와 높이를 계산하고 경계 조건을 확인하고 스크롤 막대 값과 배율 인수를 업데이트한 다음 애플리케이션의 UpdateZoomAndScroll 메서드를 호출하여 새 설정을 적용합니다.
양식 닫기
폼의 Dispose 메서드는 InkCollector 개체를 삭제합니다.