Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WM_PAINT / WM_ERASEBKGND

1,112 views
Skip to first unread message

Flzw

unread,
Jul 15, 2004, 11:21:38 AM7/15/04
to
Seeing that RichEdit controls were more trouble than help, I decided to
ditch them and try and code my very own control to output simple formated
text.

I have pretty good ideas about how I'm going to do it but there's a detail
that has me confused.

I thought a control was sent the WM_PAINT message whenever it had to be
redrawn (a window passed over it, it has been resize etc...).

Well, I don't get them.
All I have are WM_ERASEBKGND messages which I process since I didn't provide
a brush for the background in my class definition ( was that even a good
idea in the first place ?)

So I don't know, am I supposed to do a UpdateWindow() at the end of my
WM_ERASEBKGND processing ? Maybe that would work but, I don't know, that
doesn't sound "right" to me.


Matt Gregory

unread,
Jul 15, 2004, 12:02:26 PM7/15/04
to

I'm pretty sure that the BeginPaint() function sends the WM_ERASEBKGND
message when it's called. Are you subclassing an existing control or
something? When I make my own control, I just use a vanilla window so
I can handle/ignore all the messages myself. If you make up a name for
the window class, then you just get a plain window. Or am I
misunderstanding your problem?

Matt Gregory

Flzw

unread,
Jul 15, 2004, 12:20:09 PM7/15/04
to
> If you make up a name for
> the window class, then you just get a plain window. Or am I
> misunderstanding your problem?
>
> Matt Gregory

Yes, I'm not subclassing, the problem is I don't receive any WM_PAINT
messages, here is the code :

ATOM RegisterTOC( HINSTANCE hInst);
LRESULT CALLBACK TextOutputControlProc( HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
int PaintBKGND( HWND hWnd);

ATOM RegisterTOC( HINSTANCE hInst)
{
WNDCLASSEX wcx;

ZeroMemory( &wcx, sizeof( WNDCLASSEX));

wcx.cbSize = sizeof( WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcx.lpfnWndProc = (WNDPROC) TextOutputControlProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInst;
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor( NULL, IDC_ARROW);
wcx.hbrBackground = NULL;
wcx.lpszMenuName = NULL;
wcx.lpszClassName = "TEXTOUTPUT";
wcx.hIconSm = NULL;

return RegisterClassEx( &wcx);
}

LRESULT CALLBACK TextOutputControlProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
HDC hdc;
HFONT hfont;
switch( uMsg)
{
case WM_ERASEBKGND:
return PaintBKGND( hWnd);
break;
case WM_PAINT:
// WM_PAINT Stuff
break;
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
return 0;
}

// Paints the background of the control

int PaintBKGND( HWND hWnd)
{

HDC hdc;
HBRUSH hbrBkgnd;
PAINTSTRUCT ps;
RECT r;

GetClientRect( hWnd, &r);
hdc = BeginPaint( hWnd, &ps);
hbrBkgnd = CreateSolidBrush( RGB( 255,255,255));
FillRect( hdc, &r, hbrBkgnd);
EndPaint( hWnd, &ps);

return 1;
}


Frank Renner

unread,
Jul 15, 2004, 2:30:32 PM7/15/04
to

"Flzw" <flo...@wanadoo.fr> wrote in message news:cd6aqs$miq$1...@news-reader1.wanadoo.fr...

Do not call BeginPaint/EndPaint in the WM_ERASEBKGND handler.
These functions should be called inside a WM_PAINT handler only.
The DC to use in the WM_ERASEBKGND handler is passed in the
WPARAM parameter.

Regards,
Frank


Flzw

unread,
Jul 15, 2004, 2:30:43 PM7/15/04
to

> Do not call BeginPaint/EndPaint in the WM_ERASEBKGND handler.
> These functions should be called inside a WM_PAINT handler only.
> The DC to use in the WM_ERASEBKGND handler is passed in the
> WPARAM parameter.

Yes, Thank you, I just figured that out, but how am I supposed to know the
rect I have to fill ? Is WM_ERASEBKGND only called to redraw the whole
control background ? in this case, should I use WindowFromDC and then
GetClientRect ?

Thanks. I find this part really poorly described on MSDN.


Severian

unread,
Jul 15, 2004, 2:52:08 PM7/15/04
to

You can do your erasing in WM_PAINT. Return FALSE in WM_ERASEBKGND and
check the fErase member of the PAINTSTRUCT in WM_PAINT.

--
Sev

Matt Gregory

unread,
Jul 15, 2004, 8:54:38 PM7/15/04
to
Severian wrote:

> You can do your erasing in WM_PAINT. Return FALSE in WM_ERASEBKGND and
> check the fErase member of the PAINTSTRUCT in WM_PAINT.

You can just return true in WM_ERASEBKGND and that will take care of
the flag.

Matt Gregory

Severian

unread,
Jul 16, 2004, 10:40:37 AM7/16/04
to
On Fri, 16 Jul 2004 00:54:38 GMT, Matt Gregory <em...@invalid.net>
wrote:

I believe returning TRUE says "I did erase it, so nothing else has to
worry about it." If you didn't actually do the necessary painting, you
may have unexpected results.

IIRC, returning TRUE will clear the fErase flag -- which is best as
long as you have no need to know if you need to erase the background
in WM_PAINT (such as if you're copying the *entire* window area from a
bitmap.) But if you need to actually know later if you need to erase
background areas, I think it's better to return false.

I could be wrong, but I looked at existing code and tried changing my
WM_ERASEBKGND return to TRUE, and found areas outside of the image
that occupied my window were not erased. However, the code is quite
complicated and this could be due to some other influence.

--
Sev

Matt Gregory

unread,
Jul 16, 2004, 12:51:41 PM7/16/04
to
Severian wrote:

> I believe returning TRUE says "I did erase it, so nothing else has to
> worry about it." If you didn't actually do the necessary painting, you
> may have unexpected results.
>
> IIRC, returning TRUE will clear the fErase flag -- which is best as
> long as you have no need to know if you need to erase the background
> in WM_PAINT (such as if you're copying the *entire* window area from a
> bitmap.) But if you need to actually know later if you need to erase
> background areas, I think it's better to return false.

Ah ok. I've never used that flag. I figured if you're erasing in
WM_PAINT, then you're not really using that background feature at all,
but painting the whole window every time or whatever. All I know is, if
you return false from WM_ERASEBKGND, then Windows will erase it, unless
your background brush is null. But if Windows erases the background,
wouldn't the fErase flag always be cleared in WM_PAINT? I would think
if Windows erases the background it would clear the flag.

Matt Gregory

0 new messages