【发布时间】:2013-06-06 20:32:01
【问题描述】:
让我首先描述问题的症状。然后,我将提供更多事实并解释我的问题。
症状
我编写了一个自定义 Windows 控件。控件绘制自己以响应 WM_PAINT 消息。它还使用跟踪工具提示(即TOOLTIPS_CLASS公共控件的跟踪功能)。
当我将鼠标拖到控件上时,工具提示很好地跟随鼠标。 问题是它会留下一条灰色的条纹。重绘此条纹需要相当长的时间 - 正如您从所附图像中看到的那样,我能够在控件有时间重绘之前点击 PRNTSCRN 并对其进行截图。
(更奇怪的是WM_PAINT 处理程序似乎没有运行一次。但请注意,导致工具提示跟踪的代码在WM_MOUSEMOVE 中,这显然是反应灵敏。)
事实
- 请假设 vanilla C 使用 Win32 库。
-
WM_PAINT处理程序实际上非常快。该控件具有许多需要重新绘制整个客户区的功能,而这对用户来说是察觉不到的。- 确实,某些功能运行的动画会以 15-24 fps 的速度重新绘制整个客户区。
- 它的效率也相当高,并且不会比任何给定重绘时的更新矩形更多地重绘。
-
WM_ERASEBKGND处理程序什么都不做,只返回 1。- 我从不擦除背景,我只是在它上面画画。
- 窗口设置了以下样式位:
- ws:
WS_CHILD | WS_VISIBLE - 例如:
WS_EX_COMPOSITED - cs:
CS_DBLCLKS
- ws:
- 父窗口是一个顶级窗口,设置了以下样式位:
- ws:
WS_TILEDWINDOW | WS_CLIPSIBLINGS | WS_VISIBLE - 例如:
WS_EX_WINDOWEDGE - cs:
CS_REDRAW | CS_DBLCLKS
- ws:
- 控件的窗口类背景画笔为
GetStockObject(NULL_BRUSH)。 - 我发现导致相同类型“跟踪”的唯一其他方法是将另一个顶级窗口拖到我的控件上。被拖动的顶层窗口暂时遮住的区域会留下相同的轨迹。
- 为控件的窗口类赋予
CS_SAVEBITS样式似乎没有任何区别。我仍然得到同样明显的缓慢重绘痕迹。
问题
- 为什么我会得到灰色,尤其是如果我设置了
CS_SAVEBITS? - 我该怎么做才能让灰色消失?
- 是否应该在每次移动工具提示时调用
UpdateWindow()?- 但这并不能解决其他顶级窗口被拖到我的控件之上的问题。
- 救命!
- 是否应该在每次移动工具提示时调用
【问题讨论】:
-
问题似乎是Windows正在向父顶级窗口发送
WM_ERASEBKGND消息,而没有向子控制窗口发送任何相应的WM_PAINT消息。如果我削弱了父母WM_ERASEBKGND处理程序(通过返回 1 而不做任何事情)滞后绘制问题就会消失,但窗口背景也无法绘制!如何让 Windows 告诉子控件绘画!? -
注意:起初我认为问题与the lagging update region issue described here 有关(请参阅标题“全拖动”),但该解决方案没有帮助。
标签: c windows winapi gdi win32gui