Static Control Background Color with C++

Static Control Background Color with C++

For static text controls there's no permanent way to set the text color or their background. Even if you want to apply the changes to a single static control; you would still have to handle WM_CTLCOLORSTATIC notification message in parent dlgproc just when the control is about to be drawn.

This is due to the DefWindowProc overwriting your changes to the device context each time it handles WM_CTLCOLORSTATIC as stated in the MSDN:

By default, the DefWindowProc function selects the default system colors for the static control.

static HBRUSH hBrush = CreateSolidBrush(RGB(230,230,230));

case WM_CTLCOLORSTATIC:
{
if (settingstext == (HWND)lParam)

//OR if the handle is unavailable to you, get ctrl ID

DWORD CtrlID = GetDlgCtrlID((HWND)lParam); //Window Control ID
if (CtrlID == IDC_STATIC1) //If desired control
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(0,0,0));
SetBkColor(hdcStatic, RGB(230,230,230));
return (INT_PTR)hBrush;
}
}

If you're looking to make the control's background transparent over a parent dialog you could use SetBkMode(hdcStatic, TRANSPARENT).

How do I set the text and background color of an single static control c++?

When responding to WM_CTLCOLORSTATIC, check lParam which holds the handle of the control.

CreateSolidBrush creates a GDI object. It should be deleted with DeleteObject otherwise it causes a resource leak. You can declare the brush as static and delete it at the end. Example:

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBRUSH hbrush = NULL;
switch(message)
{
case WM_DESTROY:
if (hbrush) DeleteObject(hbrush);
hbrush = NULL;
PostQuitMessage(0);
break;
case WM_CREATE:
staticTextField = CreateWindow("STATIC", "static 1", WS_VISIBLE
| WS_CHILD, 20, 20, 300, 25, hwnd, NULL, NULL, NULL);
staticTextFieldTwo = CreateWindow("STATIC", "static2", WS_VISIBLE |
WS_CHILD | WS_BORDER, 100, 200, 300, 20, hwnd, NULL, NULL, NULL);
break;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
if(lParam == (LPARAM)staticTextFieldTwo)
{
SetTextColor(hdcStatic, RGB(0, 255, 0));
SetBkColor(hdcStatic, RGB(0, 255, 255));
if (!hbrush)
hbrush = CreateSolidBrush(RGB(0, 255, 255));
return (LRESULT)hbrush;
}
break;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}

How to change a background color of a static window in win32API?

The window procedure for the parent window of the EDIT and STATIC controls can handle the WM_CTLCOLOREDIT and WM_CTLCOLORSTATIC messages, respectively.

An edit control that is not read-only or disabled sends the WM_CTLCOLOREDIT message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text and background colors of the edit control.

A static control, or an edit control that is read-only or disabled, sends the WM_CTLCOLORSTATIC message to its parent window when the control is about to be drawn. By responding to this message, the parent window can use the specified device context handle to set the text foreground and background colors of the static control.

how can I set static controls background color programmatically

Try something more like this:

HWND hWndLabel;
HBRUSH hBrushLabel;
COLORREF clrLabelText;
COLORREF clrLabelBkGnd;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
hWndLabel = CreateWindowEx(0, L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_LEFT,
75, 75, 70, 70, hWnd, (HMENU)labelId, hInst, NULL);
hBrushLabel = NULL;
clrLabelText = GetSysColor(COLOR_WINDOWTEXT);
clrLabelBkGnd = GetSysColor(COLOR_WINDOW);
break;

case WM_DESTROY:
if (hBrushLabel) DeleteObject(hBrushLabel);
PostQuitMessage(0);
break;

case WM_CTLCOLORSTATIC: {
HDC hdc = reinterpret_cast<HDC>(wParam);
SetTextColor(hdc, clrLabelText);
SetBkColor(hdc, clrLabelBkGnd);
if (!hBrushLabel) hBrushLabel = CreateSolidBrush(clrLabelBkGnd);
return reinterpret_cast<LRESULT>(hBrushLabel);
}

case WM_COMMAND: // all events are handled here
break;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}

DWORD WINAPI changecolor()
{
if (hBrushLabel) {
DeleteObject(hBrushLabel);
hBrushLabel = NULL;
}
clrLabelText = RGB(0xFF, 0x00, 0x00);
clrLabelBkGnd = RGB(0, 0, 230);
InvalidateRect(hWndLabel, NULL, TRUE);
return 0;
}

There is a similar example in the WM_CTLCOLORSTATIC documentation.

The following C++ example shows how to set the text foreground and background colors of a static control in response to the WM_CTLCOLORSTATIC message. The hbrBkgnd variable is a static HBRUSH variable that is initialized to NULL, and stores the background brush between calls to WM_CTLCOLORSTATIC. The brush must be destroyed by a call to the DeleteObject function when it is no longer needed, typically when the associated dialog box is destroyed.

case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC) wParam;
SetTextColor(hdcStatic, RGB(255,255,255));
SetBkColor(hdcStatic, RGB(0,0,0));

if (hbrBkgnd == NULL)
{
hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
}
return (INT_PTR)hbrBkgnd;
}

How do I change the background of a STATIC win32 control?

You can set the background color for a static control by handling the WM_CTLCOLOR message.

From the documentation

If an application processes this message, it returns a handle to a
brush. The system uses the brush to
paint the background of the control.

The message also passes a pointer to the display context that you can use.

C++ Win32 Change static Color

Handle the WM_CTLCOLORSTATIC message inside your WndProc function:

case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam; // or obtain the static handle in some other way
SetTextColor(hdcStatic, RGB(255, 0, 0)); // text color
SetBkColor(hdcStatic, RGB(12,34,210));
return (LRESULT)GetStockObject(NULL_BRUSH);
}
break;

If you want to change only the specific component's color then obtain the target's handle using a simple if statement:

case WM_CTLCOLORSTATIC:
{
if (GetDlgCtrlID((HWND)lParam) == IDC_STATIC1) // Target the specific component
{
// same as above
}
}
break;


Related Topics



Leave a reply



Submit