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

InvalidateRect() not Causing WM_PAINT Message.

1,164 views
Skip to first unread message

Larry Lindstrom

unread,
Aug 16, 2006, 4:07:38 PM8/16/06
to
Hi Folks:

Developing with Win2K, VC6, WIN32, no MFC.

I'm writing code that manipulates rectangles in a grid.

Yesterday, I could left click the corner of a rectangle,
move the corner, and the rectangle would resize as the corner
was moved, until the left mouse button was released.

That is the behavior I want.

Today the rectangle doesn't change size until I release
the left mouse button. It then snaps into position as I
want.

That is not the behavior I want. The user should see the
size of the rectangle as it changes.

I don't understand why the rectangle is no longer being
resized as the user moves the mouse.

I've put breakpoints in the WM_MOUSEMOVE trap and the
call to InvalidateRect() is being made with proper arguments
for the window handle and rectangle.

The breakpoint in the WM_PAINT trap isn't called as a
result of these InvalidateRect() calls.

Any ideas?

Thanks
Larry

ken

unread,
Aug 17, 2006, 6:04:28 PM8/17/06
to
I'm a windows programming newbie so please take my advice with a grain
of salt. I've been triggering WM_PAINT messages by using the
RedrawWindow function with a Rect pointer indicating the area I want to
be invalidated. Not sure how that differs from InvalidateRect.
ie:
RedrawWindow(hwnd, &rc, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE);

Perhaps if you add that to your WM_MOUSEMOVE block it will send WM_PAINT
messages with each mouse movement.

Good luck!
Ken

Larry Lindstrom

unread,
Aug 18, 2006, 3:18:00 AM8/18/06
to
ken wrote:
> I'm a windows programming newbie so please take my advice with a grain
> of salt. I've been triggering WM_PAINT messages by using the
> RedrawWindow function with a Rect pointer indicating the area I want to
> be invalidated. Not sure how that differs from InvalidateRect.
> ie:
> RedrawWindow(hwnd, &rc, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE);
>
> Perhaps if you add that to your WM_MOUSEMOVE block it will send WM_PAINT
> messages with each mouse movement.
>
> Good luck!

Thanks Ken:

I feel like a newbie sometimes. I'm a Unix programmer
developing with Windows development for over 2 years.

RedrawWindow() looks like an interesting function for invalidating
regious. I've never seen it before. For invalidating rectangles, I
think I'll stick to InvalidateRect().

The problem turns out to be a bug that caused SetCursorPos()
to be called continuously. I'm guessing there were so many
WM_MOUSELEAVE messages that WM_PAINT was never queued up.

I appreciate your advice.

Thanks
Larry


Jerry Coffin

unread,
Aug 18, 2006, 12:27:37 PM8/18/06
to
In article <POOdndmMr57p93jZ...@comcast.com>,
nob...@aracnet.com says...

[ ... ]

> The problem turns out to be a bug that caused SetCursorPos()
> to be called continuously. I'm guessing there were so many
> WM_MOUSELEAVE messages that WM_PAINT was never queued up.

It probably doesn't make a whole lot of difference, but just in case you
care: WM_PAINT isn't normally queued up at all.

Instead, the window manager code has a bit (called QS_PAINT) that says
whether the window has at least some invalid area (it also has a rect to
tell what area is invalid). When/if you call GetMessage and there's
nothing waiting in the message queue, it checks that bit and if it's
set, it synthesizes a WM_PAINT message for you to receive.

When you call InvalidateRect, it doesn't (directly) cause a WM_PAINT
message to be put in the queue -- it simply sets the QS_PAINT flag, and
adds your rectangle to the invalid rectangle for the window. Nothing
else happens until you call GetMessage and there are no messages in the
queue.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Larry Lindstrom

unread,
Aug 18, 2006, 1:47:25 PM8/18/06
to
Jerry Coffin wrote:
> In article <POOdndmMr57p93jZ...@comcast.com>,
> nob...@aracnet.com says...
>
> [ ... ]
>
>> The problem turns out to be a bug that caused SetCursorPos()
>> to be called continuously. I'm guessing there were so many
>> WM_MOUSELEAVE messages that WM_PAINT was never queued up.

Thanks Jerry:

That should have been WM_MOUSEMOVE.

> It probably doesn't make a whole lot of difference, but just in case you
> care: WM_PAINT isn't normally queued up at all.
>
> Instead, the window manager code has a bit (called QS_PAINT) that says
> whether the window has at least some invalid area (it also has a rect to
> tell what area is invalid). When/if you call GetMessage and there's
> nothing waiting in the message queue, it checks that bit and if it's
> set, it synthesizes a WM_PAINT message for you to receive.

Thanks Jerry:

So a non-stop flood of SetCursorPos() calls stuffed the
queue with WM_MOUSEMOVE messages, so there was never a time
when the queue was empty and the WM_PAINT would be synthesized.

That makes sense.

> When you call InvalidateRect, it doesn't (directly) cause a WM_PAINT
> message to be put in the queue -- it simply sets the QS_PAINT flag, and
> adds your rectangle to the invalid rectangle for the window. Nothing
> else happens until you call GetMessage and there are no messages in the
> queue.
>

Thanks
Larry

Jerry Coffin

unread,
Aug 18, 2006, 3:00:27 PM8/18/06
to
In article <KJCdnUO5U7hkYHjZ...@comcast.com>,
nob...@aracnet.com says...

[ ... ]

> Thanks Jerry:

Surely.

> So a non-stop flood of SetCursorPos() calls stuffed the
> queue with WM_MOUSEMOVE messages, so there was never a time
> when the queue was empty and the WM_PAINT would be synthesized.

Yup, that sounds about right.

0 new messages