I know that there has been a lot of posts concerning the subject. But what I want to know is how to set the text color of, say, a static without changing the background color.
Posted on 2003-07-09 20:17:08 by msmith
Can't say that I know an easy way to do this. You would probably need a way that can be reusable and that's a little tough to do. It is ofcourse easy if you know the background color in advance, You can just delete and recreate a brush in the WM_CTLCOLORSTATIC message and return that. Since I believe that the brush is not permanently selected into the DC when it is drawn a call to invoke GetCurrentObject,hDC,OBJ_BRUSH will probably just yeild a useless brush (COLOR_WINDOW or something). I would try this:
.ELSEIF uMsg == WM_CTLCOLORSTATIC

mov eax,wParam
mov hDC,eax
invoke SetTextColor,hDC,00FF8000h
invoke SetBkMode,hDC,TRANSPARENT
invoke GetStockObject,NULL_BRUSH
ret
NOTE: I have not tested this !
Posted on 2003-07-09 20:52:12 by donkey
My last attempt before making the post was:




wmcolorstatic:
mov eax,[wparam]
mov [dcedit],eax
mov eax,[lparam]
mov [hwndedit],eax
cmp [lbl],eax
je lblchk
jmp defwndproc

lblchk:
invoke DeleteObject,[hBrush]
invoke GetBkColor,[dcedit]
invoke SetBkColor,[dcedit],eax
invoke CreateSolidBrush,eax
mov [hBrush],eax
invoke SetTextColor,[dcedit],$ff
mov eax,[hBrush]
jmp finish



I was trying to get the existing backcolor (was standard WIndows gray), and repaint it. This code gives me a white background.
Posted on 2003-07-09 21:06:42 by msmith
Oh, just the standard Gray brush:
.ELSEIF uMsg == WM_CTLCOLORSTATIC

mov eax,wParam
mov hDC,eax
invoke SetTextColor,hDC,00FF8000h
invoke SetBkMode,hDC,TRANSPARENT
invoke GetStockObject,LTGRAY_BRUSH
ret
Posted on 2003-07-09 21:10:47 by donkey
I may be missing your point, but the gray background was just an example. I was trying to "read" the current back color and reset it when giving the new text color.

Either I am missing the point of the 'GetBkColor' function, or it is not very useful.
Posted on 2003-07-09 21:16:28 by msmith
Now I understand, I'll try to play around with it tonight and see what can be done, I'll post some "tested" code if I find something.
Posted on 2003-07-09 21:19:27 by donkey
Likewise, and thanks!
Posted on 2003-07-09 21:24:22 by msmith
At a quick glance I have come to the following conclusions;

1. When WM_CTLCOLORSTATIC is sent there is a background brush in the DC
2. That brush is the standard window background color (White)
3. GetBkColor will return only white because at the time it is called that is the bk color
4. To get the actual color of the control you hve to examine a pixel:
.ELSEIF uMsg == WM_CTLCOLORSTATIC

mov eax,wParam
mov hDC,eax
invoke DeleteObject,hLBrush
invoke GetPixel,hDC,0,0
invoke CreateSolidBrush,eax
mov hLBrush,eax
invoke SetTextColor,hDC,00FF8000h
invoke SetBkMode,hDC,TRANSPARENT
mov eax,hLBrush
ret
5. This method works with CheckBtns, RadioBtns, GroupBoxes and Statics, it can't be used for Trackbars or ReadOnly edit controls
6. More work to be done :)
Posted on 2003-07-09 21:44:56 by donkey
Hi Donkey,,

I'm getting pretty tired. I may still try it tonight, otherwise tomorrow.

Last night, I noticed (quite by accident) that trackbar's back color responds in the WM_CTLCOLORSTATIC event.

Thanks
Posted on 2003-07-09 21:53:32 by msmith
Donkey,

I have it all working now.

Thanks!
Posted on 2003-07-09 23:42:05 by msmith
No probs msmith,

I put in a request for a demo of your package, hopefully I'll be accepted :alright:
Posted on 2003-07-09 23:58:43 by donkey
Donkey,

I will send you the key tomorrow.

That demo is for the old product (not having to do with the stuff we have been working on together). It is a c++ output compiler coupled to the FOX GUI package.

I can get you a copy of the BETA version if you wish. It outputs assembler but is not finished.
Posted on 2003-07-10 00:42:12 by msmith
I would rather have the assembler version if possible, the c++ stuff isn't as interesting to me.
Posted on 2003-07-10 01:07:59 by donkey
Assuming that no other processes have fiddled with the static control, I think it's safe to assume that its colors are retrievable via GetSysColor(), or GetSysColorBrush() since those are the defaults.

