我有一个具有以下Windows层次结构的应用程序:
W1
-W2 (Child of W1)
- W3 ( Child of W2)
--------------------|
| W1|------------| |
| |W2 |------| | |
| | |W3 | | |
| | |------| | |
| |------------| |
|-------------------|
当W2中发生某些事件时,我呼叫
UpdateWindow
:W2::onCertainEvent()
{
Invalidate(NULL);
UpdateWindow();
}
W2的
OnPaint
处理如下所示: W2::onPaint()
{
//W2 logic goes here
W3.Invalidate(NULL); //So that paint messages are given to W3
}
但是有时在W2中迷失了绘画信息。尽管
UpdateWindow
被调用,但没有相应的OnPaint
()被调用。如果我向W1(W2的父级)添加属性
WS_EX_TRANSPARENT
,则总是在W2处收到绘画消息。但是添加
WS_EX_TRANSPARENT
标志的问题在于,当我调整窗口W1的大小时,它会产生很多闪烁。我的问题是:
1.在W2中有什么问题导致Paint消息丢失?
2.为什么添加
WS_EX_TRANSPARENT
解决了Paint问题。3.如果使用了标志,如何解决闪烁问题。
谢谢,
最佳答案
闪烁
可以通过传递WM_ERASEBKGND
并确保不执行任何操作来解决闪烁。之所以会发生闪烁,是因为每个窗口在使用其背景色擦除每种无效区域之前,都会先处理此消息。如果您处理它并且什么也不做,则不会发生擦除-只需确保您的WM_PAINT
处理程序绘制整个无效区域,否则您将留下先前绘制的伪像。
但是,在这种情况下,我相信会发生闪烁,因为W1会先绘制自身,然后再绘制W2,然后再绘制W3。这表明WS_EX_TRANSPARENT
不能解决您遇到的问题。
缺少WM_PAINT
很难知道如何进行追踪。在.NET中,发生这种情况是因为子窗口遮盖了控件的整个客户端区域,因此绘制消息不会通过传播,但是我相信这是特定的.NET行为。如果您可以提供一个示例项目或示例代码来解决问题,那将是一个很大的帮助。
同时,您可以删除W3,以便不会遮挡W2,然后查看是否所有的绘制消息都返回了。另外,请注意,CWnd::Invalidate
不会将NULL作为选项,而是会使用BOOL
(TRUE
或FALSE
)。
关于c++ - 为什么即使调用UpdateWindow()后绘画消息也会丢失?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2207433/