by Mark Trescowthick - GUI Computing
A small comments addin.
VB 4 introduced the ability to create addins for the IDE directly, but not too many people did so, for the good reason it was a pretty cumbersome process. There were no real guides on how to do it effectively and the object model was all over the place. In short, it just wasn't worth the effort.
That all changes with VB 5.
For starters, there's now an Addin Wizard which generates most of the code you'll need and, second, the object model is now thoroughly documented and far more comprehensible (and comprehensive).
This little example is, in fact, largely straight out of the wizard, with just a few odd bits of code to actually do what I need. I really like it when all the hard stuff is done is done for me…
This is such a simple little addin, you might wonder why I've bothered. But it's exactly that simplicity which I think is the point here. It's now perfectly possible and reasonable to create a 'quickie' addin to do some repetitive task for a given project. That's a big change from VB 4 and has some potentially large benefits over time, I suspect.
Both Books Online and the printed manuals have reasonably comprehensive sections on the object model and creating addins, and I recommend an hour or so reading them before you dive in - I certainly haven't repeated that information here, because that does seem a little pointless.
The entire project, such as it is, is available for download.
Anyway, to the addin.
Run the Addin Wizard.
You end up with a VB Project called MyAddIn containing a form (frmAddIn.frm), module (Addin.bas) and Class (Connect.cls), which do most of what needs to be done. In fact, the form is pretty much empty, and Addin.bas is only there to provide you with an easy way of adding your addin to the environment when it's done. The real work is done in the class module.
Connect.cls contains the four mandatory methods any addin must expose - OnConnection, OnDisconnection, OnStartup and OnAddinsUpdate. These must be present, even if they contain no code (and, as the manual rightly warns, make sure they have at least a comment or the compiler will helpfully remove them entirely and invalidate your addin in the process!).
Rename your addin.
A SaveAs is appropriate now (trust me on this! It's easier now than later!). But before you do, whip into addin.bas and change the addin name there. This is the name your addin will register as in the end. You'll also want to change the project's properties, otherwise when you do run it for the first time, it will register as "MyAddin", and you'll then have to hack the registry to change that - not recommended!
Construct a form and such.
Finally, actual work!
What I want to do with this form is just construct a simple addin which lets me insert comments either in-line or at the top of my current module or whatever. You could make this much more sophisticated, obviously, but it serves well enough for an example.
My form looks like this :
The code behind it is equally simple.
The real guts is behind the OK Button, not surprisingly.
The first option is to put the comments at the top of the module, and to do that we need to use the AddFromString method of the CodeModule object of the ActiveCodePane.
A CodePane is simply the window used to display the code and we use that to find out which CodeModule we're actually working with. We could step through the CodePanes collection searching for the one we want, but as the ActiveCodePane is the current (or most recently used), that's the one we want. The CodeModule may be associated with more than one CodePane, but we know it's associated with this one, so that's all we need.
VBInstance.ActiveCodePane.CodeModule.AddFromString "'" VBInstance.ActiveCodePane.CodeModule.AddFromString "'" & txtInitials.Text VBInstance.ActiveCodePane.CodeModule.AddFromString "'" & txtDate.Text Call SplitText VBInstance.ActiveCodePane.CodeModule.AddFromString "'"
So, we add a comment or two, then insert the Name, Date and actual comments. That's about it, really. The only hard part was splitting the potentially multi-line comments into reasonable chunks, which we handle in SplitText(), which is something I flat out pinched from Jim Karabatsos.
Private Sub SplitText() Dim T As String Dim sLine As String Const MAXLEN = 45 Dim SpacePos As Long Dim CRPos As Long T = txtComment.Text Do While Len(T) SpacePos = MAXLEN + 1 If SpacePos > Len(T) Then SpacePos = Len(T) Else Do Until Mid$(T, SpacePos, 1) = " " SpacePos = SpacePos - 1 If SpacePos < 1 Then Exit Do Loop End If CRPos = InStr(T, vbCr) If SpacePos > 1 Then ' we have a REALLY long word ... If (CRPos > 0) And CRPos < MAXLEN Then sLine = Left$(T, CRPos - 1) If Mid$(T, CRPos + 1, 1) = vbLf Then T = Mid$(T, CRPos + 2) Else T = Mid$(T, CRPos + 1) End If Else sLine = Left$(T, MAXLEN - 1) & "-" ' really crude hyphenation T = Mid$(T, MAXLEN) ' truncate End If Else If (CRPos > 0) And CRPos < SpacePos Then sLine = Left$(T, CRPos - 1) If Mid$(T, CRPos + 1, 1) = vbLf Then T = Mid$(T, CRPos + 2) Else T = Mid$(T, CRPos + 1) End If Else sLine = Left$(T, SpacePos) T = Mid$(T, SpacePos + 1) End If End If VBInstance.ActiveCodePane.CodeModule.AddFromString "'" & sLine Loop End Sub
Option two is to insert the comments in-line rather than at the top of the module, and the technique used is very similar. The only real wrinkle I found was how to get the line we're currently on. You'd expect there to be a currentLineNumber property or some such of the CodePane, but I certainly couldn't find one. However, the GetSelection method proved just as useful, as it returns the line of the current 'selection' even if there isn't one.
After that, I just concatenate a decent sized string and insert it. I figure that if the actual comment is over 45 characters, it doesn't belong here anyway, so I just truncate it. That's a lazy way to do things, but then this is only an example…
Dim m As Long Dim n As Long Dim x As Long Dim y As Long VBInstance.ActiveCodePane.GetSelection m, n, x, y VBInstance.ActiveCodePane.CodeModule.InsertLines m, "'" & txtInitials.Text & " " & txtDate.Text & " " & Mid$(txtComment.Text, 1, 40)
We're now ready to proceed to...
Compile and add our new addin to VBADDIN.INI, which tells VB5 what addins are available. Yes folks, no registry shenanigans for us, just a plain old INI file.
We do that by simply typing addtoini in the immediate window. How easy can this get?
The fun part. We get to test our new creation.