Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

[MFC] How to change background color of a window? 1

Status
Not open for further replies.

alcyone

Programmer
Sep 6, 2000
33
0
0
Hi all,

I want to have a window with a black background. I do this by a 'FillRect'-command, but because the window is being refreshed 10 times a second, I see a annoying flickering each time. I'm sure there is a better way, probably by creating the window, but can't find out how.
Any ideas? Thanks in advance!
 
wndclass.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);

when registering the window class (in bare Win32 API). In MFC, look it up where you can pass arguments to the window class.
 
Thank you Sandup,

But I still can't figure out how to implement this in MFC. I don't see anything about the window class.
Anyone experience with this?
 
Fortunately for you alcyone, I am just a few pages away of learning how to do this. I will peek ahead and try to give you some sample code, and if it doesn't work I will be learning how to do it shortly.

// Step 1: Register a window 'class'

CString MyWinClass ; // name of window 'class'
MyWinClass = AfxRegisterWndClass (
CS_DBLCLKS | CS_HREDRAW,
AfxGetApp()->LoadStandardCursor(IDC_ARROW),
::CreateSolidBrush (RGB(100,255,100)),
AfxGetApp()->LoadStandardIcon(IDI_APPLICATION)
//(IDI_WINLOGO)
);

// Step 2: Create a window based on the window 'class'

Create(MyWinClass, "Ex05h Change Window Background Brush",
WS_OVERLAPPEDWINDOW, CRect(0,0,270,260));


That was written by Richard M. Jones. So far in the create od I have always used NULL as the first parameter, but it appears I will be learning how to do otherwise soon.

-Bones
 
One thing to HELP minimize the flicker factor...remember the word HELP...it's not a SOLUTION. Override the OnEraseBackground() message handler, comment out the default return value, and replace it with "return FALSE;"

Also, instead of fillrect, using this snippet in OnDraw() or OnPaint() (depending on your application). It's just personal preference:

// Set brush to desired background color
CBrush backBrush(RGB(0, 0, 0));

// Save old brush
CBrush* pOldBrush = pdc->SelectObject(&backBrush);

CRect rect;
pdc->GetClipBox(&rect); // Erase the area needed

pdc->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);

//Restore old brush
pdc->SelectObject(pOldBrush);

 
Thank you for both answers!

Bones3: I think this seems to be the solution. I'm now looking how I can use this with MFC. No luck so far...

Gorgor: (1) I tried your code instead of fillrect but don't see any difference in flickering. What's the advantage of your method?
(2) Can you tell me how to override that msg-handler? I looked with Class Wizard for that message but couldn't find it.
 
I can now answer your question better since I have completed the lesson covering this. Mr. Jones' code was directly out of an MFC application. They key to do what you want is to CONSTRUCT the window with a black background like you said:

>>I'm sure there is a better way, probably by creating the window

This is done in your main window class' constructor. (CMainFrame for me usually) It is done in two easy steps:

1: Register a window class. Do this first thing in the code of your constructor.


CString MyWinClass ; // declaring the window "class"

MyWinClass = AfxRegisterWndClass (
CS_DBLCLKS | CS_HREDRAW, // even in your code this can
// be the same, look in help for more detail

AfxGetApp()->LoadStandardCursor(IDC_ARROW),
// Deals with the cursor the window uses.

::CreateSolidBrush (RGB(100,255,100)),
//<- this is what you want, client area color. black is obviously RGB(0,0,0)

AfxGetApp()->LoadStandardIcon(IDI_APPLICATION) // deals with icon
);

Step 2: In the Create function, use the MyWinClass that you just created.

Create(MyWinClass, &quot;Ex05h Change Window Background Brush&quot;,
WS_OVERLAPPEDWINDOW, CRect(0,0,270,260));

If you still have trouble I can e-mail this sample to you with the code if you like. It really does work, I promise.


-Bones
 
Look for the WM_ERASEBKGND message and override the handler for it. It will be OnEraseBkgnd(...). Returning FALSE in that function will stop the app from erasing the background on every paint.

I'm not sure that there's much benefit in using PatBlt...it's just personal preference.
 
My problem has been solved now!
Both answers work fine for me. But the way I do it now is simply by a &quot;Invalidate (FALSE)&quot; call at every update. This is almost the same way as overriding the OnEraseBackground handler.
The problem that caused the flickering was because at every refresh the window was first drawn with a white background (the default color) and then I added my black rectangle on it. Now it's black on a black background, so no flickering! :)
Thanks again!
 


Bones3 (Programmer)


hi, after i tried ur code i recieve this warning

&quot;Warning: Window creation failed: GetLastError returns 0x0000057E&quot;

where have i gone wrong?? can e-mail me ur sample code?

kunckle@hotmail.com


 
BOOL CRouletteCalculatorApp::InitInstance()
{
COLORREF clrCtlBk,clrCtlText;
//Set dialogbackground color to black, text to white
SetDialogBkColor(clrCtlBk=RGB(1,1,1),
clrCtlText=RGB(255,255,255));
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top