Is there a way to pass an OCX control reference out from a Visual Basic 6 activeX dll via COM interop?

3.1k views Asked by At

I stumbled upon this while trying to build an ActiveX dll from an old (but still maintained) VB6 exe project(*) sources in order to perform some testing via COM / NET interop.

The (desired) use case is:

  1. Take a VB6 class with public methods taking or returning some control (for example CommonDialog) reference
  2. Compile this class into an ActiveX dll
  3. Create an instance of this class via COM interop from .NET and correctly call its methods

In short, the first problem is that having something like

Public Function bad_dlg() As CommonDialog
   Set bad_dlg = Nothing
End Function

in a Visual Basic 6 ActiveX dll's class file makes the compilation (* *) fail with the following error:

"Private object modules cannot be used in public object modules as parameters or return types for public procedures, as public data members, or as fields of public user defined types"

Hence, the question is:

  1. Is it really impossible to have something like above compile and run properly?
  2. [IF NOT] Suppose, I change everything to return and receive instances of VB6 Object type -- how can I work with such an instance from .Net (call specific methods, etc)

(*) -- not an ActiveX exe, just an "ordinary" one

(* *) provided that appropriate .ocx ("Microsoft Common Dialog Control 6.0 (SP6)", C:\Windows\system32\ComDlg32.OCX) is referenced

(* * *) the only one that I have found is Passing control Ref to dll

2

There are 2 answers

2
mlvljr On BEST ANSWER

(As for the 1st part of the question)

The Microsoft documentation (Data Types Allowed in Properties and Methods ) states:

On the Evils of Returning Private Objects

The following data types are not allowed, and references to them should never be returned to client applications:

  • All of the objects provided in the Visual Basic (VB) object library — for example, controls. Use the Object Browser to view the entire list.

  • All forms.

  • All class modules whose Instancing property is set to Private.

  • References to ActiveX controls.

Visual Basic prevents you from passing non-visual private objects to or from out-of-process components. Attempting to do so causes error 98, "A property or method call cannot include a reference to a private object, either as an argument or as a return value." This error is always received by the client.

...

IMPORTANT

  • Private objects are private for a reason, usually because they were not designed to be used outside your project. Passing them to a client may decrease program stability and cause incompatibility with future versions of Visual Basic. If you need to pass a private class of your own to a client, set the Instancing property to a value other than Private.

[Deatails follow]

3
Kris Erickson On

Can't help you with 1, but 2 should be possible in DotNet 4.0 with the dynamic keyword.