State information is lost when you draw Ink to an image by using the Renderer object (829824)



The information in this article applies to:

  • Microsoft Windows XP Tablet PC Edition Software Development Kit (SDK) 1.5
  • Microsoft Windows XP Tablet PC Edition Software Development Kit (SDK) 1.0
  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1
  • Microsoft Visual Studio .NET (2003), Professional Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Professional Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition

SYMPTOMS

When you try to render Ink to an image by using the Renderer object, the drawing attributes such as AntiAlias, Transparency, and Color are not respected on a Tablet PC that is running Microsoft Windows XP Tablet PC Software Development Kit (SDK).

CAUSE

There is a known issue in GDI/GDI+ mixed mode when an application passes a Graphics object to the Renderer.Draw method, only the HDC property of the Graphics object is then passed to the underlying drawing method for drawing. The HDC property that is passed out of the Graphics object is devoid of all other information. For example, the HDC property does not have information about the clipping region and transformation that is set on the Graphics object. Therefore, the problem occurs.

WORKAROUND

To work around this problem, use the BitBlt function to copy the image data directly.

The Win32 BitBlt function performs a bit-block transfer of the color data that corresponds to a rectangle of pixels from the specified source device context into a destination device context. Call this function in managed code through Platform Invocation technology. For example, paste the following code in the ip_Stroke method:
Graphics g1 = Graphics.FromImage(pb1.Image);
Graphics g2 = pb2.CreateGraphics();
Graphics gip= ip.CreateGraphics();
IntPtr srcDC = gip.GetHdc();
IntPtr dstDC = g1.GetHdc();
try
{
	BitBlt(dstDC.ToInt32(), 0, 0, ip.Width, ip.Height,srcDC.ToInt32(), 0, 0, 0xcc0020);
}
finally
{
	gip.ReleaseHdc(srcDC);
	g1.ReleaseHdc(dstDC);
}
ip.Renderer.Draw(g2,ip.Ink.Strokes);
pb1.Invalidate();		
ip.Invalidate();
To call the BitBlt function in managed code, import the function first. To do this, use the DllImport attribute as follows:
 [DllImport("gdi32")]
 public static extern bool BitBlt(int hDC, int x, int y, int nWidth, int nHeight, int hSrcDC, int xSrc, int ySrc, int dwRop);

MORE INFORMATION

Steps to reproduce the problem

  1. Create a Microsoft Visual C# .NET Windows application in Microsoft Visual Studio .NET.
  2. Add a reference to the Microsoft.Ink.dll file and to the Microsoft.Ink.15.dll file.

    Note The Microsoft.Ink.15.dll file is included with Tablet PC Platform SDK 1.5.
  3. Replace the code in Form1 with the following code:
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.Ink;
    public class Form1 : System.Windows.Forms.Form
    {
    	InkPicture ip;
    	PictureBox pb1, pb2;
    	public Form1()
    	{
    		Size = new System.Drawing.Size(300,600);
    		ip = new InkPicture();
    		ip.Location = new Point(0, 0);
    		ip.Size = new Size(300, ClientRectangle.Height/3);
    		ip.BorderStyle = BorderStyle.FixedSingle;
    		ip.DefaultDrawingAttributes.Width = 100;
    		ip.DefaultDrawingAttributes.AntiAliased = true;
    		ip.DefaultDrawingAttributes.Color = Color.Red;
    		ip.DefaultDrawingAttributes.Transparency = 200;
    		ip.Stroke += new InkCollectorStrokeEventHandler(ip_Stroke);
    		pb1 = new PictureBox();
    		pb1.Location = new Point(0, ClientRectangle.Height/3);
    		pb1.Size = new Size(300, ClientRectangle.Height/3);
    		pb1.BorderStyle = BorderStyle.FixedSingle;
    		pb1.Image = new Bitmap(pb1.Width, pb1.Height);
    		pb2 = new PictureBox();
    		pb2.Location = new Point(0, 2*ClientRectangle.Height/3);
    		pb2.Size = new Size(300, ClientRectangle.Height/3);
    		pb2.BorderStyle = BorderStyle.FixedSingle;
    		Controls.AddRange(new Control[]{ip, pb1, pb2});
    	}
    	private void ip_Stroke(object s, InkCollectorStrokeEventArgs e)
    	{
    		Bitmap b = new Bitmap(ip.Width, ip.Height);
    		Graphics g1 = Graphics.FromImage(pb1.Image);
    		Graphics g2 = pb2.CreateGraphics();
    		ip.Renderer.Draw(g1,ip.Ink.Strokes);
    		ip.Renderer.Draw(g2,ip.Ink.Strokes);
    		pb1.Invalidate();
    		ip.Invalidate();
    	}
    	[STAThread]
    	static void Main() 
    	{
    		Application.Run(new Form1());
    	}
    }
  4. Press F5 to run the application.
When you draw in the InkPicture control, the Ink is not correctly drawn in the second control. The second control is a PictureBox control that displays an image. The third control is another PictureBox control that shows that the Ink appears correct when it is rendered directly to the Graphics object of a control.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.

Modification Type:MajorLast Reviewed:11/29/2004
Keywords:kbgraphic kbGDI kbtshoot kbprb KB829824 kbAudDeveloper kbAudITPRO