News:

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

Can statics be colored?

Started by Mark Jones, February 23, 2005, 02:59:18 PM

Previous topic - Next topic

Mark Jones

Is it possible to change the colors of an IDC_Static? The WIN32.HLP seems to say that the only way to do this is to change the entire system color palette- yikes! I suppose that makes sense though. Is there any other control which is colorable and a little more noob-friendly then? Can Rich-Edit controls be colored? Thanks. :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

doomsday

Lookup: WM_CTLCOLORSTATIC
Also of value will be: SetTextColor, SetBkMode, GetSysColorBrush

If you really get stuck, gimme a yell and I'll get off my bum long enough to write a quickie demo or something.

regards,
-Brent

Mark Jones

 Cool, I am looking into those, thanks Brent. There is not much info about the WM_CTLCOLORSTATIC parameters in the Win32 help however, but I'll search through the MASM folder and see if there are any previous uses. If nothing else, I'll feed it some random dwords and see what happens. Wish me luck!  :U
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Relvinian

For a good explanation of what the WM_CTLCOLORSTATIC does, look at WM_CTLCOLOR. This will give you more help. But use the newer WM_ message (WM_CTLCOLORSTATIC).

Basically, what you need to process this message is have this handler in your Proc for your window.  The WPARAM contains the HDC for the window (which by default you'll want to set the background to be transparant) and the LPARAM is the HWND for your control (or the control receiving the message).  Then make sure you have a HBRUSH already created with the destired background color you want the static control to be and return that HBRUSH (dont create the HBRUSH object on the stack)..

Relvinian

Mark Jones

#4
It seems every time I look I find a newer version of WIN32.HLP. My latest version is 5.1.2600.1106 and wouldn't you believe it, there is no mention of WM_CTLCOLOR. Still, I haven't given up. :) The static gets a black background if I introduce this:


    .elseif uMsg == WM_CTLCOLORSTATIC
        invoke GetWindowLong,lParam,GWL_ID
        .if eax == MyProgram_Static1                  ; handle to static control
;           invoke SetTextColor,myProgram_Static1,Red         ; does nothing
            invoke GetStockObject,BLACK_BRUSH  ; makes static bg black, text is black on white
        .else
            xor eax,eax   ; fallback
        .endif

"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

pbrennick

Mark,
My version of winhelp is a little newer than your, but I found 'Control-Color Messages' to be elucidating.

Paul

petezl

You need to ret.
Try using this as a starting point
.elseif uMsg == WM_CTLCOLORSTATIC
                mov eax,lParam
        .if   eax == hStatic1
                invoke GetStockObject, WHITE_BRUSH
                ret
        .endif

Peter.
Cats and women do as they please
Dogs and men should realise it.

Mark Jones

 Elucidating... now there's a word you don't see every day. :) You're right Paul, there is a section entitled "Control-Color Messages." I must be doing something wrong then, I can only get the background color to change. The Win32.hlp seems to say that wm_ctlcolorstatic is only for changing the static background color. How can we then change the static's text  colors then? SetTextColor and SetBkColor seem to do nothing:


    .elseif uMsg == WM_CTLCOLORSTATIC
;        mov eax,lParam                             ; does not work
        invoke GetWindowLong,lParam,GWL_ID       
        .if eax == MyProgram_Static1
            invoke SetTextColor,MyProgram_Static1,Red   ; nothing
            invoke SetBkColor,MyProgram_Static1,Blue    ; nothing
            invoke GetStockObject,BLACK_BRUSH ; makes background black but text is black-on-white
            ret     
        .endif


I've tried putting the text colorings into WM_PAINT and WM_CTLCOLORBTN constructs with similar results... so my implementation must be askew as usual! :red
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

petezl

Mark, Are you SubClassing the Static in an attempt to change the color or are you using that for some other reason?
The lParam holds the static handle which you can trap to change any specific Static control color. If you don't use that then all the statics will be affected.
btw. The WM_CTLCOLORBTN message was discontinued according to MSDN, It won't cause a fault, it just don't work.
There are several ways to attack this, here are a couple of examples:
mov eax,lParam
.IF eax == hStatic1
invoke SetBkMode, wParam, TRANSPARENT
invoke SetTextColor, wParam, 0000ffffh ; choose a color
mov eax, WhatEver-ColorBrush
.ELSE
xor eax,eax
.ENDIF
ret
.endif
ret

or:
.ELSEIF uMsg == WM_CTLCOLORSTATIC
mov eax,wParam
mov hdc,eax
invoke SetTextColor,hdc,0
invoke SetBkColor,hdc,StaticBkgrColor
mov eax,hStaticBkgrBrush
ret

Obviously they need the appropriate brushes where necessary.
If you are still stuck, say what colour text and background you want and I'll put an example together.
Peter.
Cats and women do as they please
Dogs and men should realise it.

Mark Jones

Thanks Pete, it is working and I think I understand wParam now. lParam is not being passed correctly, so I have to use GetWindowLong. There is a lot to learn with assembler, especially when not having any previous C++ experience. Here's a working snippet showing more code, it makes white text on a black static. Maybe I should go into woodworking, eh? Thanks for everyone's help.


.const
test001_main    equ  1001
test001_static  equ  1002

.data
hInstance       db  0

.code
start:
    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke InitCommonControls
    invoke DialogBoxParam,hInstance,test001_main,0,offset DlgProc,0
    invoke ExitProcess,eax

DlgProc proc hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM

    .if uMsg == WM_CREATE   ; for some reason this is never parsed?
        invoke MessageBox, hWnd, 0, 0, MB_OK

    .elseif uMsg == WM_CTLCOLORSTATIC
        invoke GetWindowLong,lParam,GWL_ID       
        .if eax == test001_static
            invoke SetTextColor,wParam,00F0F0F0h    ; 00BBGGRR
            invoke SetBkMode,wParam,TRANSPARENT
            invoke GetStockObject,BLACK_BRUSH
            ret
        .endif
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

petezl

Glad to see your making progress Mark. Not that long ago, I was in the same boat. I still stumble on things regularly. A stubborn attitude and persistence to make it succeed usually works for me. Regarding your code post. There is no need for GetWindowLong or even SetWindowLong and the ret I previously mentioned only applies to  window code.
From what you have posted it's clear that you are using a dialog so when you retrieve the lParam, it contains the Static handle (which according to your code does'nt exist. You need to obtain this first in WM_INITDIALOG like:
invoke GetDilogItem, hDlg, test001_static
mov hStat1, eax

As you can see, the code is subtly different between a window and dialog.
I'll post two identical versions later. One for a window and another for a dialog just so you can see the difference.
Peter
Cats and women do as they please
Dogs and men should realise it.

petezl

Hi Mark, this should be self explanitory. Window and a Dialog code.
Peter.

[attachment deleted by admin]
Cats and women do as they please
Dogs and men should realise it.

Mark Jones

Thanks Pete, those examples are great! :U
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08