29

I am not using a dialog, I'm using my own custom class which I have registered and then used the CreateWindow call to create it, I have preset the background color to red when registering:

WNDCLASSEX wc;
wc.hbrBackground = CreateSolidBrush(RGB(255, 0, 0));

But now I want to change the background color at runtime, by e.g. clicking a button to change it to blue.

I have tried to use SetBkColor() call in the WM_PAINT, and tried returning a brush from the WM_CTLCOLORDLG message, they don't work.

Any help?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Kaije
  • 2,631
  • 6
  • 38
  • 40

3 Answers3

27

From Window Background comes:

...The system paints the background for a window or gives the window the opportunity to do so by sending it a WM_ERASEBKGND message when the application calls BeginPaint. If an application does not process the message but passes it to DefWindowProc, the system erases the background by filling it with the pattern in the background brush specified by the window's class.....

...... An application can process the WM_ERASEBKGND message even though a class background brush is defined. This is typical in applications that enable the user to change the window background color or pattern for a specified window without affecting other windows in the class. In such cases, the application must not pass the message to DefWindowProc. .....

So, use the WM_ERASEBKGND message's wParam to get the DC and paint the background.

Zabba
  • 64,285
  • 47
  • 179
  • 207
17

You may try the following:

HBRUSH brush = CreateSolidBrush(RGB(0, 0, 255));
SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG_PTR)brush);
Axalo
  • 2,953
  • 4
  • 25
  • 39
Tassos
  • 3,158
  • 24
  • 29
  • That changes it for all instances of that class. You'll also need to invalidate the window to cause it to erase and repaint. – Adrian McCarthy Aug 11 '10 at 23:02
  • yeah, this worked, but I have my own class wrapper and the reason i wanted to set it after registering is because i want windows from the same class to have different background colors – Kaije Aug 11 '10 at 23:05
5

Short answer: Handle WM_ERASEBKGND.

Longer answer:

When you register the WNDCLASS, you're providing information about all windows of that class. So if you want to change the color of just one instance of the window, you'll need to handle it yourself.

When it's time to repaint your window, the system will send your wndproc a WM_ERASEBKGND message. If you don't handle it, the DefWindowProc will erase the client area with the color from the window class. But you can handle the message directly, painting whatever color (or background pattern) you like.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175