有什么新希望吗?把窗户当作MDI孩子

时间:2009-02-24 14:21:04

标签: c# winforms mdi

可以通过Winforms MDI应用程序中Winform上的C#控件或PowerBuilder MDI应用程序通过COM使用的相同C#控件调用一些C#表单/控件。

我一直在使用WinAPI调用SetParent将表单附加到MDI。

  1. 它在两种环境中都有效(或似乎)。
  2. 它允许子窗口拥有自己的WindowState(Normal,Maximized),而不是接受已经打开的子窗口(这真的很痛苦)。
  3. 假设控件被称为T.控件T上的代码调用表格D.

    控制T在表格X上 控制T也在Y形式上。

    在.Net中一切都很好,表格D保持在MDI内。

    PB中的


    控制T在PB控制PX上。 控制T也在PB控制PY上。

    对于PX一切都很好 然而,对于PY,存在一个问题 - 表单D似乎不会成为MDI孩子 - 它可以在应用程序之外并且具有任务栏图标。我强调这是使用相同的对象和那些工作的对象。 SetParent实际上是相同的代码行。

    进一步的研究表明,SetParent不会真正为正确的MDI childing工作 - 但是没关系(ish)我们不需要合并菜单等。

    有趣的是,已经发现尽管SetParent似乎“工作”,但是如果你尝试使用GetParent,你就不会得到回复...

    Form form = new MyForm();
    WindowsMessageHelper.SetParent(form.Handle, MDIParentHandle); //passed down 
    int parentHandle = WindowsMessageHelper.GetParent(form.Handle);
    

    parentHandle将始终为0 ....

    在任何情况下,有没有办法让表格D表现出来?我自己的研究并不乐观。我真的不想回去重写我的表单作为控件并让PowerBuilder管理它们 - 主要是因为每个表单可能有多个实例而PowerBuilder必须处理它(而不是控制器类/基类我是在.net app中做到了。)

    我可以强调.Net中没有问题,问题只出现在PowerBuilder应用程序中

3 个答案:

答案 0 :(得分:1)

最后,我们发现不同之处在于PB正在为控件PX(调用表格D的工作)设置.MDIParent,而不是PY。

一旦对它进行了排序,那么我们就得到了正确的MDIParent句柄,现在一切都很好了。

答案 1 :(得分:0)

您的孩子需要成为System.Windows.Forms.Form,并将其MdiParent属性设置为MDI Patent窗口(而不是其父级)。

容器也需要遵循一些规则。

阅读MDI instructions on MSDN可能会有所帮助。


选项二:您可能无法使用单个控件执行此操作。 Instad考虑在两个包装器中组成核心实现。第一个包装器充当WinForms MDI子节点,第二个包装器作为COM包装器,在PowerBuilder工作的任何GUI框架下使用。

答案 2 :(得分:0)

如果您尚未解决的唯一问题是GetParent不起作用,您可能能够使用它。

编辑:但提问者有更多问题。

有许多API戳必须依次完成才能使其工作。通过COM接口或将.NET MDI子项放在.NET MDI父级中时,您可以更轻松地将其作为用户控件并将其放在本机MDI父级上。

必须在此处使用不同的基本窗口过程(DefWindowProc与DefMdiChildProc),并使这项工作最终实现DefMdiChildProc。

如果你使用.NET反射器,你或许可以找到一种方法让System.Windows.Forms.Form为你调用DefMdiChildProc。