WM_SETREDRAW并丢失z-order / focus

时间:2012-02-12 11:54:07

标签: .net winapi

我有一个带有蒙皮库(Devexpress)和MDI父窗体的.NET应用程序。

当我添加子表单时,出于性能原因,我使用 WM_SETREDRAW 来禁用绘制。

但是,在将 WM_SETREDRAW 再次设置为1并在MDI父级上调用刷新后,主窗体将丢失其z顺序并位于桌面背景上。

然后我必须调用 BringToFront 焦点,但仍有一段短暂的时间段(<1s),我的应用程序会为用户“消失”。

是否有更好的方法可以禁用重绘但保持表单可见?

1 个答案:

答案 0 :(得分:3)

我怀疑问题来自the documentation中的这句话:

  

如果应用程序将WM_SETREDRAW消息发送到隐藏窗口,则该窗口变为可见(即,操作系统将WS_VISIBLE样式添加到窗口中。)

由于a hidden window is effectively disabled(尽管它仍然可以处理消息,但它无法接收用户输入),这会导致您违反启用和禁用窗口的正确顺序。当当前聚焦的窗口被禁用(因此失去焦点)时,焦点必须某处,因为它不可能无处可去。

很难说完全在没有看到代码的情况下发生了什么。我也不完全确定你是否将WM_SETREDRAW消息发送给MDI父母或MDI孩子。但是我可以说剥皮库因为搞砸事情并导致噩梦般的错误而臭名昭着。问问自己,你是否真的需要这样的事情,以及它是否真的值得挣扎。

我还要质疑潜在的动机:

  

当我添加子表单时,出于性能原因,我使用WM_SETREDRAW来禁用绘制。

添加子表单时不应该有任何绘制或性能问题,假设您在表单的构造函数中进行了所有初始化,而不是其他方法。这样可以确保在显示表单之前正确初始化所有内容,并且不需要进行多次重绘。所有内容都被绘制一次,第一次显示表单,这与WM_SETREDRAW的理想情况完全相同:在启用重绘后,它只被绘制一次。