.net - WM_SETREDRAW 并丢失 z 顺序/焦点

标签 .net winapi

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

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

但是,再次将 WM_SETREDRAW 设置为 1 并在 MDI 父级上调用 refresh 后,主窗体会丢失其 z 顺序并出现在我桌面的背景上。

然后我必须调用 BringToFrontFocus,但仍然有很短的时间段(<1s),在此期间我的应用程序对用户来说“消失”。

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

最佳答案

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

If the application sends the WM_SETREDRAW message to a hidden window, the window becomes visible (that is, the operating system adds the WS_VISIBLE style to the window).

a hidden window is effectively disabled (虽然它仍然可以处理消息,但它无法接收用户输入),这会导致您与启用和禁用窗口的正确顺序发生冲突。当当前聚焦的窗口被禁用(并因此失去焦点)时,焦点必须移动到某个地方,因为它不可能无处不在。

在没有看到代码的情况下,很难准确地说出您的情况发生了什么。从您的问题中我也不能完全确定您是将 WM_SETREDRAW 消息发送给 MDI 父级还是 MDI 子级。但我可以说,换肤库因把事情搞砸并导致噩梦般的错误而臭名昭著。首先问问自己是否真的需要这样的东西,以及是否真的值得为此奋斗。

我还必须质疑潜在的动机:

When I add child forms, I use WM_SETREDRAW to disable painting for performance reasons.

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

关于.net - WM_SETREDRAW 并丢失 z 顺序/焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9248553/

相关文章:

c++ - 使用 glDrawArrays() 的绘制函数需要调用两次才能显示任何内容

c# - 小巧玲珑,带有 SIMPLECrud : GetList with WHERE behaving like LIKE instead of =

.net - 使用具有模型优先方法的 EF4 迁移工具

c# - 事件触发前的对象处理和垃圾收集

Windows 事件内存转储

c++ - 在进程范围上设置ThreadLocale

.Net 安全区域权限集?

c# - 如何检查 c#.net 应用程序中所有静态对象的内存使用情况

winapi - 如何以编程方式操作 DLGTEMPLATE?

c++ - WM_HOTKEY 可以用来模拟热键事件吗?