【问题标题】:Controlling a Delphi 7 form from a .NET 4 WinForm application从 .NET 4 WinForm 应用程序控制 Delphi 7 表单
【发布时间】:2011-07-12 21:08:12
【问题描述】:

我有一个 .NET 4 WinForm 应用程序,它显示来自 Delphi 7 .dll 的表单。昨天我有一些关于如何让 Delphi 表单在模态显示时正确运行的问题。已回答here

我从 Delphi .dll 导出一个方法,该方法创建 Delphi 表单的一个实例,将指向该表单的指针返回给 .NET。我还导出了一个方法来显示 Delphi 表单。 Show方法有两个参数:integer类型的owner;和指针类型的形式。

我调用 CreateForm 方法,该方法创建 Delphi 表单,将 Delphi 的 Application 对象传递给表单的构造函数。我将返回的指针存储在 .NET 中。然后我调用 Show 方法,传递来自 .NET 应用程序主窗体的句柄和 Delphi 窗体的指针。

然后我将该句柄分配给 Delphi 的 Application.Handle 属性。

这解决了我原来的问题。

现在我还有一些其他问题:

  • Delphi 表单在 Windows 任务栏上显示一个按钮。到目前为止,我发现抑制任务栏按钮的唯一方法是将 Delphi 表单创建为工具窗口(通过设置表单的 BorderStyle := bsToolWindow 或将 WS_EX_TOOLWINDOW 分配给表单的样式)。我需要 Delphi 表单是一个普通样式的表单,但我不希望工具栏按钮显示,类似于子表单在本机 Delphi 或 .NET 应用程序中的行为方式。本地是指整个应用程序是用给定语言编写的。

  • 当 .NET 应用程序最小化时,Delphi 表单不会最小化。当 .NET 应用程序的主窗体最小化时,我需要 Delphi 窗体最小化,类似于子窗体在本机 Delphi 或 .NET 应用程序中的行为。

我不确定,但这确实像是所有权问题。似乎 Delphi 表单并不“知道”它们是 .NET 应用程序的一部分。

所以我的基本问题是:如何让 Delphi 表单表现得好像它们是应用程序的本机表单?

进一步考虑:我在 Windows 7 上开发,但应用程序也需要在 XP 和 Vista 上表现相同。

【问题讨论】:

    标签: c# .net delphi interop


    【解决方案1】:

    我认为您的很多问题可以通过设置 Delphi 表单的所有者来解决。

    你必须通过 p/invoke 来完成:

    您还需要知道 Delphi 窗口的窗口句柄。

    另外,我认为您可以通过其他更复杂的 p/invoke 方法删除您所说的按钮。有一些方法可以遍历窗口的子窗口,然后您可以将父窗口与按钮分离并销毁它。然而,这有点像 hack,而且很难做到。

    【讨论】:

    • 嗯?为什么这被否决而没有任何评论? +1 补偿。
    • 是的,毫无疑问。真棒,你的名字是 Wouter,对一个说英语的人来说,它让我想起了 WOOT!!!
    【解决方案2】:

    查看我的代码后,我意识到我最初发布的内容并非 100% 正确。在创建 Delphi 表单和分配 Delphi 的 Application.Handle 时,我已经编辑了我的问题以更准确地描述事件序列。

    我通过以下方式解决了这个问题:

    我修改了 CreateForm 方法以接受“所有者”参数,而不是通过 Show 方法传递它。

    在 CreateForm 方法中,我现在首先分配 Delphi 的 Application.Handle 属性,然后创建表单,将 Application 对象传递给表单的构造函数。

    现在应用程序和子表单的行为方式符合我的要求。 Delphi 窗体的任务栏上没有按钮,当 .NET 应用程序的主窗体最小化时,Delphi 窗体消失,并在主窗体恢复时重新出现。

    【讨论】:

      【解决方案3】:

      你可以试试这个:

      public const int GWL_EXSTYLE = -20;

      公共常量 int WS_EX_APPWINDOW = 0x00040000L;

      SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | ~WS_EX_APPWINDOW);

      您可以在 http://pinvoke.net/ 中找到 SetWindowLong 和 GetWindowLong 的 C# p/invoke 定义

      希望这会有所帮助。

      【讨论】:

      • 我想知道为什么有人在这里对答案投反对票而没有留下任何评论。
      • 我得到了你的支持 +1,在我看来这个答案不错。
      猜你喜欢
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 2015-09-21
      • 2011-01-21
      • 1970-01-01
      相关资源
      最近更新 更多