SetParent API 创建的 MDI 子重绘问题

Posted

技术标签:

【中文标题】SetParent API 创建的 MDI 子重绘问题【英文标题】:Repainting problem with MDI child created by SetParent API 【发布时间】:2011-06-13 06:38:29 【问题描述】:

我有一个用 C 语言编写的遗留应用程序,它由一个主窗口和几个从菜单选项打开的 mdi 子窗口组成。为了允许用 C# 编写新的 mdi 子级,我创建了一个 C++ COM 互操作层,该层由 C 代码调用,然后调用 C# 代码。然后,我使用 SetParent API 将 C 主窗口设置为打开的任何 C# 窗口的新父级。这似乎可行 - C# 窗口的行为类似于主窗口的 MDI 子窗口。但是,子窗口不能正确绘制,如果您将其他窗口移到它上面或将其移动到主窗口的边缘,它只会变得更糟 - 它会被其他窗口的一部分绘制或在移动时留下一些自身的碎片.此外,屏幕响应不佳,例如您无法从一个文本框切换到另一个文本框。

请不要质疑我的解决方案的架构(相信我,这是唯一的方法),但如果您曾经遇到过由 SetParent 创建的孩子的此类问题,我很想听听您是否管理修复它。

【问题讨论】:

+1 对于措辞清晰的问题。然而,“这是唯一的方法”往往是不正确的。 ;) 欢迎来到 SO 公平点!我只是想继续关注这个问题,因为我已经尝试并排除了一些“其他方式”。 【参考方案1】:

试试这些:

    在处理循环中添加 Application.DoEvents,当出现问题时该循环通常会运行。

    尝试从主窗体的绘制事件中刷新 MDI 窗体。

【讨论】:

1 - 不高兴,恐怕。 2 - 不是一个选项,唉。主窗体代码是由 4GL 生成的(我知道,我知道),这限制了代码中的可能性。但我感谢您的回应。【参考方案2】:

我不完全理解 SetParent() 的工作原理;话虽如此,这里还有一些需要考虑的事情:


在the SetParent documentation的MSDN社区内容中,来自微软的Chango V.补充说:“在null和non-null parent之间切换时需要调用SetWindowPos(SWP_FRAMECHANGED)。”


另外,您确定您确实在运行 .NET Form 消息循环吗?您是调用Application.Run(yourManagedForm),还是在C 代码中运行自己的消息循环?如果您正在运行自己的消息循环,您可能需要在通过PreProcessMessage 过滤后将消息转发到托管表单上的WndProc 方法。您需要向它们公开一个接口,因为它们受到保护。不过,我不知道这有多有效。

【讨论】:

SWP_FRAMECHANGED 看起来很有希望,但不幸的是并没有解决我的问题。嗯,消息循环 - 一位同事建议这可能是问题的核心。我不确定我想进入这个......但无论如何谢谢。

以上是关于SetParent API 创建的 MDI 子重绘问题的主要内容,如果未能解决你的问题,请参考以下文章

WPF 使用SetParent嵌套窗口

WPF 使用SetParent嵌套窗口

Google Maps API 重绘地理编码界限

使用 SetParent 冻结父窗口

MDI 窗口的创建

调用 setParent 时 QMenu 显示不正确