C# ActiveX Control - events error

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 7239 Views - Last Post: 21 August 2012 - 10:17 AM Rate Topic: -----

#1 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

C# ActiveX Control - events error

Posted 11 August 2012 - 10:46 AM

Hello,
I need to design a full funcionaly ActiveX Data Grid.
I created an C# project:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32;

namespace ActiveXGrid
{
    [Guid("2DC138F0-1CB1-4F9A-ACC4-C3A1F708C495")]    
    public interface ItabelenForm //: ITreeViewEvents_Event
    {
        void Add(params object[] values);
        void AddEmptyLine();
        void AddEmptyColumn();
        string Get(int row, int cell);
    }

    [Guid("A798EE8C-9EB0-40F9-A075-506FDBB149E8")]
    [TypeLibType(4224)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface tabelenFormEvents
    {
        [DispId(1)]
        void Click(); 
    }

    [ProgId("tabelenFormTEST")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(tabelenFormEvents))]
    public partial class tabelenForm : UserControl, ItabelenForm
    {
        public tabelenForm()
        {
            InitializeComponent();
            base.Click += new EventHandler(CSActiveXCtrl_Click);
        }

        public void Add(params object[] values)
        {
            tabele.Rows.Add(values);
        }

        public void AddEmptyLine()
        {
            tabele.Rows.Add();
        }
        public void AddEmptyColumn()
        {
            tabele.Columns.Add("testCol", "TCol");
        }
        public string Get(int row, int cell)
        {
            return tabele.Rows[row].Cells[cell].Value.ToString();
        }

        #region register
        ///	<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();
        }

        ///	<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();
        }
        #endregion

        [ComVisible(false)]
        public delegate void ClickEventHandler();
        public new event ClickEventHandler Click = null;

        void CSActiveXCtrl_Click(object sender, EventArgs e)
        {
            if (null != Click) Click();     // Raise the new Click event.
        }

    }
}



The "tabele" is an:
private System.Windows.Forms.DataGridView tabele;


The ActiveX Control is registering properly, etc.
I created a new C# Windows Form project (container for the ActiveX control).
I puted the ActiveX control without problems on the form.
The interface for the methods is working properly, but I have a problem with getting the events:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            tabelEvent.Click += new ActiveXGrid.tabelenForm.ClickEventHandler(onActivexClicked);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            tabelenForm1.Add("test");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            tabelenForm1.AddEmptyColumn();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            tabelenForm1.AddEmptyLine();           
        }

        public void onActivexClicked()
        {
            button1.Text = "OK";
        }
    }
}



I have declared it like this:
private ActiveXGrid.tabelenFormEvents tabelEvent;
private ActiveXGrid.tabelenForm tabelenForm1;



On the line:
tabelEvent.Click += new ActiveXGrid.tabelenForm.ClickEventHandler(onActivexClicked);

I getting an error:
"Click" ist "Methodengruppe", daher ist die Zuordnung nicht möglich.
I have an German Visual and it means tha "Click" is a "Method group", so the assignment is not possible.
Please help me, I'm working on this control a whole week.
The control is based on the article:
http://code.msdn.mic...3f43e7d#content
Thank You very much good people ;)

Is This A Good Question/Topic? 0
  • +

Replies To: C# ActiveX Control - events error

#2 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5678
  • View blog
  • Posts: 12,213
  • Joined: 02-June 10

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 11:12 AM

onActivexClicked has the wrong signature. Its taking no parameters.
It needs to match an event handler signature where it takes and object and eventsarg. Do you see the difference in the signatures of these two event handlers?


35 public void onActivexClicked()

30 private void button3_Click(object sender, EventArgs e)



Was This Post Helpful? 0
  • +
  • -

#3 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 11:29 AM

Than You for Your answer.
I changed the line to:
 public void onActivexClicked(object sender, EventArgs e)

