WPF host application

Hey guys,

I’m wondering if I can build a wpf-host application with a delphi non-visual plugin?
I just found some samples of winForm hosts or vcl-hosts.

CU
mts

Yes you can, you need to reference two assemblies: RemObjects.Hydra and RemObjects.Hydra.Host. Then you can create an instance of the ModuleManager and use it to load Delphi module.

Thanks! I was able to load a delphi plugin in a wpf host-application.

wpf-side looks like this:

public partial class MainWindow : Window
{
    private ModuleManager mm = new ModuleManager();
    private IMessageProcessor _mp = null;

    public MainWindow()
    {
        IHYCrossPlatformPlugin cpp;

        InitializeComponent();

        LoadedModule module = mm.LoadModule(@"E:\Repository Git\TestProjekte\HydraTest\HydraTestPlugin.dll");
        cpp = mm.CreateInstance("TestNonVisualPlugin");

        if (cpp is IMessageProcessor)
            _mp = cpp as IMessageProcessor;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        _mp.ProcessMessage("huhu");
    }

Now I want to access host-interfaces by the plugin. Unfortunately the onSetHost-Event gets never fired. Is there anything I have to do first? I was referring to this documentation: remobjects wiki but I can’t find any hint.

Thanks!

You need to create a custom host object and the assign it to a module manager, for example:

public class CustomHost: IHYCrossPlatformHost, IYourOwnInterface
{
  //Impementation
}

 //Before LoadModule call
moduleManager.Host = new CustomHost();

This will trigger OnSetHost event inside a plugin and you will be able to access host interface.

Thanks again :slight_smile:

onSetHost gets fired now and the host variable is set but I cannot get my custom interface:

  if host.QueryInterface(IMessageProcessor, mp) = S_OK then
    mp.ProcessMessage('Test 123'); 

here is my interface implementation which works in the other direction:

[Guid("ba57d377-f0e6-464d-8521-62035dea4bdc")]
public interface IMessageProcessor : RemObjects.Hydra.CrossPlatform.IHYCrossPlatformInterface {
    void ProcessMessage(string Message);
}

or the delphi equivalent:

  IMessageProcessor = interface(IHYCrossPlatformInterface)
  ['{BA57D377-F0E6-464D-8521-62035DEA4BDC}']
    procedure ProcessMessage(const Message: WideString); safecall;
  end;

Two possible problems:

  1. Check if your host is COM visible - in the AssemblyInfo.cs following assembly attribute must be set to true:
    [assembly: ComVisible(true)]

  2. What object implements IHYCrossPlatformHost interface? By default WPF blocks COM interop, so if you implemented this interfce in your host main Window class it won’t be accessible from plugin. You need to create a separate non-WPF class or alternatively create a proxy class that will act as a host object and forward calls from plugin to your Window.

Hey guys. Sorry for my late reply but I had to work on other projects.
Today I came back to my hydra-Project and I’m still having the this problem.

What I did:

  • created a class as host:

     class SolderBotHydraHost : IHYCrossPlatformHost, IGUIcommands
     {
    
         public int MsgDlg(string text, TMSGTYPE msgType, TMSGBUTTON Buttons)
         {
             MessageBox.Show("Test");
             return 1;
         }
     }
    
  • set [assembly: ComVisible(true)] in AssemblyInfo.cs

  • initialize plugin:

    _mm.Host = new SolderBotHydraHost();
    LoadedModule module = _mm.LoadModule(@“libSolderBot.dll”);
    IHYCrossPlatformPlugin cpp = _mm.CreateInstance(“SolderBotNonVisualPlugin”);

Delphi:

procedure TSolderBotNVPlugin.HYNonVisualPluginSetHost(const Sender: IHYHostAware; const aHost: IHYHost);
begin
  if aHost.QueryInterface(IGUIcommands, _GUI) <> S_OK then
    _GUI := nil;   <<-- QueyrInterface does not find IGUIcommands
end;

Anything else I’m missing here?

Try to make your SolderBotHydraHost class public.

public class SolderBotHydraHost : IHYCrossPlatformHost, IGUIcommands
{
[...]

Thanks! It’s working now.