Click here to Skip to main content
15,114,611 members
Articles / Desktop Programming / Win32
Technical Blog
Posted 17 Mar 2010

Tagged as

Stats

34.3K views
8 bookmarked

BeginPaint/EndPaint or GetDC/ReleaseDC?

Rate me:
Please Sign up or sign in to vote.
4.25/5 (3 votes)
18 Mar 2010CPL2 min read
Which is better, to use BeginPaint/EndPaint, or to use GetDC/ReleaseDC?

Which is better, to use BeginPaint/EndPaint, or to use GetDC/ReleaseDC?

Actually, it depends! If you are handling WM_PAINT, you should use BeginPaint/EndPaint. Otherwise, you should use GetDC/ReleaseDC.

You already know that Windows sends WM_PAINT to your message queue as soon as a new area of the window’s client area becomes invalidated.

If Windows finds an invalidated area, it sets a flag in the message pump indicating that a new WM_PAINT is waiting for processing. If no messages are waiting in the queue, it sends the WM_PAINT to the window procedure.

An area of the client area of the window becomes invalidated in many ways. For example, when a portion of the window is covered by another window, Windows combines the area covered by the other window with the currently invalidated area of the window. In addition, you can “invalidate” an area of the window using functions like InvalidateRect (to invalidate a rectangular area.) Those functions add the area specified to the currently invalidated area (i.e. combine the new area with the currently invalidated area of the window.)

Remember that, Windows continues sending WM_PAINT messages to your message queue as long as there’s an invalidated area. Therefore, you should validate the client area before leaving the WM_PAINT handler block. That’s why it is recommended using BeginPaint/EndPaint in WM_PAINT message handler because EndPaint does validate the entire client area of the window.

The following is a pseudo-code for EndPaint:

BOOL EndPaint(...)
{
	. . .

	validate client area
	e.g. call ValidateRect()

	release the DC

	do the necessary finalization
	. . .
}

Therefore, using GetDC/ReleaseDC in WM_PAINT would clog the message pump with a sequence of WM_PAINT messages that would divert your application from continuing its work, unless you validate the client area before jumping out of WM_PAINT handler.

On the other hand, using BeginPaint/EndPaint outside the WM_PAINT handler would validate the client area each time you call EndPaint. And that would prevent WM_PAINT from arriving to your message queue.

Another interesting point to consider is the following block of code inside the window procedure:

switch (uMsg)
{
	. . .

	case WM_PAINT:

		return 0;

	. . .
}

Why is the previous code considered wrong? Yes, you are right. It leaves the WM_PAINT with neither validating the client area nor passing the message to the default window procedure.

The default window procedure actually did nothing interesting inside the WM_PAINT. However, it is required to pass the WM_PAINT to the default window procedure if you are not going to handle WM_PAINT or you're not validating the client area inside the WM_PAINT handler. That’s because Windows simply calls BeginPaint and EndPaint in pair. Thus, validates the client area.

C++
case WM_PAINT:
	BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		return 0;

Thus, you should use BeginPaint/EndPaint in WM_PAINT only and GetDC/ReleaseDC in all other places in your code.


Filed under: Windows GDI Tagged: API, C, CodeProject, Windows GDI

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)

Share

About the Author

Mohammad Elsheimy
Software Developer (Senior)
Egypt Egypt
Mohammad Elsheimy is a developer, trainer, and technical writer. He is a MCP, MCTS (WinForms), MCPD (Windows Apps), MCSA (SQL Server), MCSE (Data Analytics), and MCT expertized in .NET Framework technologies, data management and analytics. He is also a Project Management Professional (PMP) and a Quranic Readings Institute (Al-Azhar) graduate specialized in Quranic readings, Islamic legislation, and the Arabic language.

Comments and Discussions

 
GeneralMy vote of 2 Pin
Martin Richter [rMVP C++]18-Nov-10 23:54
MemberMartin Richter [rMVP C++]18-Nov-10 23:54 
GeneralErrata Pin
Prakash Gupta13-Apr-10 0:39
MemberPrakash Gupta13-Apr-10 0:39 
GeneralRe: Errata Pin
Mohammad Elsheimy20-Sep-10 2:24
MemberMohammad Elsheimy20-Sep-10 2:24 
SuggestionRe: Errata Pin
Nashev29-Dec-11 8:00
MemberNashev29-Dec-11 8:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.