One of the functions used most often in MFC development is Invalidate(). But are you calling it carelessly every time you just want to redraw the screen?
Based on the material I was given, here's a rundown of the core ideas behind the 'Dirty Flag pattern,' which cuts down on unnecessary redraws and maximizes performance.
1. What Invalidate() Really Means: "A Signal That the Screen Has Become Invalid"
Invalidate() is not a command that says "redraw the screen right now!" It's an act of marking — a request that says, "the data in this region has changed and is no longer valid, so please redraw it (WM_PAINT) whenever the OS gets a free moment."
Invalidate() has been called as being 'Dirty,' and later, once the message queue has some slack, it fires off a WM_PAINT message to actually perform the redraw.
2. The Key to Performance: The Dirty Flag Pattern
If you call Invalidate() excessively even when the data hasn't changed, the CPU ends up repeating unnecessary OnPaint operations. This is where using a Dirty Flag (a flag indicating whether a redraw is needed) can dramatically improve performance.
- Detect a data change → set
bIsDirty = true. - Call
Invalidate()only when the data has actually changed. - After
OnPaint()finishes processing → reset it back tobIsDirty = false.
Example Code: Efficient Redrawing Using a Flag
void CMyView::UpdateData(int nNewValue) {
if (m_nData != nNewValue) { // Only when the value has actually changed
m_nData = nNewValue;
m_bIsDirty = true; // Set the Dirty Flag
Invalidate(); // Only now request a redraw
}
}
void CMyView::OnPaint() {
CPaintDC dc(this);
if (m_bIsDirty) {
// Perform the actual drawing logic
m_bIsDirty = false; // Clear the flag once the redraw is done
}
}
3. A Word of Caution: Invalidate vs UpdateWindow
This is a point developers often get confused about. You need to use each one correctly depending on the situation.
Invalidate(): "Redraw it whenever." (asynchronous — queues a message)UpdateWindow(): "Redraw it right now!" (synchronous — forcibly sends WM_PAINT immediately)
When data updates happen repeatedly, it's far more efficient to use only Invalidate() and let the OS batch the redraws together.
Wrapping Up
What separates a skilled MFC UI developer from a novice comes down to "how sparingly you use Invalidate()."
Adopt the Dirty Flag pattern to track data changes, and experience smooth Windows programming free of screen flickering!