How would you colour a control, for example colour the background of a button control to Black and the text of the button control to white...

HWND hButton = CreateWindowEx(0,"BUTTON","&Send",WS_VISIBLE | WS_CHILD,230,100,70,20,hwnd,(HMENU)cmdBUTTON,0,0);

if ( hButton == NULL )
{
  MessageBox(hwnd,"Error: button could not be created","Error",0);
}

/*Change the colour of the created button here..*/

I've tried looking into API's like SetTextColor() and SetBkColor() but I can't get anything working as such.

Thanks.

Recommended Answers

All 11 Replies

for controls other than buttons, you could handle the WM_CTLCOLORXXX notification; eg. WM_CTLCOLOREDIT for an edit control.
for buttons, the button needs to be an owner-drawn button; for such a button the system sends the parent window a WM_DRAWITEM message.
see: http://msdn2.microsoft.com/en-us/library/ms673346.aspx

Thanks, that seemed to work except that for example the edit control background was set to the correct colour BUT the text in the edit control had a different background colour. for example a text box had a white line where there is any text in it and the rest was the correct color..

also, can you specify which controls you wish to colour etc using those messages and by using..

case WM_CTLCOLOREDIT:
{
   switch(LOWORD(wParam))
   { 
       case CONTROLNAME:
       {

       }
       break;
       default:
       break;
}
break;

Thanks.

BUT the text in the edit control had a different background colour.

The wparam of the message is a handle to the device context; you can use SetTextColor, SetBkMode, SetTextAlign etc. ion it.

The wparam of the message is a handle to the device context; you can use SetTextColor, SetBkMode, SetTextAlign etc. ion it.

Yes but how would one set each of these on one specific control?
like..

case WM_CTLCOLOREDIT:
        {
             switch (LOWORD(wParam))
             {
                    case (txtMessage):
                    {
                         SetTextColor((HDC)wParam,(COLORREF)CreateSolidBrush(RGB(255,255,255)));
                         SetBkColor((HDC)wParam,(COLORREF)CreateSolidBrush(RGB(0,0,0)));
                    }
             }
        }
or maybe could i do this..

        case WM_CTLCOLOREDIT:
        {
             HDC hDC = getDC(txtMessage);
                         
             SetTextColor(hDC,(COLORREF)CreateSolidBrush(RGB(255,255,255)));
             SetBkColor(hDC,(COLORREF)CreateSolidBrush(RGB(0,0,0)));
        }

Thanks.

Yes but how would one set each of these on one specific control?

for the WM_CTLCLREDIT message,
wparam - handle to the device context for the edit control window (HDC)
lparam - handle to the edit control (HWND)
if you want to make the decision based on the HWND, this is all that is required; if you want to do the same based on control id:

// ...
case WM_CTLCOLOREDIT:
{  
   HDC dc = HDC(wparam) ;
   HWND edit_window = HWND(lparam) ;
   int edit_control_id = GetDlgCtrlID(edit_window) ;     
   switch(edit_control_id)
  {
     // ...
case WM_CTLCOLOREDIT:
        {
             HWND hControl    =  (HWND) lParam;
             HDC  hDC         =  (HDC) wParam;
             int  iControl    =  GetDlgCtrlID(hControl);
             int  itxtMessage =  GetDlgCtrlID(txtMessage);
             
             if ( iControl == itxtMessage )
             {
                   SetBkMode((HDC)wParam,OPAQUE);
                   SetTextColor((HDC)wParam,(COLORREF)RGB(255,255,255));                         
                   SetBkColor((HDC)wParam,(COLORREF)RGB(0,0,0));
             }

        }

This is the code I have up to now.. I couldnt get the switch case to work like that but the above seems to work fine.. this is the output..

http://img159.imageshack.us/img159/5295/79814659hr4.png

Changing the opaque keyword to transparent I get the following output..

http://img257.imageshack.us/img257/8644/22815276qx2.png

- I need the full background of the test control to be black and the text of the edit control to be white, how could I do this?

Thanks for all your help.

...I need the full background of the test control to be black and the text of the edit control to be white, how could I do this?

what are are you returning? you need to return a handle to the brush with which the control background would be painted. eg. for a black background:
return LRESULT( GetStockObject( BLACK_BRUSH ) ) ;

Thanks, that seems to work fine except one problem when i write some text "test" and then press the backspace key.. the caret moves back as it should but the last character is still displayed for example if i wrote "test" and then pressed backspace, the box would display "test" but in fact only contain "tes".

Is there any way to stop this from happening?

Thanks.

Also.. are there any message handlers for special controls such as WC_IPADDRESS or RICHEDIT etc

you could write a handler for the EN_UPDATE notification sent by the edit control and force a repaint by InvalidateRect/UpdateWindow.
rich edit controls do not send CTLCOLOR messages; however you can set its background colour by sending it a EM_SETBKGNDCOLOR message.

i've not used WC_IPADDRESS (i've not written any gui code for several years now), but i think it is just an edit control with special formatting/validation. so my guess is that you should be able to treat it like an edit control.

Thanks for all of your help..

Do you have any kind of online references you could point me to for this kind of thing.. I still can't find a way to colour the IP address control.

And could you tell me why the NMIPADDRESS structure and the IPN_FIELDCHANGED arent being recognised?

switch (HIWORD(wParam))
                    {
                           case IPN_FIELDCHANGED:
                           {
                                NMIPADDRESS sIPAddress;
                                sIPAddress = (NMIPADDRESS) lParam;
                                if (sIPAddress.iValue > 255 || sIPAddress.iValue < 0 )
                                {
                                   sIPAddress.iValue = 1;
                                   return sIPAddress;                      
                                }
                           }
                           break;
                           default: break;
                    }

normally the best online reference is msdn. the ip address control reference is at http://msdn2.microsoft.com/en-us/library/ms671454.aspx
i looked around msdn a bit; but did not see any info on custom colouring this control.
by spying on the ip address control window, it turns out that it has four child windows (each of them an edit control). i suppose that was to be expected. so we could colour the edit controls using the normal WM_CTLCOLOREDIT mechanism. you would need to subclass the ip address control. and in the subclassed window procedure, handle the WM_CTLCOLOREDIT yourself. pass everything else for default handling ( by a return CallWindowProc(....) )
see http://msdn2.microsoft.com/en-us/library/ms633569.aspx#instance_subclassing
on how to subclass a window instance

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.