由 SetParent API 创建的 MDI 子项的重画问题
我有一个用 C 编写的遗留应用程序,它由一个主窗口和几个从菜单选项打开的 mdi 子窗口组成。为了允许用 C# 编写新的 mdi 子项,我创建了一个 C++ COM 互操作层,该层由 C 代码调用,进而调用 C# 代码。然后,我使用 SetParent API 将 C 主窗口设置为任何打开的 C# 窗口的新父窗口。这似乎有效 - C# 窗口的行为就像主窗口的 MDI 子窗口。但是,子窗口无法正确绘制,并且如果您将其他窗口移到它上面或将其移动到主窗口的边缘,只会变得更糟 - 它会被其他窗口的一部分绘制,或者在移动时留下自身的一些部分。此外,屏幕响应不太好,例如您无法从一个文本框切换到另一个文本框。
请不要质疑我的解决方案的架构(相信我,这是唯一的方法),但如果您曾经遇到过由 SetParent 创建的孩子出现这样的问题,我很想知道您是否设法解决它。
I have a legacy app written in C that consists of a main window and several mdi children opened from menu options. To allow new mdi children to be written in C# I have created a C++ COM interop layer that is called by the C code and in turn calls the C# code. I then use the SetParent API to set the C main window as the new parent of any C# window opened. This seems to work - the C# window behaves like an MDI child of the main window. BUT, the child window does not paint properly and only gets worse if you move other windows over it or move it to the edges of the main window - it gets painted with parts of the other windows or leaves bits of itself lying around as it moves. In addition the screen doesn't respond very well eg you cannot tab from one textbox to another.
Please don't question the architecture of my solution (believe me, this is the only way), but if you've ever seen a problem like this with a child created by SetParent I'd love to hear if you managed to fix it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请尝试以下操作:
在出现问题时通常运行的处理循环内添加 Application.DoEvents。
尝试从主窗体的绘制事件中刷新 MDI 窗体。
Try these things:
Add Application.DoEvents inside a processing loop that is normally running when things go bad.
Try refreshing the MDI forms from within the main form's paint event.
我不完全理解 SetParent() 是如何工作的;话虽这么说,这里还有一些需要考虑的事情:
在 SetParent 文档,来自 Microsoft 的 Chango V. 补充道:“需要调用
SetWindowPos(SWP_FRAMECHANGED)
在 null 和非 null 父级之间更改时。”另外,您确定您确实正在运行 .NET Form 消息循环吗?您是否调用了
Application.Run(yourManagedForm)
,或者您是否在 C 代码中运行自己的消息循环?如果您正在运行自己的消息循环,则可能需要将消息转发到WndProc
方法.windows.forms.control.preprocessmessage.aspx" rel="nofollow">PreProcessMessage
。您需要向它们公开一个接口,因为它们受到保护。但我不知道这有多有效。I don't totally understand how SetParent() works; that being said, here's some more things to consider:
In the MSDN community content of the SetParent documentation, Chango V. from Microsoft added that you: "need to call
SetWindowPos(SWP_FRAMECHANGED)
when changing between null and non-null parent."Also, are you sure you are actually running the .NET Form message loop? Did you call
Application.Run(yourManagedForm)
, or are you running your own message loop in the C code? If you're running your own message loop, you may need to forward messages to theWndProc
method on your managed form after filtering it throughPreProcessMessage
. You would need to expose an interface to these as they are protected. I don't know how valid this is, though.