Printing a Panel

  • Thread starter Thread starter Adam Sandler
  • Start date Start date
A

Adam Sandler

Hello,

I took a look at http://msdn.microsoft.com/en-us/library/aa287531(VS.71).aspx
which gives a code sample on how to print a form. To print a panel, I
just substituted 'p' for 'this':

private void CaptureScreen(Panel p)
{
Graphics myGraphics = p.CreateGraphics();
Size s = p.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, p.ClientRectangle.Width,
p.ClientRectangle.Height, dc1, 0, 0, 13369376);
myGraphics.ReleaseHdc(dc1);
memoryGraphics.ReleaseHdc(dc2);
}

private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(memoryImage, 0, 0);
}

Unfortunately, the output is sketchy... the capture even gets portions
of the screen which is not part of the application... for example, I
see the start menu button and taskbar in the print.

Is this the only way to print my panel? Basically, the panel I'm
trying to print just contains other, smaller, panels aligned in a grid
format. Each of the smaller panel just has a label inside.

Suggestions are greatly appreciated.

Thanks!
 
Hello Adam,

Did you try to use the CopyFromScreen method instead GetHdc and IntPtrs...
You might have more luck that way...

eg.
[..]
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(regionSize.Width, regionSize.Height,
PixelFormat.Format32bppArgb);

// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);

// Take the screenshot from the upper left corner to the right
bottom corner
gfxScreenshot.CopyFromScreen(offsetX, offsetY, 0, 0, regionSize,
CopyPixelOperation.SourceCopy);
[..]

I use this code to do something very similar to what you want to do. And it
works.

Best of luck to you.

Leo
 
Hello Adam,

Did you try to use the CopyFromScreen method instead GetHdc and IntPtrs...
You might have more luck that way...

eg.
[..]
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(regionSize.Width, regionSize.Height,
PixelFormat.Format32bppArgb);

// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);

// Take the screenshot from the upper left corner to the right
bottom corner
gfxScreenshot.CopyFromScreen(offsetX, offsetY, 0, 0, regionSize,
CopyPixelOperation.SourceCopy);
[..]

I use this code to do something very similar to what you want to do. And it
works.

Excellent... this works. Thank-you very much for the assistance.

I do have one question though when event is fired, the capture gets
the menuitem, from where the click occurs, in the image. Is there a
way to delay calling the capture function until the menuitem goes
away?

Thanks!
 
I'm glad it worked.

You could try something like:
Application.DoEvents();
System.Threading.Thread.Sleep(1000); //or less than a
second...

(But of course, that is a bit of a bodge... :-) )

Optionally, you might try to bring the panel to front or hide the menu item
before taking the screenshot...

Good luck to you. Let me know how you solve this one.

Regards,

Leo

Adam Sandler said:
Hello Adam,

Did you try to use the CopyFromScreen method instead GetHdc and
IntPtrs...
You might have more luck that way...

eg.
[..]
// Set the bitmap object to the size of the screen
bmpScreenshot = new Bitmap(regionSize.Width,
regionSize.Height,
PixelFormat.Format32bppArgb);

// Create a graphics object from the bitmap
gfxScreenshot = Graphics.FromImage(bmpScreenshot);

// Take the screenshot from the upper left corner to the
right
bottom corner
gfxScreenshot.CopyFromScreen(offsetX, offsetY, 0, 0,
regionSize,
CopyPixelOperation.SourceCopy);
[..]

I use this code to do something very similar to what you want to do. And
it
works.

Excellent... this works. Thank-you very much for the assistance.

I do have one question though when event is fired, the capture gets
the menuitem, from where the click occurs, in the image. Is there a
way to delay calling the capture function until the menuitem goes
away?

Thanks!
 
I'm glad it worked.

You could try something like:
Application.DoEvents();
System.Threading.Thread.Sleep(1000); //or less than a
second...

(But of course, that is a bit of a bodge... :-) )

Optionally, you might try to bring the panel to front or hide the menu item
before taking the screenshot...

Good luck to you. Let me know how you solve this one.

Leo, still haven't solved this one yet... perhaps I'll spend more time
on it this weekend. Thanks for the advice thus far!
 
Back
Top