WPF plugins and host windows

Hello,

I’m looking for a sutable strategy for legacy VCL Delphi application migration. The goal is to gradually migrate it to .NET stack (C#, WPF), and it seems that Hydra is one of the best tools for this.
The main constraint on the task is that all the UI and UX have to be strictly preserved during the migration. Due to application’s huge size and complexity, the only acceptable way to do the job is by migrating a couple of Delphi forms per iteration.

I’ve checked the WPF plugin sample and read the documentation but still have some questions. The main point that I wish to clarify is the relationships of WPF visual plugins and VCL host application windows.

So to begin with - as stated in this article: https://docs.hydra4.com/Plugins/WPFVisualPlugins/, “The visual plugin is the control that you will use to embed into the host application…”. Also I can see that link for the article “Showing visual plugins in a separate window” has been removed from the docs (the bottom link here - https://docs.hydra4.com/HowTos/).
Does this mean that WPF visual plugin can only be a user control inside the host window and not a separate window or a dialog on it’s own?

Thanks!

Hello

That link was more related to Silverlight plugins. Now the Silverlight platform is pretty much dead, so we’ll remove this link.

Sure you can display separate windows from plugin. However in this case it might be easier to create a non-visual plugin and to expose methods that will display separate forms and return gathered data back to the host application.
At the same time the Visual plugin cannot be displayed on its own. Just as a TPanel cannot be displayed on its own and always needs a hosting window.

Also need to note that a single Hydra plugin project can contain multiple plugins (visual and non-visual). So you don’t need to create a separate project and to ship a separate .dll for each plugin form you’ll create - they all can be bundled into a single .dll.

Regards

Can I ask you for a sample of this kind please?

One thing to note about the UI of this legacy application is that it heavily uses nested modal dialogs and the nesting level can be quite large.

Suppose we have five nested modal dialogs for example, d1->d2->d3->d4->d5, and only d2 is migrated to a WPF dialog. I’m just not sure about parent-child window relationships, hotkeys and modal windows. Does Hydra provide any help in this kind of host-plugin integration? Or maybe you can give me some useful advices on the topic? Or I just use standard windowing mechanisms native to WPF and Delphi, maybe passing windows handles around for setting parent-child, and it works?

Thanks!

I’d suggest to let d2 be a Delphi dialog that hosts WPF control. This way you;ll have WPF GUI and it won’t take long to control WPF window plugin into a standalone WPF window once the rest of the d2 -> … d5 chain is converted to WPF.

Indeed it is possible to obtain WPF window’s handle and to pass it to Delphi host to set it a child or a host window.

Anyway both approaches will come down to instantiating a plugin and to providing it some callbacks to talk to the host.

Take a look at this sample: HostEventTriggering.zip (13.4 KB)

This is a Delphi window that loads a WPF content. Pressing button displayed on the WPF pane triggers an action in the host Delphi app and displays a Message Box.

Note the Plugin2Wrapper class in this sample. I is required because WPF controls by themselves do not like interoperability that much. So if a custom interface (IInterfaceThatHasEvents in this case) has to be exposed by the WPF plugin then a custom wrapper class is required.

This is exactly the way I’m thinking about at the moment. One thing that worries me in this scenario is where the buttons controlling the dialog lifetime should be placed in.

If they would reside in Delphi dialog window then it’s likely to cause problems with handling focus change and maybe other low-level windows events in the WPF user control, wich in turn would cause problems in WPF binding on loosing focus for example.
Or if they would be placed in the WPF user control than it seems to cause problems with proper closing the Delphi dialog.

In other words I suppose that moving the whole dialog’s gui including it’s Ok-Apply-Cancel buttons to WPF user control and leaving the modal dialog window itsefl in Delphi form would not work properly.
The same seems about leaving Ok-Apply-Cancel buttons in the Delphi dialog and moving all other controls to the WPF user control.
Or am I wrong about this?

Thank you! Yes it seems that Hydra greatly simplifies two-way interactions between the host and the plugin, and that custom interfaces is Hydra’s killer feature.

Well, you could define callbacks (or even a single callback that will notify the host dialog that a button was pressed and will pass some code for the pressed button (like 1 for OK, 2 for Cancel etc)).

Then in the callback just set the dialog’s ModalResult to some value to close it. Don’t forget to properly release the plugin instance to avoid memory leaks.

Side note: For performance reasons it is better to load WPF plugins into the default .NET AppDomain (there is a corresponding option in the Hydra Module Manager)

1 Like

Thanks, this seems the way way to do it.

Ok, got it. Thanks!