最终的插件可供MFC程序调用,也可供浏览器调用(仅IE浏览器支持)
1、创建MFC ActiveX控件,这里项目命名为MFC_ActiveX_2
2、项目属性—》配置属性—》常规—》MFC的使用,选择“在静态库中使用MFC”。
模块定义文件,创建项目时已自动配置好。
3、类视图—》MFC_ActiveX_2Lib—》右键_DMFC_ActiveX_2—》添加方法
这里添加一个返回类型为“DOUBLE”,方法名为“CalFun”,拥有两个参数类型为DOUBLE参数的方法。
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;
}
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;
}
6、在MFC_ActiveX_2.cpp文件中,添加CLSID_SafeItem的定义:
其中的数值,是根据MFC_ActiveX_2Ctrl.cpp中的IMPLEMENT_OLECREATE_EX(实际上就是ActiveX的CLASSID)获取的。
7、另外,MFC_ActiveX_2.cpp中起始处还需引入两个头文件
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”注册。
10、在注册表—》HKEY_CLASSES_ROOT—》直接键盘输出MFC找到我们注册信息。
也可以通过在工程下—》MFC_ActiveX_2.idl,找到这个值
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>