Discussion:
Transparent Checkbox : How to
(too old to reply)
Roger Garrett
2005-11-16 18:27:53 UTC
Permalink
I have a checkbox on a dialog and I want the background portion of it (i.e.
around the outside of the checkbox and behind the text label) to be
transparent so that the underlying color of the dialog shows through.

I handle the dialog's OnCtlColor method and return a hollow brush.

This works just fine for plane old CButtons as well as for the radio button
type of CButton. But it does not work for the checkbox type of CButton. The
checkbox type buttons come up all black, except for the actual checkbox
itself.

What magic do I have to do in order to get it to work for checkboxes?

Roger Garrett
AliR
2005-11-16 20:38:16 UTC
Permalink
It can't be done like that. What you have to do is draw the entire control
yourself.

AliR.
Post by Roger Garrett
I have a checkbox on a dialog and I want the background portion of it (i.e.
around the outside of the checkbox and behind the text label) to be
transparent so that the underlying color of the dialog shows through.
I handle the dialog's OnCtlColor method and return a hollow brush.
This works just fine for plane old CButtons as well as for the radio button
type of CButton. But it does not work for the checkbox type of CButton. The
checkbox type buttons come up all black, except for the actual checkbox
itself.
What magic do I have to do in order to get it to work for checkboxes?
Roger Garrett
RobKinney1
2005-11-16 22:17:48 UTC
Permalink
Oh, sorry about that. I went back to my app that I was doing this on and I
put a check box in it and it displayed properly... I had made other changes
besides just that class include so it took me a minute to figure out why it
was working properly.

I have the following code:

HBRUSH CMySampleDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{

// We don't want all controls using a null brush (goofs
// up the control's paint logic)...
switch ( nCtlColor )
{
case CTLCOLOR_EDIT:
case CTLCOLOR_LISTBOX:
UpdateData(TRUE); // get check box status

default:
pDC->SetBkMode(TRANSPARENT);

// We'll use a different text color depending upon the
// chosen background

// Use a black text color.
pDC->SetTextColor(RGB(0,0,0)); // black

break;

} // switch

// Return our null brush

return m_brHollow;
}

This is bits and pieces I put together from different tutorials on the web.
Now, if I comment out the line:

// pDC->SetBkMode(TRANSPARENT);

... then my checkbox will have the default windows color instead of showing
through my bitmap properly. Maybe you need to add that line into the
OnCtlColor method...?

Rob K
Rob,
Thanks for offering a solution. The technique described in the article is
the correct approach for achieving transparent controls. And it works for
CStatics and buttons and radio buttons (both of which are variations of
CButton). But it fails to work for checkboxes, which is just another version
of CButton. It's a very odd problem.
- Roger
Roger Garrett
2005-11-16 22:50:51 UTC
Permalink
Rob,

That's almost exactly what my code is doing, but the background of the
checkbox (except for the checkbox itself) is completely black. It's possible
that it's sensitive to what version of Windows it's running on. Mine's
running on Windows XP Home Edition. My application has to run properly on all
versions of Windows.

I'm hoping some actual Microsoft guy will take a look at the issue and
provide a comprehensive answer.

Thank you for taking the time to look into it.

- Roger
Roger Garrett
2005-11-16 22:19:02 UTC
Permalink
Rob,

Thanks for offering a solution. The technique described in the article is
the correct approach for achieving transparent controls. And it works for
CStatics and buttons and radio buttons (both of which are variations of
CButton). But it fails to work for checkboxes, which is just another version
of CButton. It's a very odd problem.

- Roger
RobKinney1
2005-11-16 22:41:29 UTC
Permalink
Don't know if this will work or not for checkboxes, but I used this article
from CodeProject to make all my text transparent to a bitmap background.

http://www.codeproject.com/staticctrl/TransparentStaticCtrl.asp

I included the class in my project:

#include "TransparentStatic2.h" // used for transparent text

... And everything worked perfectly.

