One can use GetDC/ReleaseDC to draw in client area of window. But in response to WM_PAINT message one have to use BeginPaint/EndPaint. Is there something special about this?
A WM_PAINT message is issued when a part of the window needs to be updated. By specifying BeginPaint/EndPaint() you are telling gdi that you are actually doing that job. If you don't call BeginPaint() for the specified region, WM_PAINT messages will be generated for as long until someone actually updates it. The function gives you a DC just because it's convenient. Internally BeginPaint()/EndPaint() probably call GetDC()/ReleaseDC().
In contrast with GetDC and ReleaseDC you are telling GDI that you are now about to paint something onto the DC, without gdi requesting that you must.