I am trying to change the background color of a text box as follows:

invoke GetDC,
mov ,eax
invoke SetBkColor,,255

Nothing happens.

Please help.
Posted on 2003-04-22 21:51:43 by msmith
You need to catch the WM_CTLCOLOREDIT message and return the correct colour brush from it to colour the textbox background. If you create a brush (ie you don't return a system brush) then you need to also devise a way to destroy that brush otherwise you will end up with a rather large memory leak.

For more info on the WM_CTLCOLOREDIT message, check this url.
Posted on 2003-04-22 22:06:31 by sluggy
Could you provide an actual code snippet to achieve this? I am also interested in changing the color of any control such as button, combo etc.

Posted on 2003-04-23 19:22:04 by msmith
There are alot of examples on the board that deal with this type of thing.

For an example of WM_CTLCOLOREDIT, this will set the text color to blue, the bkgrnd color to dark grey. You must define a solid brush (hEditBrush) with the color 00C0C0C0h (the same as the text background) to have the background painted.

mov eax,wParam
mov hdcEdit,eax ; // handle of display context
mov eax,lParam
mov hwndEdit,eax ; // handle of edit control
invoke SetTextColor,hdcEdit,00FF8000h
invoke SetBkColor,hdcEdit,00C0C0C0h
mov eax,hEditBrush
PS: the WM_CTLCOLOR messages are all handled in this way
Posted on 2003-04-23 19:30:04 by donkey
When does the WM_CTLCOLOREDIT event occur and what causes it?

Where does hEditBrush come from?

Posted on 2003-04-23 20:50:18 by msmith

When does the WM_CTLCOLOREDIT event occur and what causes it?

Where does hEditBrush come from?


As it said above : You must define a solid brush (hEditBrush) with the color 00C0C0C0h (the same as the text background) to have the background painted.

WM_CTLCOLOREDIT is sent each time the control has to be painted, it is windows that sens these messages and you don't have to specify anything in order to enable them, they are always sent. WM_CTLCOLORBTN has to be an owner drawn button, it doesn't say that in the docs but I have never been able to get it working with an ordinary button, but then if I want cool buttons I usually go with owner drawn anyway. I have found that WM_CTLCOLORSTATIC changes the colors of group buttons, check boxes and radio buttons.
Posted on 2003-04-23 21:24:02 by donkey
I appreciate your help and your example. I see that you can set the colors. What I want to do is set the colors after the program has initialized at any time based on a user request or program decision.

I want to do in asm what this VB code snippet does:

Note: cmdBit is an array of buttons

Private Sub FlipBit()
If cmdBit(BitNdx).BackColor = 0 Then
cmdBit(BitNdx).BackColor = 255
TempBool = True
cmdBit(BitNdx).BackColor = 0
TempBool = False
End If
End Sub
Posted on 2003-04-24 20:43:02 by msmith
I don't really understand VB so I won't try to understand it. All you have to do is use variables for the colors and create the brush when you need it. You can put a .IF/.ELSE/.ENDIF block in the message processing and skipover it if you don't need it, say with a flag to determine whether or not to paint it or let Windows paint it. If you let Windows paint it the defaults will be used automatically.
Posted on 2003-04-24 20:48:01 by donkey
Thank you Mr. Donkey for your help. I have it all working except that the text background is always white.

For example, I can make yellow text on a red background ok except that the background immediately behind the text is white. The background where there is no text is red.

Any ideas?

SetTextBkColor is listed in the MFC class ref but not in the api.
Posted on 2003-04-25 21:04:24 by msmith
You're welcome, BTW it's just Donkey, no Mr.

SetBkColor should take care of that for you. :)
Posted on 2003-04-25 21:53:38 by donkey
You are right once again!

I had SetBkColor commented out from a previous experiment.

Now the only question is why the background not behind the text was colored by the brush.
Posted on 2003-04-25 22:04:45 by msmith
Also, I do a SetText to the control in question in order to cause the WM_CTLCOLOREDIT to occur.

Is there a more generic or harmless way to force the WM_CTLCOLOREDIT to occur?

In other words, I am causing this color change to occur when a button is clicked.
Posted on 2003-04-25 22:16:53 by msmith

Donkey has pointed you in the right direction, all you need to do to get colour changes on the fly is to make the values required of global scope in the .DATA or .DATA? section then when your user changes the colour, you code will change those values.

Then you do an "InvalidateRect()" on the control and it should upgrade to the new colour set by your user.


Posted on 2003-04-25 22:52:11 by hutch--

I checked out InvalidateRect on the MSDN library. It requires that I know the rectangle coordinates just as using SetText requires that I know the existing text so as not to destroy it.

I'm looking for a way to cause the repaint without:

1) Storing or getting an existing state
2) Destroying any preexisting attibutes (except the colors)


Posted on 2003-04-25 23:02:56 by msmith
Just use NULL in the place of the rectangle to invalidate the whole control i.e.

invoke InvalidateRect, hwndEdit, NULL, TRUE
Pointer to a RECT structure that contains the client coordinates of the rectangle to be added to the update region. If this parameter is NULL, the entire client area is added to the update region.
InvalidateRect just tells windows that it's time to redraw the control, nothing gets changed unless you explicitly change it
Posted on 2003-04-25 23:10:20 by donkey
Beautiful! It all works now!

Thanks to Donkey and Hutch!
Posted on 2003-04-25 23:17:13 by msmith

You're very welcome, that's why we're here.

Glad you got it working :alright:
Posted on 2003-04-25 23:18:14 by donkey

Where in Missouri are you?
Posted on 2003-04-26 10:05:51 by drhowarddrfine
Near Hermann, Missouri
Posted on 2003-04-26 10:35:19 by msmith
I'm in St. Charles which makes us practically brothers!:alright:
Posted on 2003-04-26 10:37:03 by drhowarddrfine