head.WriteLine()

Mittwoch, April 05, 2006

DrawToBitmap()

Manchmal benötigt man das grafische Abbild eines Controls, um es beispielsweise auszudrucken. In .NET 1.x musste man hierfür tief in die Trickkiste greifen und die gute alte API-Funktion BitBlt bemühen. Die folgende Hilfsfunktion zeigt die bekannte Vorgehensweise:

[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, System.Int32 dwRop);

private Image GetControlImage(System.Windows.Forms.Control ctl)
{
    const Int32 SRCCOPY = 0xCC0020;
    
    Graphics gc1 = ctl.CreateGraphics();
    Image tmpImage = new Bitmap(
        ctl.ClientRectangle.Width,
        ctl.ClientRectangle.Height, gc1);
    Graphics gc2 = Graphics.FromImage(tmpImage);
    
    IntPtr dc1 = gc1.GetHdc();
    IntPtr dc2 = gc2.GetHdc();
    
    BitBlt(
        dc2,
        0, 0,
        ctl.ClientRectangle.Width, ctl.ClientRectangle.Height,
        dc1,
        0, 0,
        SRCCOPY);
    
    gc1.ReleaseHdc(dc1);
    gc2.ReleaseHdc(dc2);
    gc1.Dispose();
    gc2.Dispose();
    
    return tmpImage;
}

In .NET 2.0 ist die Ermittlung der Oberfläche erheblich leichter geworden. Die Control-Klasse bietet hierfür die DrawToBitmap()-Methode an, der ein leeres Bitmap-Objekt, sowie eine Rectangle-Struktur übergeben wird.

Das Ermitteln einer Button-Oberfläche könnte nun beispielsweise so erfolgen:

Bitmap bmp = new Bitmap(this.button1.Width, this.button1.Height);
this.button1.DrawToBitmap(bmp, this.button1.ClientRectangle);
this.pictureBox1.Image = bmp;

Wieder so eine Kleinigkeit, die das Leben leichter macht :-)