Ok, Ok, I know what you’re asking yourself right now.
WTF would you want to do this?
But bare with me.
Realistically speaking, VB6 has a very limited shelf life. I have plenty of VB6 apps that run just fine under Win7 (even 64 bit), but Under Win8? Who knows.
But, the truth is, there are plenty of businesses that rely on WinXP and VB6 apps today, and those businesses aren’t converting those apps to .net (or anything else) particularly quickly.
As it happens, I’m currently doing some maintenance and upgrade work on a VB6 application, and, while it IS a 10+ year old IDE, it does have it niceties and not-so-niceties.
CodeSmart, MZTools, CodeHelper, and other add-ins can certainly help, but one thing I’ve definitely missed now that I’ve worked with VS2005+ is persistent bookmarks and breakpoints.
That fact that VB6 didn’t save bookmark and breakpoint locations is a real shame.
Now, people have asked about this capability for years. I found posts going back to 2001 asking for this function, but the only utility that even came close was the open source CodeDawg project. And while I still have the source here, I can no longer even locate a link for it on the web. No matter, really, because it never did work particularly well, would miss breakpoints or bookmarks that you set sometimes, and just generally had a terribly interface.
But it was a valiant attempt!
Fast forward to today, and I’m back in VB6, working in a large and not particularly straightforward codebase, and I find myself really needing bookmarks and breakpoints that I can set and come back to the next day or whenever.
But .net provides so much simpler coding paradigms for many things now (generic collections, and direct support for subclassing anyone!) that after a few days working up a prototype add-in in VB6, I couldn’t stand it and had to see if it was possible to put something together in .net.
That’s right. A VB6 addin written in VB.net 2010!
It’s not quite finished yet, so I’ll hold off on presenting the full monty for now, but it most certainly is doable, and actually makes for a quite nice development and debugging experience.
First, fire up VS2010 and create a DLL Library project.
In the project properties, you’ll need to make sure to check the “Make assembly COM visible”
Next, On the compile tab, you need to set “Register for COM Interop”
You’ll also need to add a reference to the VBIDE.DLL file:
You can usually find the file under the COM tab on the Add Reference screen:
Finally, create a new CLASS, call it Connect, and paste this:
<ComClass("96861C1E-73A0-46E2-9993-AE66D2BC6A91", "1AEA0235-959D-4424-8231-8EBB9B9C85FE")> _ <ProgId("BookmarkSave.Connect")> _ Public Class Connect Implements VBIDE.IDTExtensibility Private _App As Application Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements VBIDE.IDTExtensibility.OnAddInsUpdate _App.OnAddInsUpdate(custom) End Sub Public Sub OnConnection(VBInst As Object, ConnectMode As VBIDE.vbext_ConnectMode, AddInInst As VBIDE.AddIn, ByRef custom As System.Array) Implements VBIDE.IDTExtensibility.OnConnection Try If _App Is Nothing Then _App = New Application End If _App.OnConnection(VBInst, ConnectMode, custom) Catch ex As Exception ex.Show("Unable to start addin.") End Try End Sub Public Sub OnDisconnection(RemoveMode As VBIDE.vbext_DisconnectMode, ByRef custom As System.Array) Implements VBIDE.IDTExtensibility.OnDisconnection _App.OnDisconnect(RemoveMode, custom) End Sub Public Sub OnStartupComplete(ByRef custom As System.Array) Implements VBIDE.IDTExtensibility.OnStartupComplete _App.OnStartupComplete(custom) End Sub End Class
Now to explain a few things.
The two GUIDs you see in the first COMCLASS line, you’ll need to generate your own unique id’s for them.
Obviously, the ProgID will also need to be changed (the general convention is {addin-name.Connect}).
The Application object is my actual core addin application. I’ve intentionally kept all the addin’s code OUT of the Connect class, to keep it simple, and because this class MUST be made visible to COM so that VB6 itself can instantiate the CONNECT object (and thus kickstart your addin). Usually, the less “stuff” you have to expose to COM in a .net assembly, the better, and this represents the bare minimum.
To make debugging seamless, be sure to set the Debug Start Action to “Start External Program” and point it at your VB6.EXE file:
You’ll also need to make sure your addin is registered with VB6, so it will know to load it along with any other addins. You do that by creating a key like the “BookmarkSave.Connect” key below:
Be sure to change the “BookmarkSave.Connect” to whatever ProgID you’ve decided on.
Give it a whirl
With all that in place, you should be able to RUN your addin from VS2010, VB6 should start and your addin CONNECT object’s OnConnection method should be called.
Now it’s time to pull out my Duran Duran and SoundGarden discs and get to coding some good ol’ fashioned pseudo-OO VB6 goodness!
2 Comments
I tried this addin with Excel vba. But it didn’t work. Can you suggest me on how to make it work for excel vba as well ?
Hi, Thanks for the question, but I doubt this technique would work in that scenario. This is specifically about creating VB6 IDE plugins. Even though the Excel VBA stuff is very similar to VB6, it’s not the same, unfortunately.