Rob K
Post by Roger Garrett
I have a checkbox on a dialog and I want the background portion of it (i.e.
around the outside of the checkbox and behind the text label) to be
transparent so that the underlying color of the dialog shows through.
I handle the dialog's OnCtlColor method and return a hollow brush.
This works just fine for plane old CButtons as well as for the radio button
type of CButton. But it does not work for the checkbox type of CButton. The
checkbox type buttons come up all black, except for the actual checkbox
itself.
What magic do I have to do in order to get it to work for checkboxes?
Roger Garrett
AliR
2005-11-16 23:01:49 UTC
Permalink
My bad on the first message i posted.

Try this:

// TransparentCheckBox.h : implementation file
#pragma once


// CTransparentCheckBox

class CTransparentCheckBox : public CButton
{
DECLARE_DYNAMIC(CTransparentCheckBox)

public:
CTransparentCheckBox();
virtual ~CTransparentCheckBox();

protected:
afx_msg HBRUSH CtlColor(CDC* /*pDC*/, UINT /*nCtlColor*/);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
};



// TransparentCheckBox.cpp : implementation file
//

#include "stdafx.h"
#include "TransparentCheckbox.h"


// CTransparentCheckBox

IMPLEMENT_DYNAMIC(CTransparentCheckBox, CButton)
CTransparentCheckBox::CTransparentCheckBox()
{
}

CTransparentCheckBox::~CTransparentCheckBox()
{
}


BEGIN_MESSAGE_MAP(CTransparentCheckBox, CButton)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()



// CTransparentCheckBox message handlers


HBRUSH CTransparentCheckBox::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(HOLLOW_BRUSH);
}

BOOL CTransparentCheckBox::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}


AliR.
Post by Roger Garrett
I have a checkbox on a dialog and I want the background portion of it (i.e.
around the outside of the checkbox and behind the text label) to be
transparent so that the underlying color of the dialog shows through.
I handle the dialog's OnCtlColor method and return a hollow brush.
This works just fine for plane old CButtons as well as for the radio button
type of CButton. But it does not work for the checkbox type of CButton. The
checkbox type buttons come up all black, except for the actual checkbox
itself.
What magic do I have to do in order to get it to work for checkboxes?
Roger Garrett
Roger Garrett
2005-11-19 00:16:02 UTC
Permalink
Alir,

Thank you for the suggestion. I copied your code and made the
CTransactionCheckBox class and then subclassed one of my checkboxes to use it.
Unfortunately, it doesn't work, at least not under Windows XP Home Edition.
My own code, whihc I had previously tried, was very similar to what you
suggested, except it's the underlying window that handles the OnCtlColor
messages. But both approaches have the exact same symptom, namely that it
doesn't work for checkboxes.

I did some testing and found some interesting symptoms:

First of all we note that buttons, radio buttons, and checkboxes are all
variations of the CButton class. That should reasonably mean that they all
behave the same when setting the bkMode to Transparent and handing back a
HollowBrush via CtlColor or OnCtlColor. But they don't. It works fine for
plain buttons and for radio buttons, but it always results in a black
background for checkboxes. This is particularly odd since a radio button and
a checkbox are practically the same thing. They each have a graphic image
(the button) and a text label. It would make sense that the drawing of them
should be handled by the very same Windows code, but apparently they are not.

I also tried a slight variation to my code (the version that handles the
OnCtlColor message within the underlying Window, as opposed to handling the
reflected message directly within the control). My code basically works for
ANY control on my dialog. As a test I took out the code that sets the bkMode
to transparent. It still fails for the checkbox, butnow it also fails for
simple CStatic controls. So there's something that's not interpreting bkMode
and Hollowbrushes properly.
Again, I only have tested this on Windows XP Home Edition. Maybe it works
properly under other versions of Windows.

Which is pretty frustrarting.

I'm going to see if I can get down into the guts of Windows and see where
it's going wrong within the CButton preocessing of its checkbox variation.

Roger Garrett

Loading...