Click here to Skip to main content
16,021,112 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. There.

I created a simple C ++ ocx file, and created an HTML file to validate ocx.

I confirmed that ocx was successfully registered in the registry and confirmed that ocx was normally invoked in the test HTML to launch the AfxMessageBox().

However, I wanted to call ocx directly in C #.

To implement the ocx call, I looked up the marshaling technique in Google and wrote C # code that calls ocx through marshaling.

As a result, ocx has not been called, and there is no way to determine if this is a C ++ ocx code problem or a C # code problem.

I found a way to solve this problem over two weeks, but I could not solve it.

I would like to get help to solve these problems.

What I have tried:

The process I followed to create ocx is as follows.

1. Create an "MFC ActiveX control" project in Visual Studio 2015.
2. I modified the Ctrl.cpp, Ctrl.h, and .idl files that are automatically generated.

- ActiveXTest4_NonCtrl.cpp
C++
BEGIN_DISPATCH_MAP(CActiveXTest4_NonCtrl, COleControl)
	DISP_FUNCTION_ID(CActiveXTest4_NonCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION_ID(CLinkCtrl, "TestFunction", dispidTestFunction,TestFunction, VT_I4, VTS_I4 VTS_I4)
END_DISPATCH_MAP()

.....

void CActiveXTest4_NonCtrl::AboutBox()
{
	CDialogEx dlgAbout(IDD_ABOUTBOX_ACTIVEXTEST4_NON);
	dlgAbout.DoModal();
}

int CActiveXTest4_NonCtrl::TestFunction(int Parameter1, int Parameter2){
	CString str;
	str.Format(_T("%d"), Parameter1 + Parameter2);
	AfxMessageBox(str);
	return 1;
}

- ActiveXTest4_Non.idl
C++
importlib(STDOLE_TLB);

	//  Basic dispatch interface of CActiveXTest4_NonCtrl.
	[ 
		uuid(3C788A60-2A80-45E8-8845-FE460E779EC7)	
	]
	dispinterface _DActiveXTest4_Non
	{
		properties:
			
		methods:
			[id(DISPID_ABOUTBOX)] void AboutBox();
			[id(1)] int TestFunction(int Parameter1, int Parameter2);
	};

- ActiveXTest4_NonCtrl.h
C++
class CActiveXTest4_NonCtrl : public COleControl
{
	DECLARE_DYNCREATE(CActiveXTest4_NonCtrl)

// Creator.
public:
	CActiveXTest4_NonCtrl();

// override.
public:
	virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);
	virtual void DoPropExchange(CPropExchange* pPX);
	virtual void OnResetState();

// Implementation.
protected:
	~CActiveXTest4_NonCtrl();

	DECLARE_OLECREATE_EX(CActiveXTest4_NonCtrl)    // Class Factory and GUID
	DECLARE_OLETYPELIB(CActiveXTest4_NonCtrl)      // GetTypeInfo
	DECLARE_PROPPAGEIDS(CActiveXTest4_NonCtrl)     // property page ID.
	DECLARE_OLECTLTYPE(CActiveXTest4_NonCtrl)		

// Message Map.
	DECLARE_MESSAGE_MAP()

// Dispatch Map.
	DECLARE_DISPATCH_MAP()
	afx_msg void AboutBox();
	afx_msg int TestFunction(int Parameter1, int Parameter2);
// Event Map.
	DECLARE_EVENT_MAP()

// Dispatch and Event ID.
public:
	enum {
		dispidTestFunction = 1L,
	};
};

3. I have built a modified file.
4. The ocx file has been created and has been successfully registered in the registry.
5. I wrote the test html file.
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> Test Document </TITLE>
 </HEAD>
 <BODY>

TEST
<OBJECT ID="Test" CLASSID="clsid:5CDEAFC2-43EE-48BC-8052-3895514CD062" width="0" height="0"></OBJECT>

 <script>
 	var str = document.Test.TestFunction(5, 2);
 </script>
 </BODY>
</HTML>

6. I confirmed that ocx is executed normally in html.
7. I created a C # console project to test it in C #.
8. I used marshaling to load ocx in C #, and the code that used marshaling is:
C#
 [ComVisible(true), ComImport,
 Guid("5CDEAFC2-43EE-48BC-8052-3895514CD062"),
 InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 interface IMarshal
 {
     [DispId(1)]
     int TestFunction(int param1, int param2);
 }

private static void MarshalTest()
{
   Type typeofMarshal = Type.GetTypeFromProgID("ACTIVEXTEST4_NON.ActiveXTest4_NonCtrl.1");
   if (typeofMarshal == null) return;

   var objMashal = Activator.CreateInstance(typeofMarshal);
   IMarshal iMarshal = (IMarshal)objMashal;
   if (iMarshal == null) return;

   int retVal = iMarshal.TestFunction(1, 2);
}


My development environment is as follows.

ocx Project to create: VS2015 C ++
Project called ocx: VS2015, .NETFramework 4.5, C #
Generated ocx information
- clsId = "5CDEAFC2-43EE-48BC-8052-3895514CD062"
- progId = "ACTIVEXTEST4_NON.ActiveXTest4_NonCtrl.1"
How to call: Marshal
Posted
Updated 7-Nov-18 0:52am

1 solution

You can do it via Importing an ActiveX control into Visual Studio.

Or create an OCX in C# with an underlying dll which contains your ocx code. Remark: it should be easy to add a dll target to your existing ocx project.
 
Share this answer
 
Comments
Member 13934734 7-Nov-18 21:33pm    
I am grateful for answering my question. KarstenK.
The goal of my project is to use the OCX file created in C ++ from the C # console and finally to access the server built in C # with HTML to use the local OCX file.
Can you give me some advice?
Member 13934734 23-Nov-18 2:53am    
I Sloved it through C# WinForm, Websocket...
Thank you for your answer...

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900