News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Checkbox control background color

Started by NoCforMe, October 30, 2011, 10:35:48 PM

Previous topic - Next topic

NoCforMe

Help! I'm trying to do something reeeeeeally simple:



(code + .exe attached below)

All I want is for the background of the checkbox to be the same as the client area of my main window. (Right now it's my custom color, but could be some other color, or even just white.)

No, I don't want to use the "default gray" for the background (would solve my problem, but I want to be able to pick my color).

How can I do this? I've tried a few things and failed:

  • Registering the class for the control: results in an invisible control (but oddly, the CreateWindowEx() call doesn't fail). I tried both using the system class name ("button") and my own made-up name; neither works.
  • Creating a window proc for the control (it's in the source file but is inactive). I tried capturing the WM_ERASEBKGND message and doing some background painting, but also didn't work.
Do I need to make this an owner-draw control? Is there some simple way to accomplish this? And I'm always open to the possibility that I've made a Really Stupid n00b Mistake, even though I've been over this rather simple code a dozen times. (You know how they say that you shouldn't try to proofread your own writing ...)

Any help appreciated. If I might make a request, could y'all please refrain from going off on tangents concerning coding styles, neato-keeno ways of doing this with 5 lines of incomprehensible code, etc., etc., until after I get an answer to my question? 'K?

Gunner

You will have to handle the WM_CTLCOLORBTN and change it there.

QuoteThe WM_CTLCOLORBTN message is sent to the parent window of a button before drawing the button. The parent window can change the button's text and background colors. However, only owner-drawn buttons respond to the parent window processing this message.

~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

NoCforMe

Thanks. (To those who want to follow along, this is the link to the MSDN page on WM_CTLCOLORBTN.)

So I get that I need to make the control owner-draw (with the SS_OWNERDRAW style). But general ? about owner-draw stuff: does this mean that I now have the responsibility for every aspect of drawing the control? Or can I pick and choose what I want to alter? say, just set the background brush and let the other stuff be handled by the default proc? In that case, do I just pass everything I don't handle on to DefWindowProc()?

And how do I actually change the background color: select a new brush handle into the DC? physically paint the background (client rect of the control)? something else?

Hmm, further reading reveals:

QuoteIf an application processes this message, it must return a handle to a brush. The system uses the brush to paint the background of the button.

So do I just do this?


INVOKE CreateSolidBrush, $BkColor
RET ;Return w/handle to brush


OK, I tried that, and here's the result:


jj2007

1. make brush a global variable
2. change as follows
JE dowincmd
CMP EAX, WM_CTLCOLORSTATIC
jne @F
invoke SetBkMode, wParam, TRANSPARENT
mov eax, brush
ret
@@: CMP EAX, WM_CREATE

NoCforMe

Thanks, but that gives me an invisible control. (Might come in handy for my next project for the CIA ...)

Are you sure that's the correct message to handle? Here's what MSDN sayeth on the suject:

Quote
A static control, or an edit control that is read-only or disabled, sends the WM_CTLCOLORSTATIC message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the static control.

Here's what I did, following your suggestion (this is in the parent's window proc):


CMP EAX, WM_CTLCOLORSTATIC
JE do_colorcheckbox

...

do_colorcheckbox:
INVOKE SetBkMode, wParam, TRANSPARENT
INVOKE CreateSolidBrush, $BkColor
; MOV EAX, brush
RET ;Return w/handle to brush

Gunner

You first have to create your brush then save the handle returned to brush.. then mov brush into eax and return it in response to WM_CTLCOLORBTN why did you change to WM_CTLCOLORSTATIC?  that is for edit and static controls not sure if you will even get that message for a button
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

jj2007

Quote from: NoCforMe on October 30, 2011, 11:25:46 PM
Thanks, but that gives me an invisible control.

Interesting. My version works fine on Win XP SP3.
By the way, it's a bad idea to create a new brush every time you get that message. That is why I suggested a global variable.

NoCforMe

Quote from: Gunner on October 30, 2011, 11:32:08 PM
You first have to create your brush then save the handle returned to brush.. then mov brush into eax and return it in response to WM_CTLCOLORBTN

But if I do this:


INVOKE CreateSolidBrush, $BkColor
RET ;Return w/handle to brush


then the handle to the brush (which is returned by CreateSolidBrush() ) is already in EAX; why do I need to save it? It's not being used anywhere else.

Quotewhy did you change to WM_CTLCOLORSTATIC?

Because jj told me to?

Quotethat is for edit and static controls not sure if you will even get that message for a button

Well, that's what I thought to after posting what MSDN says about it. I changed it back to WM_CTLCOLORBTN, but it still didn't work.

NoCforMe

This is starting to bug me.

As soon as I create the control as owner-draw (by adding SS_OWNERDRAW to the window styles), I get a "blank" control (as shown above, just a gray bar). If I leave off that style, the control renders OK, though in the default color.

Doesn't matter what I do in the parent window proc in response to WM_CTLCOLORBTN:

Return FALSE:


XOR EAX, EAX
RET


do the default thang:


INVOKE DefWindowProc, hWin, uMsg, wParam, lParam
RET


or process the message as I tried to do above.

I'm hoping this is just a simple mistake or misunderstanding on my part somewhere ...

dedndave

there are a number of examples for owner-drawn controls in the attachment
also, i think one of the masm32\examples programs has an owner-drawn button - very similar to a checkbox

http://www.4shared.com/file/m1BJWoRF/XXControls.html

NoCforMe

Quote from: jj2007 on October 30, 2011, 11:38:32 PM
Quote from: NoCforMe on October 30, 2011, 11:25:46 PM
Thanks, but that gives me an invisible control.

Interesting. My version works fine on Win XP SP3.

W2K SP4 here. Version differences?

QuoteBy the way, it's a bad idea to create a new brush every time you get that message. That is why I suggested a global variable.

Point taken. I'll definitely do that in the release version!

dedndave

i can see why that one gives you a hard time   :P
logically, it should be WM_CTLCOLORBTN

but, no, it's WM_CTLCOLORSTATIC   :bg
http://support.microsoft.com/kb/130952



go figure   ::)

NoCforMe

Thanks! That dood the trick.

Looks like jj was right after all. Thank goodness for the KB, eh?

dedndave

it makes no sense at all - lol

surprising that Jochen is having related problems, huh
he's pretty sharp   :U

i tried it earlier, but did not do both SetBkColor and return a brush handle
seems like SetBkColor, alone, should do the job

NoCforMe

Quoteseems like SetBkColor, alone, should do the job

But the documentation says you're supposed to return a background brush, no?

(But then, can we trust what they say?)