Click here to Skip to main content
Click here to Skip to main content

Tagged as

The legend of Forever Alone guy who wrote himself a wrapper for C# to use as ActiveX.

, 8 Jun 2012
Rate this:
Please Sign up or sign in to vote.
Wrap a .NET user control in an ActiveX class

Target

Wrap a .NET user control in an ActiveX class

Solution

1/ Create the Class Library in VS 2010

Open your Visual Studio in Administrator mode please (some system access will be made). Create a new, empty Class Library project and add into it a Windows Form. Drag to the from 1 button named btnDo and 1 label named lblResult. Then bind the button clicking event with these code:
private void radButton1_Click(object sender, EventArgs e)
        {
            this.lblResult.Text = "I am a .NET user control happily living \ninside an ActiveX container. Cheers.";
        }
I'm sure you all know the meaning of that code. If you don't, go to the book store and pick any book about C# programming. I suggest the thin one because it should be cheaper. Ok, let's move to the next part.

2/ Setting for project

Open the library's Property Settings window and select the Application tab. You should see an "Assembly Information…" button - click on it and it will open a dialog form with various assembly settings. You will see a checkbox named "Make assembly COM-visible". The checkbox must be checked. You would also see a GUID field. Let's do something with it. Click menu Tools -> Create GUID. In the showing dialog, click Copy. Now close this dialog and paste to GUID field in Property Settings. It is used to set the ID of the typelib if this project is exposed to COM.

Figure 1 - Settings

Now, choose tab Build If you want automatic registration of the freshly created ActiveX wrapper you should check the "Register for COM interop" checkbox. It runs Regasm.exe after every build to register the types with COM (which you probably shouldn't do until you're stable because your COM GUIDs will change whenever you change the methods unless you specify GUIDs explicitly, so your registry could end up with a lot of registration junk for versions that will never be used). Last thing to do here is to provide your ActiveX a strong name key. Let do it with Microsoft style. Steps below is copied from http://msdn.microsoft.com/en-us/library/aa559684%28v=bts.20%29.aspx with a small modification.

To create a strong name key file

  1. Click Start, point to Programs, point to Microsoft Visual Studio 2010, point to Visual Studio Tools, and then click Visual Studio 2010 Command Prompt.
  2. At the command prompt, change directory to you project folder.
  3. At the command prompt, type sn -k ActivX.snk, and then press ENTER

Now, in the Property Settings, choose Signing tab and Browse ActivX.snk as Strong name key file. Done, now back to the code for a few additions.

3/ Thank God We have Interop Services

At the beginning of your Window Form class, insert below code:

    [ProgId("ActiveXTestLibrary.UserControl")]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComVisible(true)]

The ProgId attribute which provides a unique name for the created ActiveX interface. You can change ActiveXTestLibrary.UserControl by other string that describes your ActiveX function. The second ClassInterface attribute states whether and how a COM interface will be generated for the managed assembly. The last ComVisible attibute controls accesibility of member true to COM.

Also you can provide static methods that are invoked when the ActiveX is registered or unregistered through the Regasm.exe:

       [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();

            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();

            k.Close();
        }

        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            if (k == null)
            {
                return;
            }
            k.DeleteSubKey("Control", false);

            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

            inprocServer32.DeleteSubKey("CodeBase", false);

            inprocServer32.Close();
        }

The methods have predefined names (RegisterClass and UnregisterClass) and should be marked respectively with the ComRegisterFunction/ComUnregisterFunction attributes. Here we register the category of the ActiveX as a UI control.

4/ Write some thing to show the form

To show a form you need to start a message loop by calling Application.Run:
        [ComVisible(true)]
        public void Hello()
        {
            Application.Run(this);
            MessageBox.Show("Hello text", "Test");
        }

The Show() function will show the form and immediately exit. Application.Run() will not exit until the form is closed.

Now build the project. You will have dll and your dll has already been registered to System.

5/ Test

Open a text editor for writing about 4,5 lines of VBS code. I like notepad++ for Window and gedit for Ubuntu, but what you use is up to you. Paste that code, save it as Test.vbs, run the file and see what happen.
Sub main
    set objTest = CreateObject("ActiveXTestLibrary.UserControl")
    objTest.Hello
    Do While (10 > 9)
    Loop
end Sub

call main

Figure 2 - C# form is called by vbs

Then click the button Smile | :)

Figure 3 - C# event is listened

Thanks for reading a very boring post. Here is your gift: my source code

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Duc Huy Nguyen

Vietnam Vietnam
Oops!

Comments and Discussions

 
GeneralMy vote of 5 Pinmemberjfriedman12-Jun-12 4:29 
QuestionLoved the title PinmemberJose Menendez Póo8-Jun-12 7:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 8 Jun 2012
Article Copyright 2012 by Duc Huy Nguyen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid