print current form using CreateGraphics, but the message box is also printed

446 Views Asked by At

I'm printing my actived form (formMain) using CreateGraphics function as code below

Printing the Form (Visual C#)

Environment: windows 7 professional in classical mode, VisuaStudio 2008

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern long BitBlt (IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
private Bitmap memoryImage;
private void CaptureScreen()
{
   Graphics mygraphics = this.CreateGraphics();
   Size s = this.Size;
   memoryImage = new Bitmap(s.Width, s.Height, mygraphics);
   Graphics memoryGraphics = Graphics.FromImage(memoryImage);
   IntPtr dc1 = mygraphics.GetHdc();
   IntPtr dc2 = memoryGraphics.GetHdc();
   BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);
   mygraphics.ReleaseHdc(dc1);
   memoryGraphics.ReleaseHdc(dc2);
}
private void printDocument1_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
   e.Graphics.DrawImage(memoryImage, 0, 0);
}
private void printButton_Click(System.Object sender, System.EventArgs e)
{
   if (MessageBox.Show("test", "test", MessageBoxButtons.YesNo) == DialogResult.Yes)
   {
        CaptureScreen();
        printDocument1.Print();
   }
}

case1: When MessageBox show by default location, formMain is can printed clearly Clearly

case 2: but, if using mouse to move messageBox out of default location, then the print's result is be dirty. It's now having messageBox (graph) include in mainForm.

Dirty

2

There are 2 best solutions below

3
On

Instead of using the WinAPI directly (BitBlt, ...) try using this:

Bitmap bmp = new Bitmap(this.Width, this.Height);
this.DrawToBitmap(bmp, this.Bounds);
bmp.Save(@"c:\temp\test.png", System.Drawing.Imaging.ImageFormat.Png); // For testing

This should only draw the contents of your form.
I tested this with another top-most form with success.

Place it in your code:

private void CaptureScreen() {
    memoryImage = new Bitmap(this.Width, this.Height);
    this.DrawToBitmap(memoryImage, this.Bounds);
}
0
On

like XP. A counter-measure is to put this.Update();before the CaptureScreen() call.

i think my system is windows 7 , but with classical mode -> as windows xp