Slugsie
Slugsie

Reputation: 905

Calling VB6 forms from .Net COM DLL?

We have a very large application that is written in VB6. It has hundreds of forms/user controls/classes etc. We have started migrating to .Net (currently on framework v2, although just about to change that to v4) with a COM exposed DLL by converting individual forms on an 'as and when' basis. This is all working just fine so far.

Some of the more complex VB6 forms call multiple other forms, which call forms etc etc, so conversion is a bottom up process. There are several instances where it would make life easier in the short term if we could call a VB6 form from the .Net DLL, perhaps by passing some form of object reference to the form into .Net. Although I'm pretty sure this isn't possible, I want to check to be certain.

So, is this possible?

Upvotes: 3

Views: 1550

Answers (2)

tcarvin
tcarvin

Reputation: 10855

I don't know how clean your code is, so take this with a few grains of salt. But here is a a rough outline in pseudo-code (and vastly simplified) of the approach I would take:

In a shared library, exposed to both .NET and COM define an interface for each of your forms:

public interface ILoginForm
   property UserName as String 
   property Password as String
   function DisplayModal as Boolean 'True for login, false for cancel...or expose an enum
end interface

public interface IContactEditor
   property FirstName as String
   property LastName as String
   property EmailAddress as String
   function DisplayModal as Boolean 'True for save, false for cancel...or expose an enum
end interface

etc, etc for each form in your application.

Next, define a FormFactory interface:

public interface IFormFactory
   function CreateLoginForm as ILoginForm
   function CreateContactEditorForm as IContactEditor
end interface

If you like to cahce your forms, then you could chnage the interface a bit to match that use-case.

Next, in your VB6 EXE, you should implement the IFormFactory interface:

Class FormFactory Implements IFormFactory 

   public function IFormFactory_CreateLoginForm as ILoginForm
      'let's say this form is still in VB6
      Dim frm As frmLoginPage
      Set frm = new frmLoginPage
      Set IFormFactory_CreateLoginForm = frm
   end function

   public function IFormFactory_CreateContactEditorForm  as IContactEditor
      'let's say this form is in .NET
      Dim frm As DotNetLib.ContactEditorDialog
      Set frm = new DotNetLib.ContactEditorDialog
      Set IFormFactory_CreateContactEditorForm  = frm
   end function

Throughout your VB6 app, have all form creation pass through this singleton:

Dim contactEditor as IContactEditor
Set contactEditor = modSingletons.FormFactory.CreateContactEditorForm()
contactEditor.FirstName = "Joe" 'seed with initial values
contactEditor.LastName = "Blow"
contactEditor.EmailAddress = "bubblegum@something.net"
Dim saved As Boolean
saved = contactEditor.DisplayModal()
if saved then
   'read the new values back out and write to DB or whatever
end if

If you do this correctly, your main EXE should not even be aware if the forms are in .NET or VB6, you just switch them out as you go in the Factory.

Finally, you setup the same thing in the .NET lib. Create a COM exposed singleton that the VB6 exe can pass the IFormFactory instance into the .NET library. Then your .NET code can use the factory instance to invoke any form in your app.

Alternatively, you could pass the factory instance on every call into a form (to allow that form to access any other forms), but I would not do it that way. The reason for this is because there very likely are even more services aside from Form creation that you will want to start migrating over. You'd be better served with setting up a bunch of interfaces for your various application services and injecting all of them into the .NET library in a similar manner. Eventually everything will be in .NET, but your code will not need to change since it is using interfaces.

Upvotes: 2

MarkJ
MarkJ

Reputation: 30408

We've called VB6 forms from a .Net EXE by referencing a Vb6 DLL from the EXE, it works. I think the same approach should work from a .Net DLL. If you want the VB6 form to be non-modal, you have to use a VB6 ActiveX EXE instead.

A piecemeal approach to migration is a good idea. Divide the application into manageable chunks, and migrate each chunk separately.

Upvotes: 2

Related Questions