【问题标题】:Windows 7 sends unnecessary WM_PAINT messagesWindows 7 发送不必要的 WM_PAINT 消息
【发布时间】:2011-04-16 21:53:32
【问题描述】:

我有一个关于奇怪地发送到我的窗口的 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)。请注意,矩形比受线影响的正方形区域宽一个像素。

这个 WM_PAINT 因为这个绘图而到达是我不明白的。窗口没有被触摸/重叠/调整大小等。显然,这条线被系统识别为矩形无效。

而且这只发生在 Windows 7 中(与 Windows XP 不同)。

问题

W7 中的 WDM 或 Windows 处理有什么新东西吗?有什么办法可以避免这种情况?

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

感谢您提供任何线索!

丹尼

【问题讨论】:

    标签: windows-7 wm-paint


    【解决方案1】:

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

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

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

    与其在计时器中绘制,不如向窗口发布一条消息,指示计时器已触发。然后在消息处理程序中,使窗口的区域无效。然后在 WM_PAINT 处理程序中处理画线。

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

    【讨论】:

    • 谢谢。是的,我肯定会从系统提供的任意线程更新 GUI,这很可能不是创建窗口的线程。你能指出它在哪里规定禁止这样做吗?这个关于 GetDC msdn.microsoft.com/en-us/library/dd144871%28VS.85%29.aspx 的页面只声明只有 一个 线程应该在上下文中运行,一旦它被获取。
    • 上面引用的页面中的一些引用:“请注意,DC 的句柄在任何时候只能由单个线程使用... ReleaseDC 必须从调用 GetDC 的同一线程调用"
    • Windows 绑定到创建窗口的线程。您可能能够摆脱从另一个线程与窗口进行交互,但不能保证。您是否尝试过我的建议(将计时器调度回窗口线程)看看是否有帮助?
    • 嗨拉里,我会尝试创建一些简约的应用程序,看看它是否发生。顺便说一句,你到底有什么建议:使用 SetTimer 并在其回调中绘制或在另一个线程中使窗口区域无效并在 WindowProc 中正常处理 WM_PAINT?
    • 任何一个都有效。正如我所说,我不知道这是否是问题所在 - 这是一个随机猜测(我从未尝试从窗口线程外部在窗口上绘画)。
    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 2017-10-06
    • 2018-06-03
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 2012-09-09
    相关资源
    最近更新 更多