I'm porting an old Visual Basic 6 program. I deployed the migrated component in WPF and provide that component as an ActiveX control (C#, Windows Forms, .NET Framework) to add the control temporarily (to break the porting process into smaller parts) in the VB6 application.
This works great if the external ActiveX control is added in VB6 to the whole form like
Private Sub Form_Load()
Set mCtrl = Controls.Add("ActiveX_Control.UserControl1", "UserControl1", Me)
Set mActiveX = mCtrl.object
mCtrl.Visible = True
End Sub
But if I add the control to a container (Picture1 = picture box), the control will be automatically deactivate (if the .NET control loose the focus):
Private Sub Form_Load()
Set mCtrl = Controls.Add("ActiveX_Control.UserControl1", "UserControl1", Picture1)
Set mActiveX = mCtrl.object
mCtrl.Visible = True
End Sub
I learned that the interface IOleInPlaceObject is responsible for this behaviour. Also about the C# interface ICustomQueryInterface. Therefore I suppress the interface at runtime with this knowledge:
public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr ppv)
{
if (iid == typeof(IOleInPlaceObject).GUID)
{
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.Failed;
}
ppv = IntPtr.Zero;
return CustomQueryInterfaceResult.NotHandled;
}
This seems to work, but the new problem is that now the ActiveX control doesn't got automatically the focus if pressing TAB key (last control in VB6 before the ActiveX control).
Is that even the right way? Is there a better way? Maybe via a different return value from IOleObject::GetMiscStatus of the ActiveX control?
The sample C# and VB6 project you can download here.