[Note: I finally found this article in the Google search cache, so while it’s posted out of order, at least it’s finally available again.]
[This series has five previous articles: the prologue, Part 1, Part 2, Part 3 and Part 4.]
When you create an Office Add-in Project with VS2005 + VSTO, it automatically generates two Sub’s in the ThisAddIn class: ThisAddIn_Startup() and ThisAddIn_Shutdown(). Now I recall using these before for some basic background behaviour, but I have a feeling there are a few other Events in which it’s recommended to put the kind of code that’s usually used for setup, tear-down, opening persistent connections & closing them, etc.
However, the only unused Events that I can see when browsing the Method Name drop-down are New, Finalize, IsCached, StartCaching and StopCaching. Nothing really compelling so far, and none of those ring any bells. Onwards.
My plan is to work from the Word UI inwards, so that (a) if the AutoWikiBrowser folks aren’t able to grant redistribution rights for this project I’m less likely to be committed to links to their code, and (b) I’ll have more time to absorb the innards of the Word2MediaWikiPlus Macro.
Thus, I figure I’ll start with two easy tasks:
- Port any necessary code from ThisDocument.cls to ThisAddin.vb (since ThisDocument.cls is my best guess for the code closest to the Word UI)
- Drop in the code for instantiating the CommandBar, CommandBarButton(s) and any related bits o’ code.
- cmdCopyModuls_Click(): as it says, it copies code to Normal.dot. IIRC, VSTO Application Add-ins don’t need to link themselves into Normal.dot, so I’m going to skip this code for now.
- CreateSymbol(): It’s not clear what they meant by “symbol” here. Do they mean “toolbar button”? Debug symbols? I suspect it refers to toolbar (aka CommandBar), as that’s what the code seems to suggest. However, before dismissing this entirely, I needed to understand what Application.OrganizerCopy does. It’s listed among the Word Interop methods, and in the Word 2003 VBA Language Reference it’s described as “Copies the specified AutoText entry, toolbar, style, or macro project item from the source document or template to the destination document or template.” It appears the Macro is copying the object from Normal.dot to the current document, so this Sub can safely be ignored.
- CreateSymbol2(): This also instantiates the toolbar, but it’s closer to what I need in the Startup() method. I like the organization of buttons and text for the buttons so far, and there’s only three to create: Convert To Wiki, Upload Images and Configure Word2MediaWikiPlus. I’ll tuck that away for when I load in my CommandBar code.
- CopyModulesToNormal(): once again there are references to NormalTemplate and Macros. It implements an “update” routine, to copy code to Normal.dot; in the VSTO application add-in world, however, this is unnecessary.
- cmdSymbols_Click(): calls one method, CreateSymbol(). Since that routine is unneeded, this method (and the UI Button that calls it) can safely be skipped.
- cmdUninstall_Click(): calls one method, Uninstall_Word2MediaWikiPlus(). Wherever that method is, it’s hardly necessary when this VSTO add-in will have its own installer and uninstall routine tied to Add/Remove Programs.
Wow, that was a little too easy. The rest of the “port” will get harder.
Creating the CommandBar
I already know that this code should be factored out of the Startup() method, but it’s easier to refactor than create the code and link it back. I suspected there’d be a Code Snippet for instantiating a CommandBar, so I started browsing through the Code Snippet hierarchy (Edit menu > Intellisense > Insert Snippet…) starting with Office Development > Office > Environment – Menus, Action Panes and chose “Create a Command Bar“.
It took me a while to figure out what the “CommandBarHost” replacement should be in
Dim commandBarsCollection1 As Office.CommandBars = DirectCast(commandBarHost.CommandBars, Office.CommandBars)
It kept telling me to “Replace with a reference to the Excel Application, Word Application or a Word Document.” I kept thinking I’d need to find some Object buried four levels deep in the namespaces, but it turns out all I needed was
Dim commandBarsCollection As Office.CommandBars = DirectCast(Application.CommandBars, Office.CommandBars)
[Someday I really hope I understand all this Cast nonsense – I’m sure there’s a very good reason why all this has to be done, but boy does it feel like a primitive hack on what is otherwise a pretty elegant language.]
Then the other lesson for the evening kicked in: I learned that my favoured variable naming convention – using “Word2MediaWiki++” as a common prefix wouldn’t work – Visual Studio at times tried to insert a “(” character before the plus signs, and otherwise told me that “Method arguments must be enclosed in parentheses”. Grrr, W2MWPP it is.
In trying to understand what the Set keyword was supposed to accomplish in VBA, I ran across a really strong article in MSDN that I’ve been looking for all weekend: Convert VBA Code to Visual Basic When Migrating to Visual Studio 2005 Tools for Office. Among the many, many tips on resolving specific code conversion issues is an explanation that indicates the Set keyword can simply be removed, leaving the remaining VBA intact.
A few Dim keywords here & there, a few more With… End With statements, and some string substitution to update to the name of this add-in, and we’re almost done. One last thing: what is this DoEvents method that’s called just after the toolbar is made visible? I’ve searched through all the Macro code and see it repeated dozens of times throughout, but no definition for it. Is it a built-in VBA method? Back to the “Convert VBA Code…” article it seems.
Join us again… well, you know the drill by now…