Now it's saying (transleted from German):
No overload for 'onActivexClicked "agrees with the delegates' ActiveXGrid.tabelenForm.ClickEventHandler" match.

please help
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 11:32 AM

It's been a while since I've had to deal with hosted ActiveX controls, but don't you want this instead:
tabelenForm1.Click += new ActiveXGrid.tabelenForm.ClickEventHandler(onActivexClicked);



I do know that error you currently getting is correct. It's because:
    public interface tabelenFormEvents
    {
        [DispId(1)]
        void Click(); 
    }
:
tabelenFormEvents tabelEvent;


Since Click() is a method on the interface. You can't register for events as if it were declared using the event EventHandler Click;.
Was This Post Helpful? 1
  • +
  • -

#5 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5678
  • View blog
  • Posts: 12,213
  • Joined: 02-June 10

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 11:40 AM

Skydiver is right about the namespace.scope reference you are using.

I suggest you stop working on this project and do the tutorials I linked to you so you have a better understanding of events and what you need to do with them. Then return to this projects better equipped. An hour out of your day to do the tutorials will save you time in the long run compared with guessing and being lost.
Was This Post Helpful? 0
  • +
  • -

#6 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 12:37 PM

I blended out the line:
//base.Click += new EventHandler(CSActiveXCtrl_Click);

I changed my delagate, etc.
[ComVisible(false)]
        public delegate void ClickEventHandler(object sender, DataGridViewCellEventArgs e);
        public event ClickEventHandler MyClick;

        void CSActiveXCtrl_Click(object sender, DataGridViewCellEventArgs e)
        {
            if (null != MyClick) MyClick(sender, e);     // Raise the new Click event.
        }


In the container I changed this lines:
tabelenForm1.MyClick += new ActiveXGrid.tabelenForm.ClickEventHandler(onActivexClicked);

public void onActivexClicked(object sender, DataGridViewCellEventArgs e)


