[comp.windows.ms.programmer] Rectangle tooo slow?

dave@wucs1.wustl.edu (David T Mitchell III) (06/03/91)

I want to make my winapp's border non-standard colors (ie, active
and inactive border colors != COLOR_ACTIVEBORDER, COLOR_INACTIVEBORDER).

It appears that to process WM_NCPAINT, it's all or nothing (is this true?),
so I decided to be Q&D about it...
	.
	.
	case WM_NCPAINT:
	    DefWindowProc(hwnd, msg, wParam, lParam);	// draw the window
	    ExcludeClipRect(hdc, {everything inside the borders});
	    SelectObject(hdc, CreateSolidBrush(myColor));
	    Rectangle(hdc, 1, 1, {full window extents});
	    return 0L;

This works just dandy (left out details about checking for type of border,
etc, for clarity), HOWEVER it's suprisingly slow!  Stepping through with the
debugger I find that calling DefWindowProc paints the entire window frame
with border BANG!, but Rectangle() paints so slowly that you first see the
standard borders, then the new color flowing down over.

I tried using 4 seperate rectangle calls (as opposed to excluding & 1 call),
but that just gives the same results, but with 4 slow rectangles.

Why is the DefWindowProc so much faster than a simple Rectangle?  Is there
a better way (read: faster) to do this?

thanks in advance, 

dave	dave@wucs1.wustl.edu

risto@tuura.UUCP (Risto Lankinen) (06/07/91)

dave@wucs1.wustl.edu (David T Mitchell III) writes:

>I want to make my winapp's border non-standard colors (ie, active
>and inactive border colors != COLOR_ACTIVEBORDER, COLOR_INACTIVEBORDER).

>It appears that to process WM_NCPAINT, it's all or nothing (is this true?),
>so I decided to be Q&D about it...
>	.
>	.
>	case WM_NCPAINT:
>	    DefWindowProc(hwnd, msg, wParam, lParam);	// draw the window
>	    ExcludeClipRect(hdc, {everything inside the borders});
>	    SelectObject(hdc, CreateSolidBrush(myColor));
>	    Rectangle(hdc, 1, 1, {full window extents});
>	    return 0L;

>This works just dandy (left out details about checking for type of border,
>etc, for clarity), HOWEVER it's suprisingly slow!  Stepping through with the
>debugger I find that calling DefWindowProc paints the entire window frame
>with border BANG!, but Rectangle() paints so slowly that you first see the
>standard borders, then the new color flowing down over.

Hi!

Try FillRect() in place of Rectangle() .  Also, don't use CreateSolidBrush()
in a time-critical or frequently called WinProc-case.  You could create the
brush upon WM_NCCREATE, and store its handle into a static variable for use
where appropriate (and for deletion upon WM_NCDESTROY!!!) .

Also, how does 'wndclass.hbrBackground = NULL' affect the performance?  You
will then have to either handle the WM_ERASEBKGND or use FillRect() for the
first thing in the WM_PAINT to get a clean surface to draw on, but calling
the DefWindowProc() during (and not after) the WM_NCPAINT might generate some
extraneous postings/sendings of these messages.

Terveisin: Risto Lankinen
-- 
Risto Lankinen / product specialist ***************************************
Nokia Data Systems, Technology Dept *  2                              3   *
THIS SPACE INTENTIONALLY LEFT BLANK * 2 +1 is PRIME!  Now working on 2 -1 *
replies: risto@yj.data.nokia.fi     ***************************************

bonneau@hyper.hyper.com (Paul Bonneau) (06/07/91)

In article <1991Jun3.140840.26667@cec1.wustl.edu>
dave@wucs1.wustl.edu (David T Mitchell III) writes:
>I want to make my winapp's border non-standard colors (ie, active
>and inactive border colors != COLOR_ACTIVEBORDER, COLOR_INACTIVEBORDER).
>
>It appears that to process WM_NCPAINT, it's all or nothing (is this true?),
>so I decided to be Q&D about it...
>	.
>	.
>	case WM_NCPAINT:
>	    DefWindowProc(hwnd, msg, wParam, lParam);	// draw the window
>	    ExcludeClipRect(hdc, {everything inside the borders});
>	    SelectObject(hdc, CreateSolidBrush(myColor));
>	    Rectangle(hdc, 1, 1, {full window extents});
>	    return 0L;
>
>This works just dandy (left out details about checking for type of border,
>etc, for clarity), HOWEVER it's suprisingly slow!  Stepping through with the
>debugger I find that calling DefWindowProc paints the entire window frame
>with border BANG!, but Rectangle() paints so slowly that you first see the
>standard borders, then the new color flowing down over.
>
>I tried using 4 seperate rectangle calls (as opposed to excluding & 1 call),
>but that just gives the same results, but with 4 slow rectangles.
>
>Why is the DefWindowProc so much faster than a simple Rectangle?  Is there
>a better way (read: faster) to do this?
>
I think the problem with the first approach is the clipping.
Rectangle() is gawd-awful slow to begin with, but if you clip
out the inside of essentially a big PatBlt(), that can be
awesomely slow.  Not sure why the second approcah is slow as
well, make sure the ExcludeClipRect() is missing.

However, for the fastest possible solid fills, use
ExtTextOut()!

Something like:

	SetBkColor(hdc, myColor);
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, (LPRECT)&rect, lszNull, 0,
	    lpintNull);

4 times, should be fast.

cheers - Paul Bonneau.