ActiveX OCX and Windows.Forms Interop: Properties and Events

You have the unenviable position of needing to make an ancient ActiveX control communicate with managed code (i.e. display an OCX on a Form), but you're having trouble getting the two to communicate.

It's not as bad as you think.

Don't make the same mistake I made of trying to do it all manually using a combination of reflection and AxHost.GetOcx(). It's possible, but painful.

Instead, let AxImp.exe do the work for you. AxImp.exe will generate a wrapper around your OCX. You can use that wrapper to wire up events, set properties, and call methods from your .NET code. (AxImp.exe also has a handy /source flag that generates the wrapper's source code).

This example uses old-school VB6 with a timer that raises events periodically, passing a value with the event, and exposes a public property that can be set externally.

(Download all code)

Old school vb6 ActiveX ocx (the horror, the horror ...)
Option Explicit

Public Event MoodChanged(Mood As String)
Private moodCounter As Integer

Private Sub Timer1_Timer()
    Dim currentMood As String
    If moodCounter = 0 Then
        currentMood = "Happy"
    ElseIf moodCounter = 1 Then
        currentMood = "Sad"
    Else
        currentMood = "Sleepy"
    End If
    
    Label1.Caption = "COM OCX says it's " & currentMood
    RaiseEvent MoodChanged(currentMood)
    
    moodCounter = IIf(moodCounter = 2, 0, moodCounter + 1)
    
End Sub 

Private Sub UserControl_Initialize()
    moodCounter = 0 
    Timer1.Enabled = True
    Timer1.Interval = 3000
End Sub 

Public Property Let Mood(ByVal value As String)
    Label1.Caption = "COM OCX has been told it's " & value
End Property

Once you've built your OCX, here's the magic:
AxImp.exe Moods.ocx /out:MoodsAx.dll
This will create two dlls for you that wrap your OCX.
Now, over in Visual Studio, add a reference to the dll with the "Ax" ("Active X") prefix (since I explicitly set the output filename, mine is actually MoodsAx.dll).
ocx interop

The beauty of this is that you'll be able to tab-complete event handler creation with intellisense .

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AxMoods;

namespace DotNet{
	public class Form1 : Form{
		private Label moodLabel;
		private AxMood axMood;
		private TextBox textBox;

		public Form1(){

			this.axMood = new AxMood();
			this.axMood.MoodChanged += new __Mood_MoodChangedEventHandler(this.mood_MoodChanged);
			this.axMood.Width = this.Width;
			
			this.moodLabel = new Label();
			this.moodLabel.Width = this.Width;
			this.moodLabel.Text = "Waiting to hear what mood our ocx is in ...";
			this.moodLabel.Top = 60;

			this.textBox = new TextBox();
			this.textBox.Top = this.moodLabel.Top + 30;
			
			Button button = new Button();
			button.Top = textBox.Top;
			button.Left = textBox.Width;
			button.Width = 100;
			button.Text = "Change Mood";
			button.Click += new EventHandler(this.button_Click);

			this.Controls.Add(textBox);
			this.Controls.Add(button);
			this.Controls.Add(this.moodLabel);
			this.Controls.Add(axMood);	
		}

		void button_Click(object sender, EventArgs e){
			this.axMood.Mood = this.textBox.Text;
		}

		void mood_MoodChanged(object sender, __Mood_MoodChangedEvent e){
			this.moodLabel.Text = ".NET knows COM OCX is " + e.mood;
		}

	}
}


axhost interop

Note: - AxImp.exe requires that your ocx first be regsvr32'd. - Careful to set binary compatibility on your com ocx's so you don't fill your registry with GUIDS.

Download Code

Categories

| Comments (0)TrackBacks (0)

0 TrackBacks

Listed below are links to blogs that reference this entry: ActiveX OCX and Windows.Forms Interop: Properties and Events.

TrackBack URL for this entry: http://www.rootsilver.com/mt-tb.cgi/86

Leave a comment