Author Topic: Trouble adding a Custom Window to an Addin  (Read 211 times)

philchudley

  • EA User
  • **
  • Posts: 523
  • Karma: +9/-0
  • UML/EA Principal Consultant / Trainer
    • View Profile
Trouble adding a Custom Window to an Addin
« on: October 22, 2017, 10:24:43 pm »
Hi All

I am attempting to add a custom window to an addin and have used Sparx's rather brief notes

http://sparxsystems.com/enterprise_architect_user_guide/13.5/automation/custom_docked_window.html

However the addiin window is not added:

I am using Visual Studio 2013 and C# .Net 4.5

My Code is as below:

The very simple Test Addin:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestAddIn
{
    public class TestAddIn
    {
        // ----------------------------------------------------------------------
        // Menu Strings
        // ----------------------------------------------------------------------

        private String menuHeader = null;
        private String[] menuOptions = { null };

        private bool safeDeleteIsEnabled;
        private MyCustomControl myCustomControl;       
 
        //-----------------------------------------------------------------------
        // Constructor
        //-----------------------------------------------------------------------

        public TestAddIn()
        {
            safeDeleteIsEnabled = true;
            menuHeader = "-&Tester";
            menuOptions = new String[] { "&Checked", "-", "&Unchecked", "-", "&Show Window", "&Hide Window"};

        }

        // Enterprise Architect standard extension methods

        public void EA_Connect(EA.Repository repository)
        {

            myCustomControl = (MyCustomControl)repository.AddWindow
                     ("Test Addin", "TestAddIn.MyCustomControl");
            if (myCustomControl == null)
            {
                MessageBox.Show("Test AaddIn Custom Window not added");
            }
            else
            {
                MessageBox.Show("Test AddIn Custom Window added);
         }
        }

        public void EA_Disconnect()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        public object EA_GetMenuItems(EA.Repository repository,
                                      string menuLocation,
                                      string menuName)
        {

            if (menuName == String.Empty)
            {
                //return top level menu option
                return menuHeader;
            }
            if (menuName == this.menuHeader)
            {
                // return submenu options
                return menuOptions;
            }
            else
            {
                return string.Empty;
            }
        }

        public void EA_GetMenuState(EA.Repository repository,
                                    string menuLocation,
                                    string menuName,
                                    string itemName,
                                    ref bool isEnabled,
                                    ref bool isChecked)
        {
            switch (menuLocation)
            {
                case "MainMenu":
                    switch (itemName)
                    {
                        case "&Checked":
                            isEnabled = true;
                            isChecked = safeDeleteIsEnabled;
                            break;
                        case "&Unchecked":
                            isEnabled = true;
                            isChecked = !safeDeleteIsEnabled;
                            break;
                    }
                    break;
            }
        }

        public void EA_MenuClick(EA.Repository repository,
                                    string menuLocation,
                                    string menuName,
                                    string itemName)
        {
            switch (itemName)
            {
                case "&Checked":
                    safeDeleteIsEnabled = !safeDeleteIsEnabled;
                    break;
                case "&Unchecked":
                    safeDeleteIsEnabled = !safeDeleteIsEnabled;
                    break;
            }
        }
    }

}

The addin window has been added to the solutions as a Visual Studio Custom Control and the Code is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestAddIn
{
    public partial class MyCustomControl : Control
    {
        public MyCustomControl()
        {
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
    }
}

Everything builds fine and the addin works fine, but the reference nyCustomControl is always null thus indicating the Custom Window has not not been added.

Using the Extend | Manage | Add-in Windows returns No loaded add-ins are using this window

I must be missing something, but what?

All namespaces and names are correct.s

One curious thing, the article by Sparx on Custom Windows, mentions an ActiveX Custom Control and and OCX file. I do not see any OCX file in my build, so if this is what is missing, how is such an OCX file created, and where should it be located.

Any help or advice will be most appreciated.

Phil
follow me on Twitter

@SparxEAGuru

MrWappy

  • EA User
  • **
  • Posts: 144
  • Karma: +3/-0
    • View Profile
Re: Trouble adding a Custom Window to an Addin
« Reply #1 on: October 23, 2017, 06:30:38 am »
Hi Phil

A quick thought - you have said that you have registered the class, have you?
User guide says "Once the custom control has been created and registered on the target system"

EA will look for a class with the name (in your example) "TestAddIn.MyCustomControl" in the registry.
Use RegEdit to check that there is an entry under HKEY_CLASSES_ROOT

I've forgotten to do it before now.

Adrian



« Last Edit: October 23, 2017, 07:29:50 am by MrWappy »
 

Helmut Ortmann

  • EA User
  • **
  • Posts: 884
  • Karma: +37/-1
    • View Profile
Re: Trouble adding a Custom Window to an Addin
« Reply #2 on: October 23, 2017, 06:43:05 am »
Hi,

To use a custom window you have to develop a DLL for each Custom Window according to the Microsoft COM model. Then you have to make sure that this DLL is correctly registered for COM. If this is done correctly adding it within your AddIn to EA is a simple call. I have seen this call in your code.

I usually start with a running solution and adapt it to my needs. This approach works for me.

The first time I used Geert Bellekens Add-Ins to get familiar. Over time I developed my own little Add-In which I usually use to start a new project. You can find it together with a lot of documented experiences at https://github.com/Helmut-Ortmann/EnterpriseArchitect_hoTools/wiki/AddIn. It's part of the free tool hoTools. To see adding Custom Windows, you have to look into hoTools or similar AddIns.

Of course, there are a lot of other useful AddIns to start with. Geert is always an excellent address to search for.

To summarize:
The rules for a Custom Window are the same as for the primary Addin. You have to develop a dll and register it as COM object. The difference is:
- The Custom Window contains a GUI (FORM or WPF)
- You make a Call to register the registered DLL to EA from your basic AddIn.

I admit I've invested a lot of time for my first running AddIn with a Custom Window. Most issues are around correctly registering it as a COM object. Make sure that there are no Exceptions in Constructors (not easy to find).

Kind regards,

Helmut

Coaching, Training, Workshop (Addins: hoTools, Search&Replace, LineStyle)

MrWappy

  • EA User
  • **
  • Posts: 144
  • Karma: +3/-0
    • View Profile
Re: Trouble adding a Custom Window to an Addin
« Reply #3 on: October 23, 2017, 07:55:39 pm »
@Helmut - in view of your response I needed to check as in my experience I have not needed to have the custom window code in a separate DLL (unless it made sense for the design), as the AddIn is already a COM DLL, but did a simple check this morning in case things have changed!

@Phil - this is what I did to double check:

  • Created a simple user control, called "UC1", which was in my main AddIn DLL (Assembly "testAddIn") - MUST be a public class
  • Added code - see below

I added a simple menu item to show the window in the menu click (in VB.net):

Case "Show window"
 Dim myNewAddInWindow = Repository.AddWindow("My tab Label", "testAddIn.UC1")
 Repository.ShowAddinWindow("testAddIn.UC1")


Register the new class (VS doesn't do this automatically), so I re-registered the AddIn, running the batch file below.  I could then see a new class entry for "testAddIn.UC1"
When deployed the installer will handle the registration.

For testing I have an existing batch file to do the registration with the single line which runs RegAsm for the required .NET framework for my AddIn DLL.  So just re-running this did the job both the AddIn and User Control are in the same DLL.

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe   "./bin/x86/Debug/testAddIn.dll" /codebase

Note this is for .NET3.5, for other .NET versions use the appropriate RegAsm app e.g. for .NET4 use the app to register 

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe

In the case that you develop the code in a separate DLL then clearly Helmut's advice applies.

Hope this helps, but any specifics do ask

Adrian
 

philchudley

  • EA User
  • **
  • Posts: 523
  • Karma: +9/-0
  • UML/EA Principal Consultant / Trainer
    • View Profile
Re: Trouble adding a Custom Window to an Addin
« Reply #4 on: October 24, 2017, 08:30:26 pm »
Thanks for all the help guys

I have now got the Add In window working perfectly

Cheers

Phil
follow me on Twitter

@SparxEAGuru