2
votes

I have a .NET 4 WinForm application that displays forms from a Delphi 7 .dll. I had some questions yesterday about how to get the Delphi form to behave correctly when shown modally. That was answered here.

I export a method from the Delphi .dll that creates an instance of the Delphi form, returning a pointer to that form to .NET. I also export a method to show the Delphi form. The Show method two parameters: owner of type integer; and form of type Pointer.

I call the CreateForm method, which creates the Delphi form, passing Delphi's Application object to the form's constructor. I store the returned pointer in .NET. I then call the Show method, passing the handle from the .NET application's main form and the pointer for the Delphi form.

I then assign that handle to Delphi's Application.Handle property.

This solved my original issue.

Now I have some other issues:

  • The Delphi form shows a button on the Windows taskbar. The only way that I have found so far to suppress the taskbar button is to create the Delphi form as a tool window (either through setting the forms's BorderStyle := bsToolWindow or assigning WS_EX_TOOLWINDOW to the form's style). I need the Delphi form to be a normal style form, but I don't want the toolbar button to show, similar to how child forms behave in a native Delphi or .NET app. And by native I mean where the entire application is written in the given language.

  • The Delphi form does not minimize when the .NET application is minimized. I need the Delphi form(s) to minimize when the .NET application's main form is minimized, similar to how child forms behave in a native Delphi or .NET app.

I'm not sure, but this does feel like an ownership issue. It seems that Delphi forms don't "know" that they are part of the .NET application.

So my basic question is: How do I get the Delphi forms to behave as though they were native forms of the application?

Further considerations: I am developing on Windows 7, but the application needs to behave the same on XP and Vista, as well.

3

3 Answers

1
votes

I think there are alot of your issues that would be solved by setting the owner of the Delphi forms.

You'll have to do it through p/invoke:

You'll also need to know the window handle of your Delphi windows.

Also, I think you could remove the button you speak of by other, more complicated p/invoke methods. There are methods to loop through child windows of a window, then you can detach the parent window from the button and destroy it. This is quite a bit of a hack and would be hard to get right, however.

1
votes

After reviewing my code, I realized that what I had originally posted was not 100% correct. I have edited my question to give a more accurate description of the sequence of events when creating the Delphi form and assigning Delphi's Application.Handle.

I have solved the issue by doing the following:

I modified the CreateForm method to accept the "owner" parameter, instead of passing it through the Show method.

In the CreateForm method I now assign Delphi's Application.Handle property first, then create the form, passing the Application object to the form's constructor.

Now the application and child forms behave the way that I want. No buttons on the taskbar for the Delphi forms, and the Delphi forms disappear when the .NET application's main form is minimized, and reappear when the main form is restored.

1
votes

You could try this:

public const int GWL_EXSTYLE = -20;

public const int WS_EX_APPWINDOW = 0x00040000L;

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

You can find C# p/invoke definitions for SetWindowLong and GetWindowLong in http://pinvoke.net/

Hope this helps.