我有一个.NET 4 WinForm应用程序,它显示Delphi 7 .dll中的表单。昨天我有一些问题,关于如何在模态显示时使Delphi表单正常运行。回答here。
我从Delphi .dll导出一个方法,该方法创建Delphi表单的实例,并将指向该表单的指针返回给.NET。我还导出一个方法来显示Delphi表单。 Show方法有两个参数:所有者类型为整数;和指针类型的形式。
我调用CreateForm方法,它创建Delphi表单,将Delphi的Application对象传递给表单的构造函数。我将返回的指针存储在.NET中。然后我调用Show方法,从.NET应用程序的主窗体传递句柄和Delphi窗体的指针。
然后我将该句柄分配给Delphi的Application.Handle
属性。
这解决了我原来的问题。
现在我还有其他一些问题:
Delphi表单在Windows任务栏上显示一个按钮。到目前为止,我发现压缩任务栏按钮的唯一方法是将Delphi表单创建为工具窗口(通过设置表单的BorderStyle := bsToolWindow
或将WS_EX_TOOLWINDOW
指定给表单的样式)。我需要将Delphi表单作为普通样式表单,但我不希望显示工具栏按钮,类似于子表单在本机Delphi或.NET应用程序中的行为方式。原则上我的意思是整个应用程序都是用给定的语言编写的。
当.NET应用程序最小化时,Delphi表单不会最小化。我需要使用Delphi表单来最小化.NET应用程序的主窗体最小化的时间,类似于子窗体在本机Delphi或.NET应用程序中的行为方式。
我不确定,但这确实感觉像是一个所有权问题。似乎Delphi表单并不“知道”它们是.NET应用程序的一部分。
所以我的基本问题是:如何使Delphi表单表现得好像它们是应用程序的本机形式?
进一步的考虑:我在Windows 7上开发,但应用程序在XP和Vista上也需要表现相同。
答案 0 :(得分:1)
我认为通过设置Delphi表单的所有者可以解决很多问题。
你必须通过p / invoke来实现:
您还需要知道Delphi窗口的窗口句柄。
另外,我认为您可以通过其他更复杂的p / invoke方法删除您所说的按钮。有循环窗口的子窗口的方法,然后您可以从按钮分离父窗口并销毁它。然而,这有点像黑客并且很难做到。
答案 1 :(得分:1)
在查看我的代码之后,我意识到我最初发布的内容并非100%正确。我编辑了我的问题,以便在创建Delphi表单和分配Delphi的Application.Handle时更准确地描述事件序列。
我通过以下方式解决了这个问题:
我修改了CreateForm方法以接受“owner”参数,而不是通过Show方法传递它。
在CreateForm方法中,我现在首先分配Delphi的Application.Handle属性, 然后 创建表单,将Application对象传递给表单的构造函数。
现在应用程序和子表单的行为方式与我想要的一样。 Delphi窗体的任务栏上没有按钮,当.NET应用程序的主窗体最小化时Delphi窗体消失,并在主窗体恢复时重新出现。
答案 2 :(得分:1)
你可以试试这个:
public const int GWL_EXSTYLE = -20;
public const int WS_EX_APPWINDOW = 0x00040000L;
SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE)| ~WS_EX_APPWINDOW);
中找到SetWindowLong和GetWindowLong的C#p / invoke定义希望这有帮助。