|
-
May 12th, 1999, 03:09 PM
#1
Best way to call Default Drawing from a WM_PAINT message?
I am writing a basic C++ Win32 app ( no MFC ). I would like to be able to have custom client drawing as well as the default drawing in the same control. I have code that works but is probably not the best or standard way to accomplish this. The following code flickers and causes certain refresh problems.
// this is called from the message dispatcher.
long
CWindow::PaintContent( void )
{
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint( mHandle, &ps );
// this is a virtual method to do custom drawing
this->PaintContentSelf( hdc, ps.rcPaint );
::EndPaint( mHandle, &ps );
return 0;
}
void
CWindow::PaintContentSelf( HDC inHDC, const RECT & inClipRect )
{
// problem with flicker
// first re-invalidate the rect
::InvalidateRect( mHandle, &inClipRect, false );
// send the message back to the parent process
::CallWindowProc( mOldWndProc, mHandle, WM_PAINT, 0, 0);
// for testing draw a red line
HPEN pen = ::CreatePen( PS_DOT, 2, RGB( 255, 0, 0 ) );
::SelectObject( inHDC, pen );
::MoveToEx( inHDC, 0, 0, nil );
::LineTo( inHDC, 20, 20);
: eleteObject( pen );
}
Any Suggestions would be appreciated.
Thanks
David Giovannini
-
May 12th, 1999, 04:13 PM
#2
Re: Best way to call Default Drawing from a WM_PAINT message?
Why do you need to re-Invalidate the window? By doing so, you are posting another WM_PAINT to the message queue.
Another thing is this line in your code:
::CallWindowProc( mOldWndProc, mHandle, WM_PAINT, 0, 0);
If the goal is to call the old window procedure, you should be sending the original wParam and lParam values to the old window procedure, not zeros.
Regards,
Paul McKenzie
-
May 12th, 1999, 06:21 PM
#3
Re: Best way to call Default Drawing from a WM_PAINT message?
You are right, safest thing to do is pass the l and w params. According to docs, the wparam is nothing and the lparam is a possible hdc.
BeginPaint validates the rectangle. Calling the default will do nothing if the rect is not re-invalidated. That is why I called InvalidateRect.
If another WM_PAINT is posted, that will explain the flicker. If I replace the BeginPaint and EndPaint with GetDC and ReleaseDC, I do not need the Invalidate call but I loose any DC processing that BeginPaint does (including giving me the clip rect).
Am I placing too much importance on BeginPaint?
I set my class styles to include CS_(HV)REDRAW. All drawing occured as expected. The code ( excluding wnd register ) looks like
long
CWindow::PaintContent( HDC inHDC )
{
HDC hdc = inHDC;
if ( not inHDC ) hdc = ::GetDC( mHandle );
this->PaintContentSelf( hdc );
if ( not inHDC ) ::ReleaseDC( mHandle, hdc );
return 0;
}
void
CWindow::PaintContentSelf( HDC inHDC )
{
this->DefaultLastMessage(); // preserves params
// more drawing
...
}
-
May 12th, 1999, 08:45 PM
#4
Re: Best way to call Default Drawing from a WM_PAINT message?
Try GetUpdateRect(). According to the documentation, this will get you the same clipping region as BeginPaint(). So I would call GetUpdateRect(), the default handler, and then use GetDC / ReleaseDC to do the custom drawing, in that order.
There may not be any need to call BeginPaint(), EndPaint(), or InvalidateRect().
Regards,
Paul McKenzie
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|