and its working, but I need get the "MyClick" event through the interface of events: ActiveXGrid.tabelenFormEvents,
because it will be implemented to an container that need interfaces.
It's a problem with the ActiveX Events interface, because the events are declared like this:
[Guid("A798EE8C-9EB0-40F9-A075-506FDBB149E8")]
    [TypeLibType(4224)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface tabelenFormEvents
    {
        [DispId(1)]
        void MyClick(); 
    }

Skydiver or somebody any ideas?
please help
Was This Post Helpful? 0
  • +
  • -

#7 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 01:33 PM

I don't recall enough. A quick and dirty test here seems to show that as long as you instantiate the correct COM object, the events are exposed automatically:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Outlook;

namespace GetCOMEvents
{
    class Program
    {
        static void Main(string[] args)
        {
            var app = new Application();
            app.ItemLoad += new ApplicationEvents_11_ItemLoadEventHandler(app_ItemLoad);
            while (true)
                ;
        }

        static void app_ItemLoad(object Item)
        {
            Console.WriteLine("Message opened");
        }
    }
}



To get the above, I just added a reference to the Outlook Object Library under the COM tab.

I'll keep digging, though.

In the meantime, why are you trying to test your ActiveX control by testing it C#? You should be writing a C++ ActiveX host and getting the events that was so that you are sure that the circuit tested.
Was This Post Helpful? 0
  • +
  • -

#8 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:02 PM

I'm testing it in C# because it will be implemented to an C# project. It will work in SAP Buisness One as an ActiveX and the code will be writen in C#. The interface for the metods works fine, but the interface for the events is trowing an non interface exception while implementation.
I found something like this in the SBO exampels showing the implementacion of ActiveX:
    [ComVisible(true)]
    [Guid("F2D388F5-5082-48A6-AB35-7B0C9418A42C")]
    [ComEventInterface(typeof(tabelenFormEvents), typeof(EventProvider))]
    [TypeLibType(16)]
    public interface tabEvent_Event
    {

        event ClickEventHandler MyClick;
        
    }


    [Guid("6B2C79D0-21B8-4E8A-AF32-73876EF82B40")]
    public interface IInterface : tabEvent_Event
    {
       
    }

    [Guid("A798EE8C-9EB0-40F9-A075-506FDBB149E8")]
    [TypeLibType(4224)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] 
    public interface tabelenFormEvents
    {
        [DispId(1)]
        void MyClick(); 
    }


but I don't know what is this EventProvider.
In the example library it looks like an normal variable (it's not colored).
When I put EventHandler there (it's colored), but I run a test:
private ActiveXGrid.IInterface inerfejs;

inerfejs.MyClick += new ActiveXGrid.ClickEventHandler(onActivexClicked);


the MyClick is showed like an event but it's throwing "NullReferenceException".

I think thats the good way, but I stuck in there...
Thank you Skydiver I will be glad if You can help me because my ActiveX knowledge is not so good, but I must get it working ;)
Was This Post Helpful? 0
  • +
  • -

#9 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:07 PM

And here's the manual way of hooking up events that I now remember:
http://www.informit....=25922&seqNum=5

Here are the key lines:
UCOMIConnectionPointContainer icpc = (UCOMIConnectionPointContainer)ie;

// Find the connection point for the
// DWebBrowserEvents2 source interface
Guid g = typeof(DWebBrowserEvents2).GUID;
icpc.FindConnectionPoint(ref g, out icp);

// Pass a pointer to the host to the connection point
icp.Advise(this, out cookie);



With this approach you have it implement the interface in, and pass an instance of your implementation to Advise().
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:23 PM

I'm confused. I understand that you want your ActiveX control to be written in C#. I also understand that SAP Business One accepts ActiveX objects. What is confusing me is the last part:

Quote

It will work in SAP Buisness One as an ActiveX and the code will be writen in C#.


How do you know SAP will be written in C#? If it is written in C# wouldn't it be better if they could load your managed assembly instead of having to go through COM? The COM route means that an assembly must by tied to either 32 or 64 bits, requires COM registration, and worse of all the communication path goes from their managed code, to unmanaged COM interfaces, then back to your managed code.

Ah well, SAP must have made a decision to go for the lowest common denominator and COM was it. It was a mistake my group made several months back when we decided COM only, but then WinRT came along and the COM interface was too cumbersome to use in WinRT. It was a mad scramble to re-design the interfaces.
Was This Post Helpful? 0
  • +
  • -

#11 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:33 PM

Thank You very much and I have a big request to You. Could You help me to implement this into my code, because I'm learnig C#. I'm on a internship and this is my first task and a big challenge for me. I only need that You can show me how to get working it. I'm sitting a whole week on this and slowly gettiing crazy ;P Thank You very much.

Sorry for my english. I've meant that we make a plug in for SAP, and SAP is only taking ActiveX from outside.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:48 PM

So if SAP is only taking ActiveX, then you are wasting your time trying to force another C# program to take the COM events. Just have a small C++ program that hosts the object and registers for events.
Was This Post Helpful? 0
  • +
  • -

#13 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 02:56 PM

SAP is written in C#, but it's so builded that you can use only the controls they maded (very bad grid, etc.) and ActiveX controls. We write in C# a plug in for this SAP and my boss wants an ActiveXDataGrid exported from .NET and Microsoft doesn't support it. I'm on the half way because the metods are working fine, but in don't know how to make the events interface work.
Was This Post Helpful? 0
  • +
  • -

#14 Jelinios  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-August 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 03:44 PM

Skydiver if You have a little bit of time could You help me with this events interfejs. I will be really thankful to You. But know I'm going to sleep because my watch is showing 1.00 AM ;) Thank You once more for You help
Was This Post Helpful? 0
  • +
  • -

#15 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3666
  • View blog
  • Posts: 11,496
  • Joined: 05-May 12

Re: C# ActiveX Control - events error

Posted 11 August 2012 - 03:49 PM

Doesn't the example in link #9 work?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2