Sharing the goodness…
Beth Massi is a Senior Program Manager on the Visual Studio team at Microsoft and a community champion for .NET developers. Learn more about Beth.
More videos »
I've been heads down this week (re)learning an older technology -- Visual Basic 6! With all the things to focus on like this, this and this you're probably asking "Um, Beth, WHY!?". It's because I've really been learning the Interop Forms Toolkit 2.0 in order to bring you some killer videos on the subject. The Interop Forms Toolkit makes interoperating with .NET forms and user controls from VB6 (and Fox) apps a total snap! I'm really impressed with how easy it is. The toolkit provides a library and code templates that does all the heavy lifting for you so you can concentrate purely on the task at hand. (NOTE: The Interop Forms Toolkit 2.0 is a Visual Studio Add-In and does not run under the Express editions of Visual Studio.)
Why would you want to use it? Well lets say you have a 10 year old Visual Basic (or Visual FoxPro) line-of-business application that needs new features that only .NET can provide, or it's just brain-dead simple in .NET and you're crying because of the effort involved with VB6. Well that's where the toolkit comes in. Instead of converting your entire codebase over to .NET (yea, that'll happen), you can take a phased migration strategy to your application -- even if the application is a monolithic one. This is because the toolkit allows you to seamlessly interoperate between VB6 (COM) and .NET code. .NET controls look like ActiveX controls to VB6.
Let's look at an example. Once you install the toolkit you're ready to start creating .NET control assemblies that can interoperate with VB6. (You can also create complete .NET forms, but the advantage of creating user controls (new to version 2.0 of the toolkit) instead is that they can use RegFree-COM which allows you to deploy your assemblies along with your VB6 exe's via ClickOnce Technology. ) When you create a new project, select the template located under "My Templates" called VB6 Interop User Control which will create a control library that you can interoperate with VB6 applications. This template sets up the proper interop code you need as well as the manifests that enable RegFree-COM.
If we double-click on the InteropUserControl you'll notice some ComClass attributes as well as a region called "VB6 Interop Code".
So I have a VB6 application that we want to extend. For this example it's just a simple form with a grid that pulls up customers from an Access database. A new requirement is to be able to edit the customer details below this grid so we'll extend the VB6 application with a .NET user control. We can easily create this user control in .NET and connect to the same Access database using the drag-and-drop databinding of Visual Studio 2005 as shown in my videos.
Of course this is a very simple example. You are not limited to data-access controls. You have the entire .NET Framework here at your disposal including the BackgroundWorker for multi-threading and .NET Web Services -- things that in VB6 are difficult or impossible to do.
When we design our .NET user control, any public property or method we create on the control will be exposed to VB6. I'll add a public property called CustomerID and in the setter I'll load the customer record from our database. I just create a simple parameterized query (like I did here) on the CustomerTableAdapter that passes the CustomerID.
'Please enter any new code here, below the Interop code
Private m_custID As String
Public Property CustomerID() As String
Set(ByVal value As String)
If m_custID <> value Then
m_custID = value
Private Sub LoadCustomer()
If Me.CustomerID <> "" Then
Now build the solution. In development, this will register your interop user controls into the registry so that you can use them as ActiveX controls in Visual Basic 6. So back in the VB6 IDE, just add a reference to your new components by selecting "Project -- Components" (or Ctrl +T) and selecting your library. This will add the components to the VB6 toolbox.
Then you can drag-and-drop the user control from the toolbox onto the VB6 form. Jump to the code-behind in VB6 and add the code to set the CustomerID on the user control. You get intellisense on the public properties and methods.
Running the VB6 app we can now access our .NET control just like any other control on the form. The interop forms toolkit helper methods even take care of managing tabbing and focusing of the controls for you.
Consider performing a phased migration to your current LOB applications instead of a costly rewrite using the Interop Forms Toolkit 2.0. As you can see it allows you to quickly get .NET functionality into your current applications. Your users will need the .NET framework installed on their machines and the .NET user control assemblies registered, however with RegFree-COM and ClickOnce Deployment, these issues can be easily solved.
Are you saying that you are hosting the .NET user control you built with the toolkit in Access not VB6? This sounds like an unsupported use of the Interop toolkit but I'm not clear how your hosting this.
The interop toolkit helps expose the .NET user control to COM, like an ActiveX control. I'm not familiar with how the Access design environment works with these but the same principles should apply.
Yes, I'm hosting a .net interop control in Access (it's COM based). After some experimenting, I found that just the intellisnse isn't suppored in the Access environment. You need to know what the properties or methods names are in the vba code as they do in fact work.
Second questions regards deploying a control to the client machine. I'd like to use an xcopy approach along with a batch file and not use any msi's. All the doc's I find talk about using the MSI's and boot strappers. Can you point me to any doc's that might be useful?
You'll need to register the assembly for COM interop into the registry (you treat this like any other COM component). So the MSI approach is the easiest because it will automatically pick that up. Here's a video on how to distribute interop controls:
Otherwise you can register it manually using the regasm utility:
I've installed the component on the client machine using the msi and using regasm, and it appears that out of the box the interop forms tool kit doesn't support resizing of a user control through the Microsoft Access designer. In fact, it doesn't appear to be possible to resize a user control through code in this environment. I've scoured the internet looking for solutions and haven't come across anything that resolves this. It's too bad since I think deploying .net controls and using them in a legacy application has a lot of potential. We could use the forms approach, but the downfall of that approach in an Access MDI applicaiton is that the .net forms doesn't know anything about the MDI container, which get's confusing for end users.
What we we're really wanting to leverage in .net is the ability to manipulate images in memory and use some of the appropriate controls like sliders to adjust contrast, brightness and even rotate an image, someting which isn't possible using the office controls.
Looks like we'll have to use a interop dll to manipulate the image and leave the presenation to Access/VBA.
I mentioned what you're trying to do to the team and like I thought you're pretty much outside of the supported scenarios of the interop forms toolkit. It's really meant for VB6 legacy applications and was never tested with the Access design environment.
Unfortunately I don't have any experience with the Access design environment, just databases. Maybe you could ask someone it the forums if they are using the toolkit this way.
i have the same Problem with invalid Pointer.
This is the second time that i have this Problem. I develop my code in VB2008 and build it. When i open the VB6 Form where i placed the control i become this error. There is no error wth other controls. Last time i deleted this control an made a new one. But this is not realy fine to do this.
i think i found an error in the interop toolkit behaviour. I hope you can help me.
I have an example Project with a single InteropUserControl (a Windows Forms Button) which is embedded on vb6 form.
The Button is doing the following in his click event:
double b = double.MinValue;
double c = b - 100;
In the vb6 form i have a timer which is doing the following calculation
Dim a As Single
Dim b As Single
Dim c As Single
a = 5
b = 3
c = a / b
When the interop button is clicked, the vb6 application crashes with an error (runtime error 6: overflow) while accessing one of the single values.
It seems that the overflow on the .NET side of the interop is leading to an overflow on the vb6 side, the next time a single variable is accessed.
Is there anything i can do about? I already tried to read the fpu registers, because it seems that the exceptions are somehow not masked on the .NET side, but found nothing.