So I started to think about how to write coherently about creating a C# MindManager 7 Add-in sample. While the MindManager Add-in model loosely follows that seen in Visual Studio and the Microsoft Office products, there are a number of areas specific to MindManager.
I began with creating the attached map. But it's sometimes useful to use a narrative theme, something to tie together the various pieces into a cohesive whole. So why not use the MM7 Add-in wizard template as a starting point, and go from there?
Well, to put it bluntly, the MindJet Add-in wizard doesn't buy you much.
True, you do get a Connector class that implements the IDTExtensibility interface. And the wizard generates a small Utility class that has a few useful methods. The generated code does compile, rudimentary comments are included in extractable markup, and the correct .NET CLR attributes are placed on the Connector class to make it visible to COM application and define a ProdID.
Probably the most useful thing the wizard does is create a Setup project that carries the Windows Registry settings needed to let the MindManager application locate the Add-in component at load-time. These settings are used by MindManager to discover and load selected Add-in components. If they are wrong, your Add-in never makes it onto the available Add-ins list.
But all this stuff is small potatoes given the work remaining to implement the Add-in and make the wizard-generated code useful.
All the Utility member methods are static, there is no need to create an instance of this type, but MindJet.Utility class carries an unneeded constructor anyway. And this Utility class is also sealed, so you can't derive from it. Any changes you make to the source will reside in the MindJet.Utility namespace and only in that namespace. Since Utility.cs is a C# source file in the generated Add-in project, you'll need to use the cut-and-paste wizard to use your enhancements elsewhere.
The responses you provide to the wizard are used to create a stubbed out Extensibility.IDTExtensibility2 implementation in a class called Connector, but this is pretty simple to do manually. Derive a class from an interface, and Visual Studio will stub out the methods with "Not Implemented" method bodies on demand.
However, the wizard-generated code does place try-catch blocks in the method bodies of the Connector type, passing control to MindJet.Utility.ShowError() method in the catch block. This may seem like a good thing, but on further inspection it turns out more work is needed to reach a useful implementation. While Utility.HandleError() puts up a MessageBox(), it doesn't throw an exception itself, so there's no help in implementing a useful exception handling scheme. Rather, an exception passed to Utility.ShowError() in a catch block is just shown in all its cryptic glory to the user, and then dropped on the floor.
A better scheme would provide a MindJet.Exception class definition and use that to log exception instance details, then throw them to an outer catch block or the .Net runtime itself. Such an implementation could be used to as a base class in creating additional Exception classes specific to the Add-in itself.
Given the number of things possible in a MindManager Add-in, I sort of expected base classes to help with command/event handling, Task Pane creation and perhaps the Options dialog or some code sample that dealt wth the Ribbon/Tab/Group parts of the UI . None of that is present. Nor is there any demonstration of the MindJet object model or the use of markup technology, two useful parts of the MindManager software solution platform.
Finally, I have a basic distrust of wizards, learned through scars acquired in the early C++ Microsoft Foundation Class (MFC) days. I'd rather know what the code is doing than blindly trust a wizard. If there is not enough bang for the investment in understanding the wizard output, let's cut to the chase and drop the wizard altogether.
So I'll keep going with my hand-rolled sample and not sweat the MM7 Add-in Wizard Template. Just about everything I want to talk about has to be done anyway, regardless of the starting point. You can start with the generated output from the MM7 Wizard, or with an empty file in a text editor and get to the same place.