简单MFC ActiveX插件例子

最终的插件可供MFC程序调用,也可供浏览器调用(仅IE浏览器支持)

1、创建MFC ActiveX控件,这里项目命名为MFC_ActiveX_2
简单MFC ActiveX插件例子
简单MFC ActiveX插件例子

2、项目属性—》配置属性—》常规—》MFC的使用,选择“在静态库中使用MFC”。
简单MFC ActiveX插件例子
模块定义文件,创建项目时已自动配置好。
简单MFC ActiveX插件例子

3、类视图—》MFC_ActiveX_2Lib—》右键_DMFC_ActiveX_2—》添加方法
简单MFC ActiveX插件例子
这里添加一个返回类型为“DOUBLE”,方法名为“CalFun”,拥有两个参数类型为DOUBLE参数的方法。
简单MFC ActiveX插件例子

4、然后在MFC_ActiveX_2Ctrl.cpp中就能看到刚刚添加的函数CalFun。这里对它做一些实现。

DOUBLE CMFC_ActiveX_2Ctrl::CalFun(DOUBLE num1, DOUBLE num2)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO:  在此添加调度处理程序代码
	DOUBLE sum, difference, product, quotient;

	//运算加减乘除
	sum = num1 + num2;
	difference = num1 - num2;
	product = num1 * num2;
	quotient = (0 == num2) ? (0) : (num1/num2);

	CString sum_s, difference_s, product_s, quotient_s;
	sum_s.Format(_T("%lf"), sum);
	sum_s = _T("两个数的和为") + sum_s;
	difference_s.Format(_T("%lf"), difference);
	difference_s = _T("两个数的差为") + difference_s;
	product_s.Format(_T("%lf"), product);
	product_s = _T("两个数的积为") + product_s;
	quotient_s.Format(_T("%lf"), quotient);
	quotient_s = _T("两个数的商为") + quotient_s;

	//和的弹窗
	MessageBox(sum_s);
	//差的弹窗
	MessageBox(difference_s);
	//积的弹窗
	MessageBox(product_s);
	//商的弹窗
	MessageBox(quotient_s);

	return 0;
}

简单MFC ActiveX插件例子

5、接下来需要声明组件安全性,对于ATL写的ActiveX,实现IObjectSafety即可;对于MFC写的ActiveX,可以通过修改注册表的方式来实现控件的安全性。

项目中新建Cathelp.h和Cathelp.cpp文件,并将以下代码复制进去。
Cathelp.h

#include "comcat.h"

// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);

// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

// HRESULT UnRegisterCLSIDInCategory - Remove entries from the registry 
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

Cathelp.cpp

#include "stdafx.h"
#include "comcat.h"
#include "strsafe.h"
#include "objsafe.h"


// HRESULT CreateComponentCategory - Used to register ActiveX control as safe 
HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription)
{
    ICatRegister *pcr = NULL ;
    HRESULT hr = S_OK ;
 
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (FAILED(hr))
        return hr;
 
    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered.
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // english
    size_t len;
    // Make sure the provided description is not too long.
    // Only copy the first 127 characters if it is.
    // The second parameter of StringCchLength is the maximum
    // number of characters that may be read into catDescription.
    // There must be room for a NULL-terminator. The third parameter
    // contains the number of characters excluding the NULL-terminator.
    hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
    if (SUCCEEDED(hr))
        {
        if (len>127)
          {
            len = 127;
          }
        }   
    else
        {
          // TODO: Write an error handler;
        }
    // The second parameter of StringCchCopy is 128 because you need 
    // room for a NULL-terminator.
    hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
    // Make sure the description is null terminated.
    catinfo.szDescription[len + 1] = '\0';
 
    hr = pcr->RegisterCategories(1, &catinfo);
    pcr->Release();
 
    return hr;
}
 
// HRESULT RegisterCLSIDInCategory -
//      Register your component categories information 
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
    ICatRegister *pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
                NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Register this category as being "implemented" by the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }
 
    if (pcr != NULL)
        pcr->Release();
            
    return hr;
}
 
