Final Feature from ThisDocument.cls: Normal.dot ?
One of the annoyances about VSTO development in Word is that Word always seems inclined to write settings into the Normal.dot file (Word’s default template). I’ve never really looked into what these settings typically are, and I’m not sure in the case of this project either, but during the first few rounds of trying to get the CommandBar code working, I was getting asked every time whether I wanted to update the Normal.dot file (and having to create a workaround — see Part 8 for details — to avoid this).
I haven’t seen this come up in the last few days of coding, so I’m not sure if (a) I’ve gotten over whatever hurdle causes this because I’ve finally fixed a bug, or (b) I inadvertently slipped and let the Normal.dot get updated. I’ll check it out in the near future, and I’m sure I’ll have to change something because of it, but for now it’s just not worth worrying about.
Button Click() Event
I was flipping through a copy of Visual Studio Tools for Office (by the two Eric’s — Lippert and Carter) and I happened to catch the section in Chapter 7 (Working with Word Events) entitled “Visual Studio Generation of Event Handlers”. This little gem finally drilled home what the WithEvents keyword means: it allows me to select one of the controls for which I’ve tagged WithEvents in its declaration, then select any of the available Events, and VS2005 will automatically generate the Event Handler stub, complete with all those nasty parameter declarations that always give me heartburn.
So now I understand why I declared the ButtonControl, UploadControl and ConfigControl using WithEvents. Now I can easily generate the Click() Event Handlers for each of these CommandBarButtons.
The more I look at them however, the less I like the names “ButtonControl” etc. They’re not a whole lot better than “ButtonButton”, “UploadButton” and “ConfigButton” (which are obviously redundant, especially with an IDE that automatically describes each object’s type as you’re using it). Further, they really aren’t easy to find when you’re looking for one of the buttons while you’re typing code.
Somewhere along the line I picked up an elegant convention, which is to prefix UI controls with the string “ui”, as in “uiButton”, “uiUpload”, “uiConfig”. That way, any code you’re writing for UI controls will be easy to use Intellisense to narrow down to just those controls with the “ui” prefix.
I’m going to change “ButtonControl” to “uiConvert” as well. I don’t know what the name “ButtonControl” was supposed to mean (other than the most generic way of addressing this first control), and it’ll be easier to remember when the Button label and the object Name are similar.
Issue: Word Macro Settings blocking the Click() event
I dropped a MessageBox.Show() call into each Event handler and Debug’d the application. What’s odd isn’t that Word 2003 complained about Macro settings (“The macro cannot be found or has been disabled because of your Macro security settings”), but that the Configure button first displayed the MessageBox, and after I clicked OK, then it complained like the others. There’s nothing different in the way I constructed the Event Handlers for these three buttons, and they all appear to be doing the same thing, but obviously there’s something happening differently with the uiConfig_Click() handler.
Once I set Breakpoints on all three of these handlers, I realized that only the uiConvert_Click() is actually executing the Sub, which is weird — this event handler is catching the Click event for the Configure button; the other two buttons are erroring before they even try to execute their code.
…Hmm, looks like I found the problem. I’d originally started out with three separate blocks of near-identical code to generate the three CommandBarButtons and all their Properties. Then, when I got the crazy idea to make my code more elegant, I collapse them into a single For Each loop. This really made the code easier to follow, but I forgot to deal with the variable used to configure each of the buttons.
Right now, the loop performs all operations in each iteration on the variable uiConvert, which is typed a CommandBarButton. What I actually need to do is have the For Each loop act on three separate variables (uiConvert, uiUpload and uiConfig) during its three iterations, so that the three buttons get configured properly.
To try to fix this, I’ve tried adding a member to the Structure of type CommandBarButton that references the CommandBarButton variable for each button. Then I use that Structure member in the For Each loop to assign all button Properties, thinking that it’d implicitly be configuring the referenced CommandBarButton variable. Unfortunately, it doesn’t seem to quite work that way.
This code fragment should explain where I’m currently at:
Structure CommandBarButtonSettings Public ButtonVariable As Office.CommandBarButton Public Tag As String Public StyleProperty As Office.MsoButtonStyle ... End Structure
Dim buttonSettings As New CommandBarButtonSettings()
Dim buttonsList As New ArrayList() buttonSettings.BeginGroupProperty = True buttonSettings.ButtonVariable = uiConvert buttonSettings.StyleProperty = Office.MsoButtonStyle.msoButtonIconAndCaption ... buttonsList.Add(buttonSettings)
For Each _buttonSettings As CommandBarButtonSettings In buttonsList 'Create the CommandBarButton if it doesn't exist If W2MWPPBar.FindControl(Tag:=_buttonSettings.Tag) Is Nothing Then (*) buttonSettings.ButtonVariable = CType(W2MWPPBar.Controls.Add(1), Office.CommandBarButton) Else ' If it already exists, do not create the CommandBarButton but just obtain a handle to it (*) buttonSettings.ButtonVariable = W2MWPPBar.FindControl(Tag:=_buttonSettings.Tag) End If Try (*) With buttonSettings.ButtonVariable .BeginGroup = _buttonSettings.BeginGroupProperty .Style = _buttonSettings.StyleProperty ... End With ... End Try Next
The problem is with the code marked with an (*), and I’m stumped on now to resolve this problem.
Aside: Update for VSTO SE available
If you’re using VSTO SE add-in for Visual Studio, then make sure you’ve installed the VSTO SE Update that Microsoft released a couple of months ago. I didn’t know about this, and though it probably won’t affect my code, it’s never a bad thing to be sure.