ActiveX Doubt

Jan 21 2009 11:30 AM
Hi Everyone,
In my office I have given a work to open windows form application in browser. Its world wind Globe application which will show latitude and longitude values any where on the globe, I have searched google and I could find few articles which guided me to create an ActiveX Control.

I created C# Class library and added all the classes, Folders[Data, Layers, Location, Plugin Engine, Plugins, Terrain, Web], References,  from C# windows application. Program.cs is main entry for the application and I given Attributes ProgID, guid, COMVisible...

The code goes as follows: Program.cs

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using Microsoft.Win32;
using System.ComponentModel;
using System.Threading;

namespace Globe
{
    [ProgId("Program")]
    [ClassInterface(ClassInterfaceType.AutoDual), ComSourceInterfaces(typeof(ControlEvents))] //Implementing interface that will be visible from JS
    [Guid("BB5E3B2B-E560-4199-8673-F7EDA38A8987")]
    [ComVisible(true)]

    public class Program 
     {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>

        //[STAThread]
        //private string myParam = "Empty";
        public event ControlEventHandler OnClose;
         //<summary>
         //Opens application. Called from JS
         //</summary>
        [ComVisible(true)]
        public void Open()
        {
            //TODO: Replace the try catch in aspx with try catch below. The problem is that js OnClose does not register.
            try
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                //Application.Run(new MainForm());
              
            }
            catch (Exception e)
            {
                //ExceptionHandling.AppException(e);
                throw e;
            }
        }

        [ComVisible(true)]
        public void execute()
        {
            Application.Run(new MainForm());
        }


        /// <summary>
        /// Parameter visible from JS
        /// </summary>
      [ComVisible(true)]
        public void Close()
        {
            if (OnClose != null)
            {
                OnClose("http://otherwebsite.com"); //Calling event that will be catched in JS
            }
            else
            {
                MessageBox.Show("No Event Attached"); //If no events are attached send message.
            }
        }
         
        ///    <summary>
        ///    Register the class as a    control    and    set    it's CodeBase entry
        ///    </summary>
        ///    <param name="key">The registry key of the control</param>
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");
            // Open the CLSID\{guid} key for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
            // And create    the    'Control' key -    this allows    it to show up in
            // the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();
            // Next create the CodeBase entry    - needed if    not    string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();
            // Finally close the main    key
            k.Close();
            MessageBox.Show("Registered");
        }

        ///    <summary>
        ///    Called to unregister the control
        ///    </summary>
        ///    <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open    HKCR\CLSID\{guid} for write    access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // Delete the 'Control'    key, but don't throw an    exception if it    does not exist
            k.DeleteSubKey("Control", false);

            // Next    open up    InprocServer32
            //RegistryKey    inprocServer32 =
            k.OpenSubKey("InprocServer32", true);

            // And delete the CodeBase key,    again not throwing if missing
            k.DeleteSubKey("CodeBase", false);

            // Finally close the main key
            k.Close();
            MessageBox.Show("UnRegistered");
        }
     }
     /// <summary>
     /// Event handler for events that will be visible from JavaScript
     /// </summary>
     public delegate void ControlEventHandler(string redirectUrl);
     /// <summary>
     /// This interface shows events to javascript
     /// </summary>
     [Guid("BB5E3B2B-E560-4199-8673-F7EDA38A8987")]
     [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
     public interface ControlEvents
     {
        //Add a DispIdAttribute to any members in the source interface to specify the COM DispId.
        [DispId(0x60020001)]
        //[DispId(1)]
        void OnClose(string redirectUrl); //This method will be visible from JS
     }
    
};

I also successfully created ini and cab files.

I have given Java Scripting in HTML file which is:

<html xmlns="http://www.w3.org/1999/xhtml">
<head> <title></title> </head>

<body onload="myload();">
<object id="Program" name="Program" classid="clsid:4CBBC676-507F-11D0-B98B-000000000000"  codebase="Program.cab"></object>   

<script type="text/javascript">
      function Program::OnClose(redirectionUrl)
       {
        alert(redirectionUrl);   <!-- http://otherwebsite.com should be returned-->
                   //window.location = redirectionUrl;
       }
</script>
<script type ="text/javascript">
function myload()
{
   try
    {
         document.Program.Open(); //Running method from activeX
         //document.MainForm().action = alert(Program.execute());
         document.Program.execute();
         alert(Program.execute());
        //document.forms.item=Program.Open();
       
    }
    catch(Err)
    {
        alert(Err.description);
    }
}
</script>
</body></html>

Mainform contains Private Members, Constructors, World Window Events, Main Form changing events, Main Form Events. I need to run [Application.EnableVisualStyles();                Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm());] from another class.
I tried and am getting error Object doesn't support this property or method, I would be very helpful if anyone fix this error for me.

Thanking you all in advance,
Regards,
Sharat.

Answers (1)