open a window. open a second window and make it frontmost. now drag the
second window around such that redraws in the first window are triggered.
the problem: even if you've overriden WM_ERASEBKGND and returned 1, even if
you've set the background brush of the window class to NULL, *something* uses
the background brush (or COLOR_WINDOW if it's NULL) to fill the area needing
redraw apparently just before either WM_ERASEBKGND or WM_PAINT have been
called. This will be true for *each* redraw event needed.
I've included code to reproduce this (this example code is based on petzold's
hellowin program). The code below shows that even though the WM_ERASEBKGND
message is handled, and WM_PAINT is set to do nothing, the bright blue that
is set as the background brush *is* used in the scenario described above, and
i believe *only* in the scenario described above. in windows 95 w/active
sizing redraw, the background brush color is never seen, as it should be.
has anyone else observed this. is it a bug or just different implementation
and required for some reason with the active sizing redraw?
you can modify the example code to paint in a random color for the background
and see the ugly flashing effect that way by uncommenting the line that
contains "*** uncomment" (no quotes). this ugly flashing effect was what
prompted me to look into this in the first place.
note also 1) the effect is not found when redraws are due to actively resizing
either the window itself or the second window in front of it when it's in the
background, and 2) the background brush is not used very well as you still end
up with portions of the window that are *not* painted in that color.
#include <windows.h>
#include <time.h>
#include <assert.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HBRUSH hbrBg = NULL;
static char szAppName[] = "HelloWin" ;
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
srand( time( NULL ) );
hbrBg = CreateSolidBrush( 0x00FFFF00 );
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = 0 ;
//wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = hbrBg ;
//wndclass.hbrBackground = (HBRUSH)(COLOR_MENUTEXT+1);
//wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
//wndclass.hbrBackground = NULL ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindow (szAppName, // window class name
"The Hello Program", // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
HBRUSH hbr;
COLORREF cr;
int t;
switch (iMsg)
{
case WM_CREATE :
return 0 ;
case WM_ERASEBKGND :
//return 1;
hdc = (HDC) wParam;
t = GetClipBox( hdc, &rect );
assert( t );
cr = rand();
hbr = CreateSolidBrush( cr );
assert( hbr );
/*** uncomment next line to see w/bg being painted ***/
//t = FillRect( hdc, &rect, hbr );
assert( t );
DeleteObject( hbr );
return 1;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
In article <35ff42d2.2446609949@msnews-gw>,
raym...@microsoft.com.--- (Raymond Chen) wrote:
> During "high speed" painting, as happens during full window drag,
> USER will do "quick erasing". It first tries the window
> background brush, and if that doesn't work, it just uses some
> generic background brush.
>
> Remember that WM_PAINT is a low-priority message, so you don't
> get a real WM_PAINT until things settle down.
>
> The reason for this is that USER wants to keep the full window
> drag responsive, so it doesn't send WM_PAINT messages until
> things go quiet.
understood, but (and much thanks for the response btw, you are *exactly* the
person i was hoping would respond!) why can't it just do **nothing** in the
client area of my window until the WM_PAINT and/or WM_ERASEBKGND arrive?
Wouldn't that allow the drag to be even *more* responsive?? and wouldn't
that get rid of the ugly flashing that is the whole point of my post? Doing
nothing in this scenario is exactly what Windows 95 appears to do. Moreover,
that's exactly what Windows NT itself does when instead of moving the front
window the user is resizing it, an activity which could certainly also be
considered similarly "high speed drawing", particularly when the resize
entails a "corner" resize where both x and y dimensions are changing
simultaneously, in which case the "high speed" desired for the operation
seems to me to be *almost identical* to the high speed desired for the move.
Which shows that Windows NT is *not even consistent.* if it's such a good
thing to guess at how my window wants to paint itself, why not guess when
sizing too?
(note to readers: i've included slightly modified code below that shows the
ugly flashing. on a fast machine, you can still see it plainly, but you may
have to have a few other non-trivial windows, e.g. a couple web browsers, also
up on the desktop.)
it's obviously a bad thing to do this guessing, because it creates unnecessary
flashing, which is the real subject of this thread. This flashing makes NT
apps look stupid in my opinion. I would never have thought this **ugly
flashing is built into the OS** until I looked into this myself.
Plus, it would seem that if NT feels a need to do a "quick erase," which
again doesn't seem particularly necessary to me and apparently is not
considered necessary in Windows 95 ever when moving/sizing or again in
Windows NT when sizing a front window rather than moving it, why not allow
the programmer to do that quick erasing via, um, well, the WM_ERASEBKGND
message that is the subject of this message and whose entire purpose seems to
be to do a "quick erase"!? I anticipate your response on this will be on
thread issues... which i accept, so back to square one, why not do
*nothing*??
>If it sent WM_PAINT messages aggresively, the
I'm certainly not saying it should send WM_PAINT messages more aggressively
and bog the whole system down. this would be absurd. i'm saying that its
behavior creates an absolutely unnecessary *ugly flashing* effect which can
be gotten rid of simply by it doing nothing instead of *guessing* how my
client area should be painted. if it really wanted to send something more
aggressively, it would obviously make more sense to send the WM_ERASEBKGND
message, but again, my opinion is that it should do nothing rather than
guessing at how my window should be drawn.
> full window drag would get reaaaaaaly slow when you dragged over
> an application that paints slowly
>
> Set your window class background brush to something boring that
> won't clash with your window.
>
ugly flashing should not be built into the os.
> >i believe *only* in the scenario described above. in windows 95 w/active
> >sizing redraw, the background brush color is never seen, as it should be.
>
> Windows 95 will also do this "emergency" painting, but less
> frequently.
>
apparently, but i don't really see why the system *ever* does this emergency
painting. even if an application is hung, seeing its client area not
painting itself seems to communicate this just as well as seeing its client
area painted in a color selected by windows nt.
-- Paul
CODE WHICH SHOWS UGLY FLASHING:
/***
turn on "show window contents while dragging option".
TO REPRODUCE UGLY FLASHING,
1) run this program
2) open up a couple other windows, e.g. web browsers.
3) open up another window of some sort and bring
it to the front.
4) now move that frontmost window around such that
redraws are caused in all three other windows.
you should see flashes of light blue before the blue
is painted.
5) now instead of moving the frontmost window, resize
it from a corner and again, drag around such that
redraws in all windows again are needed. note that
the redraw requirements and speed requirements
are virtually the same in this case as in the
move case. note the lack of flashing b/c Windows
NT in this case doesn't intervene and try to paint
the client area for no particular reason.
***/
RegisterClassEx (&wndclass) ;
cr = 0x00FF0000;
hbr = CreateSolidBrush( cr );
assert( hbr );
t = FillRect( hdc, &rect, hbr );
assert( t );
DeleteObject( hbr );
On Win95, we only do this fill if the app has been hung for a LONG time
(like several seconds). The reason you want to do this is because
after a certain threshold it impacts usability as some stale bits look a
lot ike a running app, and the user starts clcking around on what looks
like a button or a menu or...
So to defend Raymond, Win95 really does have a reason to paint over the
window but basically it is at the point where we have decided that the
app is totally out to lunch.
If you really want to, you can get around even this. Set your class
brush to a hollow brush (not a NULL handle, see GetStockObject). Even
though we will still 'paint' your update region, we'll be doing so in a
brush that doesn't change any pixels onscreen :)
-f
Thanks very much for looking at this issue.
Thanks.
Ben
Paul...@my-dejanews.com wrote:
> In article <4588-36...@newsd-223.iap.bryant.webtv.net>,
> fran...@webtv.net (Francis Hogle) wrote:
> > Well you've found a chink in the armor. This is something we'll
> look
> > into fixing in a future release of NT.
> > [...]
>
> Thanks very much for looking at this issue.
>
Old posts can be looked up at www.dejanews.com or www.reference.com