Windows 7 发送不必要的 WM_PAINT 消息

发布于 2024-11-02 06:54:20 字数 879 浏览 6 评论 0原文

我有一个关于发送到我的窗口的奇怪来源的 WM_PAINT 消息的问题。它发生在Windows 7上,但不会发生在Windows XP上。

详细信息

在我的程序中,我有一个触发 GUI 更新的计时器,该计时器基于此 API 调用:

CreateTimerQueueTimer

在系统提供的线程中处理计时器到期,我做了一些 GUI 更新,即,在窗口中画一条线 (0,0)->(57,50)

HDC hdc = GetDC (hwnd);
MoveToEx (hdc, 0, 0, NULL);
LineTo (hdc, 57, 50);
ReleaseDC(hwnd,hdc);

Windows XP 上按我的预期工作,但在 Windows7 上 这使得系统向该窗口发送 WM_PAINT 消息,更新区域为:(0,0,58,51)。请注意,矩形比受线影响的正方形区域宽 1 个像素。

由于这张图而到达的 WM_PAINT 是我不明白的。窗口没有被触摸/重叠/调整大小或其他什么。显然,这条线被系统识别为矩形的无效。

这种情况仅发生在 Windows 7 中(而不是 Windows XP)。

问题

W7 中的 WDM 或窗口处理有什么新内容吗?有什么办法可以避免这种情况吗?

这可能是我的程序或我正在使用的图形工具包(或两者)中的错误。但为什么它只出现在 Windows 7 上呢?

感谢您提供任何线索!

丹尼

I have a question about strangely originating WM_PAINT messages sent to my window. It happens on Windows 7 and doesn’t happen on Windows XP.

Details

In my program, I have a timer that triggers GUI updates, the timer is based on this API call:

CreateTimerQueueTimer

In the thread provided my the system to process timer expiration, I do some GUI updates, namely, drawing a line in the window (0,0)->(57,50):

HDC hdc = GetDC (hwnd);
MoveToEx (hdc, 0, 0, NULL);
LineTo (hdc, 57, 50);
ReleaseDC(hwnd,hdc);

In works as I would expect on Windows XP, but on Windows7 this makes a system to send WM_PAINT message to this window with update region: (0,0,58,51). Notice that rectangle is by one pixel wider than the square area affected by the line.

This WM_PAINT arriving because of this drawing is something that I don’t understand. The window is not touched/overlapped/resized or whatever. Apparently, this line is recognized by the system as invalidation of the rectangle.

And this only happens when in Windows 7 (as opposed to Windows XP).

Question

Is it something new about WDM or windows handling in W7? Any way to avoid this?

It maybe a bug in my program or the graphic toolkit I’m using (or both). But why it only manifests on Windows 7 then?

Thanks for any clue!

Denny

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酷炫老祖宗 2024-11-09 06:54:20

心理调试时间(换句话说,我完全是猜测)...

请记住,您只能从创建窗口的线程更新窗口的内容。如果您从创建窗口的线程以外的线程调用 GetDC()..ReleaseDC() ,我并不奇怪它会导致问题。

Vista/Win7 的计时器 API 与 XP 中的计时器 API 的实现完全不同,您的计时器完全有可能运行在不同的线程上。

为什么不向窗口发布一条消息来指示计时器已触发,而不是在计时器中绘制呢?然后在消息处理程序中,使窗口区域无效。然后在 WM_PAINT 处理程序中处理线条的绘制。

一般来说,如果您在 WM_PAINT 处理程序中的窗口上绘画而不是在其他窗口消息期间绘画,Windows 会更高兴。

Psychic debugging time (in other words, I'm totally guessing)...

Remember that you can only update the content of a window from the thread which created the window. If you're calling GetDC()..ReleaseDC() from a thread other than the thread which created the window, I'm not suprised it's causing problems.

The timer APIs for Vista/Win7 have a totally different implementation from the timer APIs in XP, it's entirely possible that your timer might be running on a different thread.

Instead of drawing in the timer, why not post a message to the window indicating that the timer fired. Then in the message handler, invalidate the region for the window. Then handle drawing the line in the WM_PAINT handler.

In general Windows is much happier if you paint on a window in the WM_PAINT handler instead of painting during other window messages.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文