Justin
Wed May 12 01:03:27 CDT 2004
> I can appreciate the ability to have those features such as alpha blending or
> adding custom graphics. It is great to have those things but what about the
> basic task of printing a Windows Form?
Intrinsically this is not a basic task as I've outlined later. In actuality you
are wanting
to screen scrape a form, and that is done via BitBlt, which doesn't nearly have
the
limitations you appear to think it has.
> I have managed to get the printing working for TextBoxes, RadioButtons,
Buttons, RichTextBoxes,
> Labels, CheckBoxes, etc. but what an arduous task! You have to code for all
of the different
> appearance attributes - example: text alignment, background images, image
alignment, etc...
> So yes, you have to reverse engineer OnPaint. You have to attempt to draw
> the form exactly as OnPaint draws it.
In most cases the ControlPaint just has an arduous number of overloads that you
pass
all of your parameters into. Also, drawing it exactly as OnPaint does is often
not what
you want for a printed graphic.
> On the subject of BitBlt - you can load an image into a graphics context but
you cannot
> save a graphics context to an image. Technically this should be a trivial
matter.
> I suspect that the reason why you cannot save is due rather to a business
motive.
This is not true. You can easily grab the hDC for GDI+ bitmaps and use that
with calls to
BitBlt that Blt from the screen to a GDI+ surface. This is a trival matter as
you point out
and is quite easy to do. It gets even easier in Whidbey where they have special
methods
that copy from the screen to a GDI+ surface for you.
> Imagine if Microsoft would provide this simple function - it would then be
trivial.
> All you would have to do is do a form refresh and save the graphics context to
an image
> buffer and then print the image buffer. You could even preprocess the image
buffer,
> e.g. cropping, rotating, 2D effects, etc...
If only it were that easy. Were you aware that Windows Forms is actually a
wrapper for Win32 in
some cases, but not others? In many cases Win32 is rendering directly to the
GDI surface and the
GDI+ Graphics object isn't even being used. Take this as a test. Create a
brand new form,
construct a PaintEventArgs with a Graphics that points to a Bitmap you could
save out. Then call
OnPaint with your new PaintEventArgs. See the result? It should be blank. The
reason is that
all of the actual form rendering logic is happening at the Win32 layer and ends
up on the screen,
not anywhere near your GDI+ surface. If you enable certain things like sizing
grips and what not,
you'll actually see those end up on the screen. Reasoning for that? Well, that
is being rendered
by WinForms and not the Win32 layer. They simply can't easily write the
software you are talking
about on the current platform. Wait for Longhorn.
> My point ***exactly***. When OnPaint() draws the ListBox does it not draw it
correctly with
> only the 3 visible items shown? So instead of be given the API hook to tell
the ListBox
> to draw itself correctly onto the graphics context, we have to write code to
> mimic the behaviour of OnPaint.
My point is that this is not the correct behavior at all. When you are
printing, 3 items doesn't have
meaning, since you don't know what the other 30 items are. In most cases, when
printing, you
want a number of special considerations to take place. For instance, to print a
Tab Control as
you suggest, what you actually want to see on a printed document is all of the
tab areas printed
one after the other as separate pages or flowed graphics starting with the first
to the last displaying
the Tab text as a header of some sort.
I think the concept of printing a form as it appears on screen is irrational at
best. A single scrolling
region completely destroys its potential use.
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog:
http://weblogs.asp.net/justin_rogers