MindManager 7 "ToDo List" Add-in development Part 3: Initial Working Code

Successful running of the add-in!  Once I added the required Registry settings, the add-in finally made itself known (through the MessageBox’es).  I learned that the HKCR settings are also necessary for other calls to succeed, but the essential behaviour of being recognized and loaded by MindManager was entirely dependent on having those Registry settings populated in the \Addins key.

At first I just used a .REG file to populate the Registry settings, following the model of the MM7 Sample Addin.  I had to do this as a side-effect of the work the helpful folks on the Mindjet “Dev Support” team did to rip out a bunch of “custom actions” stuff from my MM7 add-in solution, and this appears to have included all the Registry settings as well.  [Note: the Mindjet dev support folks are really helpful, and I’m not blaming them for this — the MM7 VS project template was (a) developed under Visual Studio 2005 not 2008 (which I’m using), and (b) was last updated last summer (and is no currently under active development I’d guess because the person who originally created it has since left the company — at least, that’s the usual way these things occur).

However, it’s not quite perfectly operating yet — just before the OnStartupComplete dialog box comes up, the following error is thrown by MM7:


According to this thread, this means that Addin ID must match the first parameter to applicationObject.Commands.Add().  In my code that parameter is “ParanoidMike.ToDoListBuilder.AddIn”, and my first guess is that the key under HKLM\Software\Mindjet\MindManager\7\AddIns needs to have the same name (which it currently doesn’t).  Upon changing it to match, I finally saw the Add-Ins Ribbon tab that I hadn’t been able to expose until now.

On to a little code…

First stage: Ribbon Button That Counts Tasks in Current Map

I wanted to use as much of the code from the MindManager7 Sample Add-in as possible… however somehow I ended up not using much or any of that.  This was my original plan:

  1. Create variable for MM application
    • Sample\MmxUtility\Helper.cs: MmxUtility.Helper.GetMmxMap()
  2. Beg/borrow/steal ribbon button code from existing add-in
    • Sample\MmxUtility\RibbonTabBase.cs (base class for creating a new Ribbon tab)
    • Sample\MmxUtility\ControlStripBase.cs
  3. Attach function to Ribbon button
  4. Create variable for Current Map
    • Application.ActiveDocument
  5. Find the Base Topic and enumerate
    • Sample\MmxUtility\Helper.cs: Helper.BaseTopicFinder()
  6. Create variable for Count
  7. Create For Each loop of Task objects, and count ’em
    • Sample\MmxUtility\Helper.cs (Topic attributes)

Instead, though, I ended up trying to separate out the UI from the data manipulation code, and leveraging the code I’d written from the MindManager DevZone article “How to Create a MindManager 7 Add-in Using C#“. 

This is what resulted:

        private void mmCommand_Click()
            // Process the MindManager command and say hello
            MessageBox.Show("Hello world! (C#)", addInDisplayName);

            // Get the current Map
            Mindjet.MindManager.Interop.Document currentMap;
            currentMap = applicationObject.ActiveDocument;

            // Count the current Map's Tasks and display for the user:
            int count;
            ToDoListBuilder taskCounter = new ToDoListBuilder();
            count = taskCounter.countTasks(currentMap);
            MessageBox.Show("There are " + count.ToString() + " Tasks in this Map");
    class ToDoListBuilder
        public int countTasks(MMInterop.Document mindMap)
            int tasksCount; // count of the number of Topics that are Tasks
            MMInterop.Range range; // just a collection of whatever we can find in the Document 🙂
            range = mindMap.Range(MMInterop.MmRange.mmRangeAllTopics, true);
            tasksCount = 0; // initialize to avoid error CS1065
            foreach (MMInterop.Topic topic in range)
                if (topic.Task.Complete >= 0)  // this is intended to test whether the "topic" has Task attributes attached to it, and is how ResultsManager characterizes a Task
                    tasksCount++; // increment this counter variable
            return tasksCount;

The key magic in this code was the test for whether a Topic is a Task or not:

if (topic.Task.Complete >= 0) 

I’d spotted this approach in a macro that was published on ActivityOwner, but it seemed more complicated and indirect than should be necessary.  I wondered whether something like topic.Task.IsValid() would identify whether a topic had “valid” Task characteristics.  I looked into what documentation for this method was available, but the available info is pretty sparse.  If not for the generous help from the MindManager development community like Nick Duffill, I would’ve been forced to work through this by trial & error.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s