OnPaint over controls

  • Thread starter Thread starter Dan Baker
  • Start date Start date
D

Dan Baker

I have a form with several controls. I would like to paint *over* several
controls (mainly GroupBoxes and Labels). But, Everywhere I try to perform
painting, I end up "behind" the controls. I need a device context for the
entire form, that I can render to *after* all the controls have been
painted.

Suggestions?
Thanks
DanB
 
You can get a Graphics object for each of the controls seperately by calling CreateGraphics() on each of them.
You can hide the controls by calling Hide() and just paint normally.

Unfortunately, I don't think there is a way to obtain a device context that will draw over a child control, however, there is a
class style that can be used to set the control's device context to that of the parent's. Form and Control do not set this flag so
you'd have to implement your own container using NativeWindow. Probably not worth the effort.

Maybe, you can try to prevent the controls from refreshing by overriding the WndProc method and preventing any paint messages from
being sent to the child controls. I'm not sure if this can be done, but it might not help since Windows will probably "remember"
the last bitmap used for each control and overwrite your form's context anyway.

If simply hiding the controls isn't good enough (if you need to do alpha blending or overwrite non-client area, etc. and keep the
controls visible) then I would suggest you create "smart" implementations of the controls on the form so that they can render as
appropriate for their clipping region.

GL
 
This is completely erroneous and will cause nothing but pain.

You must NEVER paint on a control after obtaining it's Graphics object using
CreateGraphics. See the GDI+ FAQ #1 most asked question for details.

You can use interop to obtain the desktop window and draw directly on that.
This will enable pixels to be forced onto any control but can cause a few
problems for clean refreshes.

The best method is to use a seperate layered window control with per-pixel
alpha to create a semi-transparent window that sits on top of all others on
the form.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
Your solution sounds good. I'm trying to animate over the controls (like a
bouncing arrow, pointing into a list of items). All controls are static, and
don't have any user-interaction, so the refresh shouldn't be a problem.
I've done this before in MFC without problems.

I would like to perform the animation in a timer routine. Is there any way
of getting a Graphics object in the timer routine that will allow me to
paint on this semi-transparent window you are describing?

DanB
 
I think Bob's suggesting that you create an overlaid window, that's transparent, and covers your entire form area.

You'd have to hook-up the events so that any changes to the underlying Form's location/bounds is reflected on the overlaying window.

If you use an overlaying Form you can use Windows API calls (or the CreateGraphics() method that Bob doesn't like) to obtain the
device context and draw at any time (including in a timer routine), or you can create a custom window implementation by deriving
from NativeWindow. Using the latter solution forces you to write most of the code using Interop.

Here's the reference I use for GDI coding:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_8x45.asp

GL
 
Back
Top