1

获得了一些 C# 窗体/控件,可以从 Winforms MDI 应用程序中 Winform 上的 C# 控件或 PowerBuilder MDI 应用程序通过 COM 使用的相同 C# 控件调用。

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

  1. 它在两种环境中都有效(或似乎有效)。
  2. 它让子窗口拥有自己的 WindowState(正常,最大化),而不是承担已经打开的子窗口的状态(这真的很痛苦)。

假设控件称为 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 应用程序中进行操作)。

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

4

3 回答 3

1

最后,我们发现不同之处在于 PB 相当于为控制 PX 设置了 .MDIParent(调用表格 D 起作用的那个),而不是为 PY 设置 .MDIParent。

排序后,我们就得到了正确的 MDIParent 句柄,现在一切都很好。

于 2009-02-25T17:08:56.673 回答
0

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

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

通读MSDN 上的 MDI 说明可能会有所帮助。


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

于 2009-02-24T18:05:58.667 回答
0

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

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

有许多 API poke 必须依次完成才能完成这项工作。当通过 COM 接口使用它时,将其作为用户控件并将其放置在本机 MDI 父级上或将其放置在 .NET MDI 父级中时,将其放置在 .NET MDI 子级上时,您将更容易将其设置为用户控件。

此处必须使用不同的基本窗口过程(DefWindowProc 与 DefMdiChildProc),为了完成这项工作,您最终需要实现 DefMdiChildProc。

如果您使用 .NET 反射器,您可能会找到一种方法来使 System.Windows.Forms.Form 为您调用 DefMdiChildProc。

于 2009-02-24T18:21:19.800 回答