// HRESULT UnRegisterCLSIDInCategory - Remove entries from the registry 
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    ICatRegister *pcr = NULL ;
    HRESULT hr = S_OK ;
 
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
            NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Unregister this category as being "implemented" by the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
    }
 
    if (pcr != NULL)
        pcr->Release();
 
    return hr;
}

简单MFC ActiveX插件例子
简单MFC ActiveX插件例子

6、在MFC_ActiveX_2.cpp文件中,添加CLSID_SafeItem的定义:
简单MFC ActiveX插件例子
其中的数值,是根据MFC_ActiveX_2Ctrl.cpp中的IMPLEMENT_OLECREATE_EX(实际上就是ActiveX的CLASSID)获取的。
简单MFC ActiveX插件例子

7、另外,MFC_ActiveX_2.cpp中起始处还需引入两个头文件
简单MFC ActiveX插件例子
8、修改MFC_ActiveX_2.cpp中DllRegisterServer和DllUnregisterServer函数

// DllRegisterServer - 将项添加到系统注册表
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
	HRESULT hr;    // HResult used by Safety Functions

	AFX_MANAGE_STATE(_afxModuleAddrThis);

	if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
		return ResultFromScode(SELFREG_E_TYPELIB);

	if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
		return ResultFromScode(SELFREG_E_CLASS);

	// Mark the control as safe for initializing.

	hr = CreateComponentCategory(CATID_SafeForInitializing,
		L"Controls safely initializable from persistent data!");
	if (FAILED(hr))
		return hr;

	hr = RegisterCLSIDInCategory(CLSID_SafeItem,
		CATID_SafeForInitializing);
	if (FAILED(hr))
		return hr;

	// Mark the control as safe for scripting.

	hr = CreateComponentCategory(CATID_SafeForScripting,
		L"Controls safely  scriptable!");
	if (FAILED(hr))
		return hr;

	hr = RegisterCLSIDInCategory(CLSID_SafeItem,
		CATID_SafeForScripting);
	if (FAILED(hr))
		return hr;

	return NOERROR;
}


// DllUnregisterServer - 将项从系统注册表中移除
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
	AFX_MANAGE_STATE(_afxModuleAddrThis);

	// 删除控件初始化安全入口.   
	HRESULT hr = UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);

	if (FAILED(hr))
		return hr;

	// 删除控件脚本安全入口   
	hr = UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);

	if (FAILED(hr))
		return hr;

	if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
		return ResultFromScode(SELFREG_E_TYPELIB);

	if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
		return ResultFromScode(SELFREG_E_CLASS);

	return NOERROR;
}

9、编译工程,生成MFC_ActiveX_2.ocx。接下来进行注册,管理员身份运行cmd,进入到MFC_ActiveX_2.ocx目录,通过命令“regsvr32 MFC_ActiveX_2.ocx”注册。
简单MFC ActiveX插件例子
10、在注册表—》HKEY_CLASSES_ROOT—》直接键盘输出MFC找到我们注册信息。
简单MFC ActiveX插件例子
也可以通过在工程下—》MFC_ActiveX_2.idl,找到这个值
简单MFC ActiveX插件例子

11、之后我们就可以写一份html来调用看看了,通过IE浏览器打开

<HTML>  
<HEAD>  
<TITLE>Test ActiveX</TITLE>  

    <script language="javascript" type="text/javascript">
        function functionInfo() {
		var result = Dean.CalFun(1.1,3.3);
		alert(result);
        }
    </script>

</HEAD>  
<OBJECT ID="Dean" WIDTH=528 HEIGHT=545 classid="CLSID:7BA07224-5176-4C69-8084-4960D8F67DDC">  
    <PARAM NAME="_Version" VALUE="65536">  
    <PARAM NAME="_ExtentX" VALUE="12806">  
    <PARAM NAME="_ExtentY" VALUE="1747">  
    <PARAM NAME="_StockProps" VALUE="0">  
</OBJECT> 
<body>
<input type="button" value="test" onclick="functionInfo()">
</body> 
</HTML> 
上一篇:Serverless:重新定义DevOps


下一篇:输入几行代码,轻松迁移 SpringBoot 应用上云