HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Shared VB6 *and* VBA extensibility add-in with OnConnect and OnDisconnect handling

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
handlingsharedwithvb6ondisconnectextensibilityvbaandaddonconnect

Problem

Rubberduck works well enough when the VBE is of the VBA variety, but it currently only works when the Rubberduck is configured to load at VBA start-up, and it has a tendency to crash the host application or fail to shutdown when exiting. There's a number of outstanding issues around being able to load Rubberduck after the IDE is already loaded, and to unload Rubberduck without closing the IDE.

There's also a number of requests for adding the ability to work with VB5/VB6. While VB and VBA both have VBIDE libraries that are very similar, and they both support the IDTExtensibility2 interface, they are not interchangeable.

I've relied heavily on the MZ Tools documentation of Carlos Quintero of MZ-Tools, and the Microsoft documentation in coming up with a bare-bones solution that attempts to:

  • Allow for the add-in to be loaded/unloaded as the user requires.



  • Allow for the add-in to work under VB5/VB6 and 32/64-bit VBA.



I've created my own interop assemblies for the respective VBEs:

  • VB6's VBIDE - Fubaa.Interop.VB6Ext



  • VBA's VBIDE - Fubaa.Interop.VBA6Ext



Connect.cs

```
using Extensibility;
using Fubaa.Interop.VB6Ext;
using Fubaa.Interop.VBA6Ext;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyAddin
{
[ComVisible(true)]
[Guid(ClassId)]
[ProgId(ProgId)]
public class Connect : IDTExtensibility2
{
private const string ClassId = "506EC676-068F-497D-BEBB-B8EE42A34573";
private const string ProgId = "MyAddin.Connect";

private IVBE _vbe;
private object _Addin;

private bool isLoaded;

public void OnAddInsUpdate(ref Array custom)
{
Debug.WriteLine("Begin Event: OnAddInsUpdate");
Debug.WriteLine(" Addin is Loaded:" + isLoaded.ToString());
Debug.WriteLine("End Event: OnAddInsUpdate"

Solution

OnConnection and OnStartupComplete

I can forsee a problem arising. Assume the addin is started with ext_ConnectMode.ext_cm_AfterStartup then in the OnConnection() handler you are calling DoInit(). Afterwards the OnStartComplete() handler will be called and you call DoInt() again no matter if it had been called already. You should have at least

if (isLoaded) { return; }


at the top of the OnStartComplete() handler.

While we are at OnConnection´...

  • methdod parameter should be named using camelCase casing.



  • swallowing an exception is bad style unless you have a very good reason for it. If you have a very good reason you should state this reasing as a comment so future developers know why you did what you did. In addition in your code if an exception is thrown the default flow just continues and you could see a Addin is Loaded:True but that wouldn't be the truth.



  • if Application is neither Fubaa.Interop.VBA6Ext.VBE nor Fubaa.Interop.VB6Ext.VBE you should return from the handler.



DoInit() and DoCleanup()

Why are these methods
public ? Make them private because thats the only scope they need.

Am I crazy to use an IVBE interface, or should I just use dynamic?

IMO the interface is good as it is. You have implemented it easy and it serves its purpose.

Using
dynamics` instead can lead to compilable code which will throw at runtime. IMO its better to have compiler type checking.

Code Snippets

if (isLoaded) { return; }

Context

StackExchange Code Review Q#136796, answer score: 4

Revisions (0)

No revisions yet.