Hello all,
As per the subject, there's some good information in Wolfgang's wiki, about creating COM modules in X# and using them form VO, written by Wolfgang and Dick:
https://docs.xsharp.it/doku.php?id=com_module_sample
https://docs.xsharp.it/doku.php?id=com_module_sample_vs
I know Irwin has had some success with creating Windows.Forms controls to be used from VFP, I hope he can share this with us!
Creating COM modules/ActiveX controls in X# for use from other languages
Creating COM modules/ActiveX controls in X# for use from other languages
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Re: Creating COM modules/ActiveX controls in X# for use from other languages
WOW,I hope so too.
简单的东西重复做,你能成为专家;重复的东西用心做,你能成为赢家!
Re: Creating COM modules/ActiveX controls in X# for use from other languages
Hi Xinjie,
after all, X# is a descendant from C# with a lot of things added to be compatible with xBase dialects and to boost the programmers productivity, so it can also produce COM libraries to be used in Win32 applications.
Nearly all my legacy Win32 applications are using a least one X# COM library to add functionalities otherwise impossible to implement.
Wolfgang
after all, X# is a descendant from C# with a lot of things added to be compatible with xBase dialects and to boost the programmers productivity, so it can also produce COM libraries to be used in Win32 applications.
Nearly all my legacy Win32 applications are using a least one X# COM library to add functionalities otherwise impossible to implement.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Re: Creating COM modules/ActiveX controls in X# for use from other languages
Hi everybody,
Hope this guide explains the steps necessary to expose a .NET control to COM, making it accessible from environments like Visual FoxPro/VO/VB6, etc. The example focuses on creating a custom button control.
When exposing a control via COM, interfaces play an important role, especially when using ClassInterfaceType.None. This type of class interface means you must define the methods yourself and explicitly expose them.
a) Define Event Interface
This interface (IControlEvents) will handle the events that your control will raise. For example, a MyButtonClick event can be defined like this:
[Guid]: Assigns a unique identifier for the interface.
[InterfaceType]: InterfaceIsIDispatch allows the interface to be accessed via late binding, which is useful in environments like Visual FoxPro.
[DispId]: Assigns a dispatch ID to the method for COM.
b) Define Method Interface
If you are using ClassInterfaceType.None, you need to define the methods manually using an interface like ICustomButton. This interface ensures that any method you want to expose is explicitly declared. Here is an example for a Button_Click method:
Obligatory for ClassInterfaceType.None: When using ClassInterfaceType.None, no automatic interface is generated. This means you must explicitly declare any methods you want to expose through COM.
Now that the interfaces are defined, you can implement your custom control. The control class will inherit from UserControl (or any other Windows Forms control) and implement the ICustomButton interface.
[ComSourceInterfaces]: Specifies which interfaces (like IControlEvents) will be used to trigger events accessible via COM.
[ProgId]: The Programmatic Identifier that COM clients like Visual FoxPro will use to instantiate the control.
[ClassInterface(ClassInterfaceType.None)]: Disables automatic generation of COM interfaces for the class. This is why you must define your own interfaces, like ICustomButton, to expose the necessary methods.
In this step, you will implement the event handler and expose the necessary methods in your control.
a) Implement Button Click Event
The Button_Click method, defined in the ICustomButton interface, is implemented as follows:
This method triggers the MyButtonClick event whenever the button is clicked.
b) Declare the Event
To make the event accessible via COM, define a delegate and an event:
Once the control is implemented, it must be registered in the Windows registry so that COM clients like FoxPro can find and use it.
a) Register the Control
This is done using the ComRegisterFunction and ComUnregisterFunction attributes. These methods modify the Windows registry to register or unregister the control.
The RegisterClass method adds the control to the Windows registry so it appears in COM.
The UnregisterClass method removes it from the registry.
1. Don't forget to add the ComVisible(true) attribute in the AssemblyInfo.prg file.
2. You have to convert your compiled assembly in the COM equivalent by using the Assembly Registration Tool (RegAsm)
3. Use your own guids, I've built a plugin that adds an option in the Tools menu (Generate Guid) that injects the guid in your editor caret current position. @Chris where can we share all the plugin we build?
Hope this guide explains the steps necessary to expose a .NET control to COM, making it accessible from environments like Visual FoxPro/VO/VB6, etc. The example focuses on creating a custom button control.
When exposing a control via COM, interfaces play an important role, especially when using ClassInterfaceType.None. This type of class interface means you must define the methods yourself and explicitly expose them.
a) Define Event Interface
This interface (IControlEvents) will handle the events that your control will raise. For example, a MyButtonClick event can be defined like this:
Code: Select all
[Guid("ea567180-887c-48f0-8867-c51aaef20750")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
INTERFACE IControlEvents
[DispId(1)]
METHOD MyButtonClick() AS VOID
END INTERFACE
[InterfaceType]: InterfaceIsIDispatch allows the interface to be accessed via late binding, which is useful in environments like Visual FoxPro.
[DispId]: Assigns a dispatch ID to the method for COM.
b) Define Method Interface
If you are using ClassInterfaceType.None, you need to define the methods manually using an interface like ICustomButton. This interface ensures that any method you want to expose is explicitly declared. Here is an example for a Button_Click method:
Code: Select all
INTERFACE ICustomButton
METHOD Button_Click(sender AS OBJECT, e AS EventArgs) AS VOID
END INTERFACE
Now that the interfaces are defined, you can implement your custom control. The control class will inherit from UserControl (or any other Windows Forms control) and implement the ICustomButton interface.
Code: Select all
[Guid("6e3a579a-59a4-42c9-b9c7-3b162f5c0005")]
[ComSourceInterfaces(typeof(IControlEvents))]
[ProgId("ActiveX.MySample.MyCustomButton")]
[ClassInterface(ClassInterfaceType.None)]
PARTIAL CLASS MyCustomButton INHERIT System.Windows.Forms.UserControl ;
IMPLEMENTS ICustomButton
[ProgId]: The Programmatic Identifier that COM clients like Visual FoxPro will use to instantiate the control.
[ClassInterface(ClassInterfaceType.None)]: Disables automatic generation of COM interfaces for the class. This is why you must define your own interfaces, like ICustomButton, to expose the necessary methods.
In this step, you will implement the event handler and expose the necessary methods in your control.
a) Implement Button Click Event
The Button_Click method, defined in the ICustomButton interface, is implemented as follows:
Code: Select all
METHOD Button_Click(sender AS System.Object , e AS System.EventArgs) AS VOID
IF MyButtonClick != NULL
MyButtonClick()
ENDIF
END METHOD
b) Declare the Event
To make the event accessible via COM, define a delegate and an event:
Code: Select all
DELEGATE MyButtonClickEvent AS VOID
EVENT MyButtonClick AS MyButtonClickEvent
Once the control is implemented, it must be registered in the Windows registry so that COM clients like FoxPro can find and use it.
a) Register the Control
This is done using the ComRegisterFunction and ComUnregisterFunction attributes. These methods modify the Windows registry to register or unregister the control.
Code: Select all
[ComRegisterFunction()]
PUBLIC STATIC METHOD RegisterClass(tcKey AS STRING) AS VOID
VAR loSb := StringBuilder{tcKey}
loSb:Replace("HKEY_CLASSES_ROOT\", "")
VAR k := Registry.ClassesRoot:OpenSubKey(loSb:ToString(), TRUE)
VAR ctrl := k:CreateSubKey("Control")
ctrl:Close()
VAR inprocServer32 := k:OpenSubKey("InprocServer32", TRUE)
inprocServer32:SetValue("CodeBase", Assembly.GetExecutingAssembly():CodeBase)
inprocServer32:Close()
k:Close()
END METHOD
[ComUnregisterFunction()]
PUBLIC STATIC METHOD UnregisterClass(tcKey AS STRING) AS VOID
VAR loSb := StringBuilder{tcKey}
loSb:Replace("HKEY_CLASSES_ROOT\", "")
VAR k := Registry.ClassesRoot:OpenSubKey(loSb:ToString(), TRUE)
k:DeleteSubKey("Control", FALSE)
k:OpenSubKey("InprocServer32", TRUE)
k:DeleteSubKey("CodeBase", FALSE)
k:Close()
END METHOD
The UnregisterClass method removes it from the registry.
1. Don't forget to add the ComVisible(true) attribute in the AssemblyInfo.prg file.
2. You have to convert your compiled assembly in the COM equivalent by using the Assembly Registration Tool (RegAsm)
3. Use your own guids, I've built a plugin that adds an option in the Tools menu (Generate Guid) that injects the guid in your editor caret current position. @Chris where can we share all the plugin we build?
Re: Creating COM modules/ActiveX controls in X# for use from other languages
Hi, Irwin
Thank you!
Thank you!
简单的东西重复做,你能成为专家;重复的东西用心做,你能成为赢家!
Re: Creating COM modules/ActiveX controls in X# for use from other languages
Thanks a lot Irwin!
As for the XIDE plugins, we will create a section in the downloads area for that. But it has to wait till the next official X# release, which will contain the new IDE as well (which includes plugin system additions that your plugin probably depends on).
As for the XIDE plugins, we will create a section in the downloads area for that. But it has to wait till the next official X# release, which will contain the new IDE as well (which includes plugin system additions that your plugin probably depends on).
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu