Click here to Skip to main content
15,891,629 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to be able to click a button in the client area and have the client area redrawn.
My main issue is that I can't seem to get it to work properly.
what I get is a flickering after the button is pressed.

What I have tried:

I've tried.
C++
void CButtonTestView::OnButtonClicked()
{
	AfxMessageBox(L"Button clicked");
	Clicked = TRUE;
	Invalidate();
	UpdateWindow();
}

void CButtonTestView::OnDraw(CDC* pDC)
{
	CButtonTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: add draw code for native data here
	pDC->TextOutW(800, 100, _T("Button test"));

	if (Clicked)
	{
		InvalidateRect(nullptr, TRUE);
	}
}


visual studio 2017.
Any contribution is appreciated
Posted
Updated 4-Dec-17 10:50am
Comments
Richard MacCutchan 4-Dec-17 16:54pm    
The simple answer is that you should never call InvalidateRect from inside your OnDraw method.

As far as I know you shouldn't call InvalidateRect inside OnDraw because, at the end, this reschedules OnDraw again.
 
Share this answer
 
A CPallini mentioned, you do not need the InvalidateRect call inside your OnDraw handler. You are setting yourself up for an endless loop doing it that way. At the very least, set Clicked to false in there to stop the looping.

The cause of the flickering is the call to Invalidate() because it has a default argument, erase, set to true which means it erases the entire window. That causes OnEraseBkgnd to be called which fill the entire window with the background color and then the OnDraw method is called. All of this results in flicker.

There are (at least) two possible ways to avoid the flicker. One is to call Invalidate and pass false to it so it doesn't erase the background. That will only work if your OnDraw method completely draws all of the foreground image and they usually don't. Another way is to draw into a memory device context. MFC has a built-in class called CMemDC to help with this. There is also an article here written by Keith Rule with a simple implementation of a memory DC that works very well. To this your OnDraw handler has to also draw the background and you want to have an OnEraseBkgnd handler that just returns TRUE to indicate it was drawn but it actually does nothing.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900