Is there any way to change a solid brush color other than to do a 'DeleteObject' followed by a 'CreateSolidBrush' with a new color?
Posted on 2003-07-06 21:36:25 by msmith
SelectObject ?
Posted on 2003-07-06 22:45:31 by JimmyClif
here's a related(somewhat question) I'm using comrade's tutorial on Dlgcolor, how do I change the color of the buttons on it?
Posted on 2003-07-07 00:03:41 by EEDOK

I have never succesfully managed to use WM_CTLCOLORBTN on a normal button. It works well on owner drawn buttons but seems to be just about useless for all other types of buttons. The WM_CTLCOLORSTATIC message is used for groupboxes and other special buttons but the push button doesn't seem to react to anything except subclassing and processing WM_PAINT.

I dsicussed this with msmith here:


Why would you want to change a brush without DeleteObject, it seems like a make work project (I doubt it can be done) :)

invoke DeleteObject,hBrush
invoke CreateSolidBrush,0FF0000h
mov hBrush,eax
Posted on 2003-07-07 00:08:29 by donkey
Hi Donkey,

Your code snippet is exactly what I'm doing. I just thought that there would be a way changing an existing brush color.

Posted on 2003-07-07 01:01:40 by msmith
I have never run into a way to do that. I really don't think it can be done because a brush is a created GDI object and although it has a handle I don't think that it processes messages so there is no way to communicate with it. Without that functionality there is no way to change any aspect of the object. You're pretty much stuck with the direct approach.
Posted on 2003-07-07 01:16:31 by donkey
I tried to play around with coloring standard buttons because I've seen alot of questions about this. It seems that the standard push button has a few strange properties. First the button in the pressed state does not send a WM_PAINT message to the subclassing procedure or at least I didn't get one. Second you have to take care of the 3D borders yourself, that's a bit difficult. At any rate this is how far I got till I gave up (for now), if anybody wants to take over, I put the brush color in the USERDATA of the button structure.the button text is kept in a buffer called BtnText:
ButtonSubClass PROC uses ebx esi edi hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM


.IF uMsg == WM_PAINT
invoke GetWindowLong,hWin,GWL_USERDATA
push eax
invoke CreateSolidBrush,eax
mov hBtnBrush,eax
invoke BeginPaint,hWin,addr ps
mov hdc,eax
invoke SelectObject,hdc,hBtnBrush
invoke GetClientRect,hWin,addr rect
sub rect.right,3
sub rect.bottom,3
invoke CreateRectRgn, 1, 1, rect.right, rect.bottom
mov hRgn,eax
invoke PaintRgn, hdc, hRgn
invoke GetClientRect,hWin,addr rect
invoke GetTextExtentPoint32,hdc,ADDR BtnText,edx,ADDR rect.right
pop eax
invoke SetBkColor,hdc,eax
mov rect.left,10
invoke DrawText, hdc, ADDR BtnText, -1, ADDR rect, DT_SINGLELINE
invoke DeleteObject,hRgn
invoke EndPaint,hWin,addr ps
invoke DeleteObject,hBtnBrush

invoke CallWindowProc,OldBtnProc,hWin,uMsg,wParam,lParam

ButtonSubClass endp
Personally I think that the best way to go about this is to use bitmapped buttons and draw the text onto the bitmap. This is the subclassing setup:

BtnColor dd 0009EBF7h
BtnText db "Test",0
invoke GetDlgItem,hDlg,1001 ;[b]used a dialog with a button id 1001[/b]
mov hBtn,eax
invoke SetWindowLong,hBtn,GWL_USERDATA,BtnColor
invoke SetWindowLong,hBtn,GWL_WNDPROC,OFFSET ButtonSubClass
mov OldBtnProc,eax
Posted on 2003-07-07 02:40:57 by donkey