[size=12]invoke GetSysColor, COLOR_BTNFACE

invoke SetBkColor, hdc, eax[/size]


Edit: You might also want to monitor the WM_SYSCOLORCHANGE message too.
Posted on 2003-07-10 01:15:24 by iblis
Donkey,

This code works for labels and checkboxes, but not radio buttons or edit. list box works partly but in an unusable way. If I uncomment the edit, I get a system error. If I disable the button part, the checkbox still colors ok. The slider (trackbar colors ok, but if you move the slider it goes back to gray.

If I minimize the window and then restore it, everything loses it's color (except the slider).

Code not shown here sets the background color and turns on bit 3 of a dword in a structure. It also sets the fore (text) color and turns on bit 4. If both are set, I only get 1 color event so you can see that the bit 3 routine has to also check for bit 4.



proc !WindowProc,OBMain,wmsg,wparam,lparam
enter
push ebx esi edi
cmp [wmsg],WM_CREATE
je !wmcreate
cmp [wmsg],WM_CTLCOLORSTATIC
je !wmctlcolorstatic
;cmp [wmsg],WM_CTLCOLOREDIT
;je !wmctlcolorstatic
cmp [wmsg],WM_CTLCOLORBTN
je !wmctlcolorstatic
cmp [wmsg],WM_CTLCOLORSCROLLBAR
je !wmctlcolorstatic
cmp [wmsg],WM_CTLCOLORLISTBOX
je !wmctlcolorstatic
cmp [wmsg],WM_COMMAND
je !wmcommand
cmp [wmsg],WM_DESTROY
je !wmdestroy

!defwndproc:
invoke DefWindowProc,[OBMain],[wmsg],[wparam],[lparam]
jmp !finish

!wmcreate:
invoke CreateSolidBrush,0
mov [!Brush],eax
call OBMain_Load
jmp !finish

!wmctlcolorstatic:
mov eax,[wparam]
mov [!dc],eax
mov eax,[lparam]
invoke GetWindowLong,eax,GWL_USERDATA
mov esi,eax
add esi,12
btr dword [esi],3
jc !backcolorstatic
btr dword [esi],4
jc !forecolorstatic
jmp !defwndproc

!backcolorstatic:
btr dword [esi],4
jc !colorstatic
add esi,20
mov eax,[esi]
mov [!BackColor],eax
invoke DeleteObject,[!Brush]
invoke CreateSolidBrush,[!BackColor]
mov [!Brush],eax
invoke SetBkColor,[!dc],[!BackColor]
mov eax,[!Brush]
jmp !finish

!colorstatic:
add esi,20
mov eax,[esi]
mov [!BackColor],eax
add esi,4
mov eax,[esi]
mov [!ForeColor],eax
invoke DeleteObject,[!Brush]
invoke CreateSolidBrush,[!BackColor]
mov [!Brush],eax
invoke SetBkColor,[!dc],[!BackColor]
invoke SetTextColor,[!dc],[!ForeColor]
mov eax,[!Brush]
jmp !finish

!forecolorstatic:
add esi,24
mov eax,[esi]
mov [!ForeColor],eax
invoke DeleteObject,[!Brush]
invoke GetPixel,[!dc],0,0
invoke CreateSolidBrush,eax
mov [!Brush],eax
invoke SetTextColor,[!dc],[!ForeColor]
invoke SetBkMode,[!dc],TRANSPARENT
mov eax,[!Brush]
jmp !finish

!wmcommand:
call OBMain_Command
jmp !finish

!wmdestroy:
invoke DeleteObject,[!Brush]
invoke PostQuitMessage,0
xor eax,eax

!finish:
pop edi esi ebx
return

Posted on 2003-07-12 15:36:58 by msmith
Maybe these old posts will give you some more ideas to solve your problem:

http://www.asmcommunity.net/board/index.php?topic=1447

http://www.asmcommunity.net/board/index.php?topic=1012
Posted on 2003-07-12 16:29:28 by LuHa
LuHa,

Thank for the tip. I'll check it out.

In my previous code, I changed the 3 btr instructions to bt so that when the color request is processed, it does not kill the request.

The result is that the minimize/restore sequence repaints all the colors. Also, when I move the slider, it repaints also. Progress!

Now I just need to know how to paint the radio buttons and find out why processing edit color blows up.
Posted on 2003-07-12 16:38:07 by msmith