Transparent Static Text In Dialogs






4.39/5 (24 votes)
Jul 5, 2004
3 min read

197347

7615
A simple way to make static text controls draw transparently over the dialog background.
Introduction
Recently, I was implementing a PropertySheet based wizard, and part of the graphic design was to place a bitmap as the window background and then draw the text and other controls over that. I found a few examples of using a bitmap as a dialog background - the best of which simply involved overriding the default WM_ERASEBKGND
behavior.
That worked fine, but of course, the Static text controls were still being drawn on their beige backgrounds. I found a couple of ideas about drawing transparent text, but they generally involved overriding WM_PAINT
and doing all the text drawing yourself. I was hoping for something simpler.
There are numerous articles about overriding WM_CTLCOLOR
, and they generally discuss using this as a way to change the text color or the background color. I was put off for a long time by the name 'WM_CTLCOLOR
' thinking that it was just about color. However, you can change several characteristics of the drawing environment here just before a control is drawn.
It is possible to call SetBkMode
and set the background mode to TRANSPARENT
which keeps the text drawing routines from erasing before drawing text. This is not quite enough however because when a Static control is drawn, the entire control background is first painted with the HBRUSH
returned by OnCtlColor
. Fortunately, having OnCtlColor
return the NULL_BRUSH
takes care of this as well.
Using the code
This example implements a PropertySheet based wizard. The same techniques would apply to a Dialog.
To change the CStatic
text behavior to transparent drawing requires adding one message handler with four lines of code.
I create a sub-class of CPropertyPage
(for a regular dialog, you would create a sub-class of CDialog
). Then I use ClassWizard to create a handler for WM_CTLCOLOR
. In that handler, OnCtlColor
, I check the nCtlColor
parameter, and if it shows that we are about to draw a Static control (CTLCOLOR_STATIC
) then I call SetBkMode
to change the DC mode to TRANSPARENT
. I also get a handle to the stock NULL_BRUSH
object and return that as the function result. Then Windows takes care of all the text drawing itself.
You can change a number of things about the DC in OnCtlColor
. All of the various CDC functions are available such as SetTextColor
which allows you to change the text color. Of special note is the ability to use CDC::SelectObject
which allows you to change the Pen, Brush, Font, Bitmap and Region. The ability to modify the font here is especially useful in working with PropertySheets because there is no way to set the face, size, or style of the font used (PropertySheets always use MS Shell).
This example also implements using a bitmap for the dialog background. This is done by using ClassWizard to create a handler for WM_ERASEBKGND
in the CPropertyPage
(CDialog
) sub-class. The OnEraseBkgrnd
routine then fills the window with the bitmap instead of painting with the background brush.
History
- 1.0 -15 Jul 2004 - first version.