50

当我想重绘一个窗口时,在 InvalidateRect 和 RedrawWindow 之间是否有任何首选函数可以调用?

例如,这两个调用是否相等:(win 将是 HWND)
RedrawWindow(win, NULL, NULL, RDW_INVALIDATE);
InvalidateRect(win, NULL, NULL);

主要问题:我什么时候应该使用其中一个?背景中是否存在任何差异?(不同的 WM_messages / 焦点 / 顺序 / 优先级..)

我想重绘窗口的原因是因为我向它发送了一个我希望它显示的新图像,这意味着窗口的内容不再有效。

4

4 回答 4

60

InvalidateRect不会立即重绘窗口。它只是为窗口的特定矩形区域“安排”未来重绘。使用InvalidateRect您可以根据需要安排尽可能多的区域,使它们累积在一些内部缓冲区中。所有累积的预定区域的实际重绘将在稍后进行,此时窗口无事可做。(当然,如果在您发出InvalidateRect调用时窗口处于空闲状态,则将立即进行重绘)。

您还可以通过调用强制立即重绘所有当前累积的无效区域UpdateWindow。但是,同样,如果您不着急,UpdateWindow则不需要显式调用,因为一旦窗口空闲,它将自动对所有当前无效的区域执行重绘。

RedrawWindow另一方面,它是一个功能更广泛、更灵活的功能。它可以用来执行失效调度(即做同样的事情InvalidateRect),也可以用来强制执行指定区域的立即重绘,而不做任何“调度”。在后一种情况下,调用RedrawWindow实际上等同于调用InvalidateRect然后立即调用UpdateWindow

于 2010-02-24T17:24:07.553 回答
21

RedrawWindow(win, NULL, NULL, RDW_INVALIDATE);并且InvalidateRect(win, NULL, NULL);是等价的。这两个函数都使窗口无效。在这WM_PAINT两种情况下都发生在正常时间(应用程序队列中没有其他消息)。

如果您希望立即完成绘制,则调用其中一个RedrawWindow(win, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW)InvalidateRect后跟一个UpdateWindow将执行此操作。

RedrawWindow只需使用 RDW_* 位提供更多选项。如果您只想在没有立即绘制的情况下使窗口无效,那么调用InvalidateRect似乎更干净。

于 2012-11-27T18:58:12.940 回答
1

我不喜欢只提供链接,但 MSDN 为您提供了您需要的所有信息,在这里重新输入所有信息是浪费时间。

重绘窗口

无效矩形

简而言之,是的,存在差异。问题是,为什么要重绘窗口?是因为内容不再有效吗?如果是,则使用InvalidateRect,否则使用RedrawWindow

于 2010-02-24T12:51:01.617 回答
1

RedrawWindow 立即重新绘制窗口。InvalidateRect 仅标记要在下一个 WM_PAINT 消息上重新绘制的窗口。但是 WM_PAINT 消息的优先级低于其他消息,因此如果您的应用正忙于处理其他消息,则不会立即重新绘制。

于 2010-02-24T17:14:46.837 回答