You can draw the background in WM_ERASEBKGND and draw the text with Owner-drawn
A test in C++/Win32 :
#include <windows.h>
#include <tchar.h>
#include <commctrl.h>
#pragma comment (lib, "comctl32")
#include <Vsstyle.h>
#include <vssym32.h>
#include <uxtheme.h>
#pragma comment(lib, "UxTheme")
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int nWidth = 600, nHeight = 400;
#define IDC_STATUSBAR 10
#define IDC_BUTTON 11
VOID __inline UpdateStatusBar(HWND hWndStatusBar, LPCWSTR lpszStatusString, WORD partNumber, WORD displayFlags)
{
SendMessage(hWndStatusBar, SB_SETTEXT, partNumber | displayFlags, (LPARAM)lpszStatusString);
}
LRESULT CALLBACK StatusBarSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR);
BOOL IsDarkMode();
BOOL _bDarkMode = FALSE;
COLORREF GetButtonBackgroundColor();
COLORREF _colorBackground = RGB(51, 51, 51);
typedef BOOL(WINAPI* fnAllowDarkModeForWindow)(HWND hWnd, BOOL allow);
fnAllowDarkModeForWindow pAllowDarkModeForWindow;
enum PreferredAppMode { Default, AllowDark, ForceDark, ForceLight, Max };
typedef PreferredAppMode(WINAPI* fnSetPreferredAppMode)(PreferredAppMode appMode);
fnSetPreferredAppMode pSetPreferredAppMode;
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
hInst = hInstance;
WNDCLASSEX wcex =
{
sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("WindowClass"), NULL,
};
if (!RegisterClassEx(&wcex))
return MessageBox(NULL, TEXT("Cannot register class !"), TEXT("Error"), MB_ICONERROR | MB_OK);
int nX = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2, nY = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
HWND hWnd = CreateWindowEx(0, wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, nX, nY, nWidth, nHeight, NULL, NULL, hInst, NULL);
if (!hWnd)
return MessageBox(NULL, TEXT("Cannot create window !"), TEXT("Error"), MB_ICONERROR | MB_OK);
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hWndButton = NULL;
static HWND hWndStatusBar = NULL;
int wmId, wmEvent;
switch (message)
{
case WM_CREATE:
{
hWndButton = CreateWindowEx(0, L"Button", L"Click", WS_CHILD | WS_VISIBLE | BS_PUSHLIKE, 100, 60, 60, 32, hWnd, (HMENU)IDC_BUTTON, hInst, NULL);
HMODULE hDll = LoadLibrary(L"UXTheme.dll");
pSetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hDll, MAKEINTRESOURCEA(135));
if (pSetPreferredAppMode)
pSetPreferredAppMode(AllowDark);
pAllowDarkModeForWindow = (fnAllowDarkModeForWindow)GetProcAddress(hDll, MAKEINTRESOURCEA(133));
if (pAllowDarkModeForWindow)
pAllowDarkModeForWindow(hWndButton, TRUE);
SetWindowTheme(hWndButton, L"Explorer", NULL);
_bDarkMode = IsDarkMode();
hWndStatusBar = CreateWindow(STATUSCLASSNAME, L"",
WS_VISIBLE | WS_CHILD | WS_BORDER | SBS_SIZEGRIP,// | SBARS_TOOLTIPS,
0, 0, 0, 0, hWnd, (HMENU)IDC_STATUSBAR, hInst, NULL);
RECT rect;
GetClientRect(hWnd, &rect);
int ptArray[5];
ptArray[0] = 0;
ptArray[2] = rect.right;
ptArray[1] = ptArray[2] - 300;
ptArray[0] = 100;
SendMessage(hWndStatusBar, SB_SETPARTS, sizeof(ptArray) / sizeof(ptArray[0]), (LPARAM)(LPINT)ptArray);
UpdateStatusBar(hWndStatusBar, L"Part 0", 0, SBT_POPOUT | SBT_OWNERDRAW);
UpdateStatusBar(hWndStatusBar, L"Part 1", 1, SBT_POPOUT | SBT_OWNERDRAW);
UpdateStatusBar(hWndStatusBar, L"Part 2", 2, SBT_POPOUT | SBT_OWNERDRAW);
SetWindowSubclass(hWndStatusBar, StatusBarSubclassProc, 0, 0);
return 0;
}
break;
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* lpDIS;
lpDIS = (LPDRAWITEMSTRUCT)lParam;
int savedDC = SaveDC(lpDIS->hDC);
if (lpDIS->hwndItem == hWndStatusBar)
{
RECT rect;
COLORREF crOldTextColor, crOldBkColor;
int nOldMode;
WCHAR sDrawText[255] = L"";
int nID = lpDIS->itemID;
CopyRect(&rect, &lpDIS->rcItem);
if (lpDIS->itemData)
lstrcpy(sDrawText, (LPWSTR)lpDIS->itemData);
nOldMode = SetBkMode(lpDIS->hDC, TRANSPARENT);
if (nID == 0 || nID == 1 || nID == 2)
{
if (nID == 0)
crOldTextColor = SetTextColor(lpDIS->hDC, RGB(0, 0, 255));
else if(nID == 1)
crOldTextColor = SetTextColor(lpDIS->hDC, RGB(0, 255, 0));
else
crOldTextColor = SetTextColor(lpDIS->hDC, RGB(255, 0, 0));
//crOldBkColor = SetBkColor(lpDIS->hDC, GetSysColor(COLOR_BTNFACE));
DrawText(lpDIS->hDC, sDrawText, -1, &rect, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
SetTextColor(lpDIS->hDC, crOldTextColor);
//SetBkColor(lpDIS->hDC, crOldBkColor);
SetBkMode(lpDIS->hDC, nOldMode);
}
}
RestoreDC(lpDIS->hDC, savedDC);
return 1;
}
case WM_SETTINGCHANGE:
{
WCHAR* plParam = (LPWSTR)lParam;
if (plParam)
{
if (lstrcmp(plParam, TEXT("ImmersiveColorSet")) == 0)
{
_bDarkMode = IsDarkMode();
RedrawWindow(hWndStatusBar, NULL, NULL, RDW_UPDATENOW | RDW_INVALIDATE | RDW_ERASE);
SendMessageW(hWndButton, WM_THEMECHANGED, 0, 0);
}
}
return 0;
}
break;
case WM_SIZE:
{
SendMessage(hWndStatusBar, message, wParam, lParam);
return 0;
}
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDC_BUTTON:
{
if (wmEvent == BN_CLICKED)
{
Beep(1000, 10);
}
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK StatusBarSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR)
{
switch (msg)
{
case WM_ERASEBKGND:
{
RECT rect;
GetClientRect(hwnd, &rect);
COLORREF color = GetButtonBackgroundColor();
HBRUSH hBrush = CreateSolidBrush(color);
FillRect((HDC)wParam, &rect, hBrush);
DeleteObject(hBrush);
return 0;
}
break;
}
return DefSubclassProc(hwnd, msg, wParam, lParam);
}
BOOL IsDarkMode()
{
DWORD nValue = 0;
DWORD nSize = sizeof(nValue);
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hKey, L"AppsUseLightTheme", nullptr, nullptr, (LPBYTE)&nValue, &nSize);
RegCloseKey(hKey);
}
return nValue == 0; // 0 = Dark mode, 1 = Light mode
}
COLORREF GetButtonBackgroundColor()
{
if (IsDarkMode())
return _colorBackground;
return GetSysColor(COLOR_BTNFACE);
}