Exemplo de Zoom à Tinta
Este programa de exemplo demonstra como aplicar zoom e rolar tinta. Em particular, ele permite que o usuário amplie e reduza a tinta em incrementos. Ele também demonstra como ampliar uma região específica usando um retângulo de zoom. Por fim, este exemplo ilustra como coletar tinta em diferentes taxas de zoom e como configurar a rolagem dentro da área de desenho ampliada.
No exemplo, a exibição do objeto Renderizador e as transformações de objeto são usadas para executar zoom e rolagem. A transformação de exibição se aplica aos pontos e à largura da caneta. A transformação de objeto aplica-se somente aos pontos. O usuário pode controlar qual transformação é usada alterando o item Largura da Caneta de Escala no menu Modo.
Observação
É problemático executar algumas chamadas COM em determinados métodos de interface (InkRenderer.SetViewTransform e InkRenderer.SetObjectTransform, por exemplo) quando uma mensagem é ENVIADA. Quando as mensagens são ENVIADAs, elas precisam ser enviadas para a fila de mensagens POST. Para resolver esse cenário, teste se você está tratando uma mensagem do POST chamando InSendMesssageEx e POSTE a mensagem para si mesmo se a mensagem foi ENVIADA.
Os seguintes recursos são usados neste exemplo:
- O objeto InkCollector
- O método SetViewTransform do objeto Renderer
- Método SetObjectTransform do objeto Renderer
Inicializando o formulário
Primeiro, o exemplo faz referência às interfaces de Automação do Tablet PC, que são fornecidas no Windows Vista ou no SDK (Software Development Kit) do Windows XP Tablet PC Edition.
using Microsoft.Ink;
O exemplo declara um InkCollector, myInkCollector
e alguns membros privados para ajudar no dimensionamento.
// 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;
Em seguida, o exemplo cria e habilita o InkCollector no manipulador de eventos Load do formulário. Além disso, a propriedade Width da propriedade DefaultDrawingAttributes do objeto InkCollector está definida. Por fim, os intervalos de barras de rolagem são definidos e o método do UpdateZoomAndScroll
aplicativo é chamado.
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();
}
Atualizando os valores de zoom e rolagem
A área de desenho do coletor de tinta é afetada por muitos eventos.
UpdateZoomAndScroll
No método , uma matriz de transformação é usada para dimensionar e traduzir o coletor de tinta dentro da janela.
Observação
O método SetViewTransform do objeto Renderer aplica a transformação aos traços e à largura da caneta, enquanto o método SetObjectTransform aplica apenas a transformação aos traços.
Por fim, o método do UpdateScrollBars
aplicativo é chamado e o formulário é forçado a atualizar.
// 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();
Gerenciando as barras de rolagem
O UpdateScrollBars
método configura as barras de rolagem para funcionar corretamente com o tamanho da janela atual, a configuração de zoom e o local de rolagem dentro do InkCollector. Esse método calcula a alteração grande e os valores de alteração pequenos para as barras de rolagem vertical e horizontal. Ele também calcula o valor atual das barras de rolagem e se elas devem estar visíveis. O método PixelToInkSpace do objeto Renderer manipula a conversão de pixels para o espaço de coordenadas ampliado e contabiliza qualquer escala e rolagem que é aplicada por meio da exibição e das transformações de objeto.
// 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;
}
Aplicar zoom a um retângulo
Os pnlDrawingArea
manipuladores de eventos do painel gerenciam o desenho do retângulo para a janela. Se o comando Zoom To Rect estiver marcado no menu Modo, o manipulador de eventos MouseUp chamará o método do ZoomToRectangle
aplicativo. O ZoomToRectangle
método calcula a largura e a altura do retângulo, verifica se há condições de limite, atualiza os valores da barra de rolagem e o fator de escala e chama o método do UpdateZoomAndScroll
aplicativo para aplicar as novas configurações.
Fechando o formulário
O método Dispose do formulário descarta o objeto InkCollector .