Printing long form in C# 2005

  • Thread starter Thread starter RickSean
  • Start date Start date
R

RickSean

I have a long form within a panel which exceeds the maximum height of 876. I
use the following code to print the form but it prints only the portion of
the form that is displayed on the screen (max sized to 876). How do I print
the entire form?

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);
 
Thanks for you detailed answer.


Peter Duniho said:
The short answer is "you don't".

You undoubtedly could shoe-horn the form into printing the entire thing.
One approach would be to repeatedly move the form so incremental portions
are visible, building the entire page up one screen-full at a time.
Another might be to send the WM_PRINT message to the form window handle
and hope that everything in the form handles that message properly (not
guaranteed).

But basically, printing forms is just not well supported. Using an
on-screen user-interface just isn't a great way to create printed pages.
This is one reason that it's not well-supported, and at the same time it's
a bit of a self-fulfilling prophecy, since the fact that it's not
well-supported also means it's not a great way to create printed pages. :)

But really, it's true that the on-screen representation of a
user-interface is really just not a great way to display things on a
printed page. There are too many significant differences between an
interactive display and a static, printed page.

A common strategy for applications that have a lot of custom
user-interface stuff that they also want to be able to print is to create
a shared rendering engine that can handle both. Typically the engine
would include some special-case things to deal with the differences
between the too, but otherwise would emit rendered data to an arbitrary
Graphics instance. When displaying on-screen, this would be the Graphics
instance for the Paint event, and when printing this would be the instance
for the PrintPage event.

And of course, you could have printing code that doesn't interact at all
with the on-screen UI. This would be reasonably common for applications
that have a very simple presentation on-screen and printed (just plain
text, for example), and as well for applications that print the data in a
very specific way that's not closely related to the on-screen display (a
database report using some specific criteria set in the UI, for example).

By the way, using BitBlt probably doesn't make much sense. At the very
least, you should probably change your code so that it uses either
Graphics.CopyFromScreen() or, even better, Control.DrawToBitmap(). Either
will still have some limitations, and which will likely cause issues. But
at least you won't have to be going writing p/invoked stuff in your own
code. :)

Pete
 
Back
Top