Win32 WM_CTLCOLORSTATIC background not completely filled

Viewed 106

I am working on a dialog box that is created and controlled by a host program. The host creates the window and then sends me all the messages, but this means I don't have full access to everything it's doing. (I mention this because it could be contributing to my issue.)

I would like to change the color of an LTEXT to red. I am handling the WM_CTLCOLORSTATIC message and it is working where the text is drawn. The problem I'm having is that the rectangle for the LTEXT is slightly wider than the length of the text. For the part of the control that does not contain text it is leaving the background white instead of COLOR_BTNFACE as I have specified.

Here is the code for my handler. I call it by way of HANDLE_WM_CTLCOLORSTATIC.

// color message handler
HBRUSH OnControlColor ( HWND hDlg, twobyte dlgItem, HDC hdcCtrl, int type ) override
{
    if ( (dlgItem == ID_MANUAL_EDIT_WARNING) && (type == CTLCOLOR_STATIC) )
    {
        SetTextColor(hdcCtrl, RGB(204, 0, 0));
        SetBkColor(hdcCtrl, GetSysColor(COLOR_BTNFACE));
        return (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
    }
    return NO;
}

It seems like maybe I need to invalidate the entire client rect some way, but I am not sure how to do this. Obviously I could carefully make the rectangle the exact right size in the dialog designer, but this doesn't seem like the safest approach.

1 Answers

What you could do is to explicitly select your desired background brush into the control's device context; thus, when its rectangle is drawn, that brush will be used. You can do it with one additional line of code in your handler:

HBRUSH OnControlColor ( HWND hDlg, twobyte dlgItem, HDC hdcCtrl, int type ) override
{
    if ( (dlgItem == ID_MANUAL_EDIT_WARNING) && (type == CTLCOLOR_STATIC) )
    {
        SetTextColor(hdcCtrl, RGB(204, 0, 0));
        SetBkColor(hdcCtrl, GetSysColor(COLOR_BTNFACE));
        SelectObject(hdcCtrl, GetSysColorBrush(COLOR_BTNFACE)); // Select the B/G brush
        return (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
    }
    return NO;
}

My one concern here is that you're manipulating object selection in a device context that is 'owned' by another process; this could cause issues if the replaced object in that DC is user-created (but that doesn't seem to be so in this case).

Related