Visual Plugins - something I would like to understand


the other day I spent hours troubleshooting a problem with a WPF Visual Plugin that was not being displayed in a Delphi host.

I finally got it to work, but I do not understand why/how my change ‘fixed’ the problem.

My WPF VisualPlugin implements a custom interface: IPartGridView.

This is the class declaration:

  [Plugin, VisualPlugin, NeedsManagedWrapper(typeof(PartGridVisualPluginWrapper))]
  public partial class PartGridVisualPlugin : IPartGridView
// ...

This following delphi code is what I was originally using to instantiate the Visual-Plugin.
FDotNetPartGrid is a member variable of type: IPartGridView.
The problem was that the WPF control was not displayed at all.

procedure TApmControlPartGrid.BootUp;
  VisualPlugin: IHYVisualPlugin;
  VisualPlugin := TJobUIFactory.CreatePartGridVisualPlugin;
  FDotNetPartGrid := VisualPlugin as IPartGridView;  // FDotNetPartGrid should point to the same object as VisualPlugin, or not???
  FInitialized := False;

As soon as I added FVisualPlugin as a member variable of type IHYVisualPlugin it suddenly worked:

procedure TApmControlPartGrid.BootUp;
  FVisualPlugin := TJobUIFactory.CreatePartGridVisualPlugin; // keep a reference to the Visual Plugin
  FDotNetPartGrid := FVisualPlugin as IPartGridView;
  FInitialized := False;

But this is the part which I do not understand.

Aren’t the FVisualPlugin and the FDotNetPartGrid pointing at the same .NET object?
Does this maybe have something to do with the NeedsManagedWrapper attribute?

Anyhow, it is working just fine now, but I would just like to understand.

Thank you!

Not exactly. At this level you work with COM objects that point to .NET objects and this is a major difference. These casts are not just variable type casts, they also involve COM interface casts.

The wrapper around visual WPF plugin is used/required to provide COM access to that plugin. This is a workaround around some .NET limitations not allowing to directly expose WPF control via COM

Ok. Thanks for the info.

If I understand correctly, performing the COM interface cast in this case, returns a pointer to a different .NET object.

Good to know :slight_smile: