0

我正在编写一个工具栏样式的控件,并使用 ThemeServices 单元来绘制工具栏所需的背景。像这样:

ThemeServices.DrawElement(Canvas.Handle, 
  ThemeServices.GetElementDetails(trRebarRoot), ARect);

然后我将子控件放到工具栏上,瞧——即时工具栏。除了时不时地我注意到嵌套(子)控件也不会重新绘制。所以我的控件绘制了它的背景,并且子控件消失了,直到你将鼠标移到它们上面。

一些编辑控件显示它们的客户区(无边框),其中一些完全消失了。

这主要发生在我将另一个应用程序的窗口放在工具栏上并将其移开时。

我一直认为这必须很容易治愈,也许我以某种方式阻止了绘画消息到达子控件,或者错过了覆盖但我一直无法弄清楚。

4

3 回答 3

1

当画布被另一个 Windows 控件覆盖时,必须重新绘制画布是正常的。

您应该在容器控件的 OnPaint 事件中绘制工具栏。

于 2010-03-24T18:38:02.007 回答
1

为了使其正常工作,因此您最终不会从 WM_NCPaint 过度绘制子控件,您可以使用 Window 的 GDI 区域函数创建一个剪切区域,该区域排除您不想绘制的区域。

您可以通过使用具有背景大小的 CreateRectRgn(或类似)函数创建一个区域来做到这一点。

通过 SelectClipRgn 函数将此区域选择到您正在使用的 DC 中。

接下来,遍历工具栏/面板上的顶级子窗口,并为每个子窗口调用 ExcludeClipRect 并使用适当的坐标。

最后,当你绘画时,只有没有被排除的区域才会被绘画。

另请注意,您可能需要清除您的区域(最好查看 GDI 帮助)。

于 2010-03-25T12:46:23.807 回答
0

好的,我自己发现了问题。我在 WM_NCPAINT 中绘制背景,因为它是渐变背景,无法真正一点一点地绘制。我没有意识到 WM_NCPAINT 经常在没有重新绘制客户端控件的情况下被调用。所以我仍然在 WM_NCPAINT 和 WM_PAINT 中绘制背景。后者已经被裁剪以排除边框并让前者裁剪客户区,我称之为ExcludeClipRect。

这就像一种享受。

于 2010-03-25T10:39:49.130 回答