为什么不手动发送WM_PAINT
why not to send WM_PAINT manually
我读到过,我不应该手动发送WM_PAINT
,而应该调用InvalidateRect
,但是没有发现任何原因。为什么不呢?
update对InvalidateRect
有效,但对SendMessage(WM_PAINT)
无效
LRESULT CALLBACK window_proc(HWND wnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
switch (msg)
{
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(wnd, &ps);
Polyline(..);
EndPaint(wnd, &ps);
return 0;
case WM_USER:
// SendMessage(wnd, WM_PAINT, NULL, NULL);
// InvalidateRect(wnd, NULL, FALSE);
return 0;
}
}
WM_PAINT
的官方文档在备注部分的第一句话就指出不应该这样做。说真的,这应该是一个足够的理由不。
至于技术原因,我想这是其中之一,摘自BeginPaint
评论部分:
更新区域由InvalidateRect或InvalidateRgn函数设置,并由系统在调整大小、移动、创建、滚动或任何其他影响客户端区域的操作后设置。
因此,如果您手动发送WM_PAINT
, BeginPaint
可能无法正常工作。
可能有更多的原因/惊喜
如果您想立即触发重新绘制,正确的方法是:
-
使用
InvalidateRect()
+UpdateWindow()
-
使用
RedrawWindow()
这些将触发新的WM_PAINT
消息生成
您没有任何关于其他程序的窗口的信息。只有操作系统有这个信息。所以你真的不知道你的窗户何时何地需要重新粉刷。WM_PAINT和BeginPaint提供了这些缺失的信息
因为WM_PAINT
不是真正的消息
想象一下,每个窗口都有一个存储"无效区域"的结构,也就是说,"屏幕上窗口的这一部分不再是最新的,需要重新绘制"。
无效区域由窗口管理器自己修改(窗口大小调整,覆盖等),或通过调用InvalidateRect
, ValidateRect
, EndPaint
等。
现在,这里是GetMessage
如何处理这个的粗略模型:
... GetMessage(MSG* msg, ...)
{
while(true) {
if(ThereIsAnyMessageInTheMessageQueue()) {
*msg = GetFirstMessageOfTheMessageQueue();
return ...;
} else if(TheInvalidRegionIsNotEmpty()) {
*msg = CreateWMPaintMessage();
return ...;
} else {
WaitUntilSomethingHappend();
}
}
}
tl;dr: WM_PAINT
表示接收,而不是发送。
- "WM" C++是什么意思?
- 如何访问委托的paint()函数中的另一个索引?
- 直接在QlistView上绘制小部件,并使用QStyleDitemdelegate :: Paint()
- QT4:在所有qgraphicsItem上的单个qgraphictem rapers paint()上的update()
- 什么是窗口最大化/最小化/恢复的WM Windows消息
- Qt. 方法显示文本() 如果我在 QStyledItemDelegate 中定义了 paint() 方法不起作用
- 如何在我的子类控件paint方法中在默认的paint结果之上绘制一些东西
- 请求X11在C或C++中合成WM的图像
- Qt QTableView paint() 事件无限期交付,占用 100% 的 CPU 内核
- Paint QPushButton with QLinearGradient
- Paint Job Estimator C++
- Q即使宽度和高度都为非零,也不调用ridget paint
- Qt paint事件崩溃
- 如何使用插槽实时更新paint()
- paint函数中的QStyleOptionViewItem参数-如何处理它
- 除非先使用MS Paint打开/保存文件,否则带有QRCode位图的LoadImage()将失败
- 如何将使用Qt Paint Application绘制的图像传输到Mat openCV
- OpenGL新手,致力于"paint"程序
- 如果在WM/CE平台中用于卸载,DMProcessConfigXML将关闭正在运行的应用程序
- 重写QGraphicsItem的paint()和mouseEvents()