基于MFC的网页ActiveX控件开发全程实录1(ActiveX控件创建和网页端嵌入)
1. 创建ActiveX控件以管理员身份运行VS2010(这里注意,一定要确保当前处于管理员运行状态,否则后续注册控件的时候会有问题),新建MFC ActiveX项目下一步,“运行时许可证”不用勾选,下一步,勾选“在插入对话框中可用”点击完成。修改输出环境为release 32位修改项目属性:选择菜单栏项目——ActiveXDemo属性——配置属性——常规修改...
1. 创建ActiveX控件
以管理员身份运行VS2010(这里注意,一定要确保当前处于管理员运行状态,否则后续注册控件的时候会有问题),新建MFC ActiveX项目
下一步,“运行时许可证”不用勾选,下一步,勾选“在插入对话框中可用”
点击完成。
修改输出环境为release 32位
修改项目属性:选择菜单栏项目——ActiveXDemo属性——配置属性——常规
修改两处地方 “MFC的使用”和“字符集”,如下图所示
修改完点击确认即可
插入对话框,修改属性 visible改为true,style改为child
为新建的对话框新建类CActiveXDlg
在CActiveXDemoCtrl类的头文件中引用刚才的类
#include "ActiveXDlg.h"
在public中定义该对话框的一个对象
CActiveXDlg m_MyDlg;
接下来为CActiveXDemoCtrl类添加WM_CREATE消息响应OnCreate函数,添加代码如下
int CActiveXDemoCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
m_MyDlg.Create(IDD_DIALOG1,this); //初始化对话框
return 0;
}
上述步骤主要将新建的对话框对象绑定到控件上,接下来需要在控件上显示该对话框。编辑CActiveXDemoCtrl类的OnDraw函数,注释掉两行绘图代码,改成下面的形式:
void CActiveXDemoCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)
return;
// TODO: 用您自己的绘图代码替换下面的代码。
//pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
//pdc->Ellipse(rcBounds);
m_MyDlg.MoveWindow(rcBounds,true);
}
然后我们在刚开始间建的对话框上建立一个测试函数,具体步骤:删除确定和取消按钮,添加一个新按钮,修改caption为测试,如下图
双击添加测试按钮的响应函数如下
void CActiveXDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox("我的第一个网页ActiveX测试");
}
最后生成解决方案,生成过程中可能会出现如下错误
这个主要是因为没有管理员权限,无法完成控件注册造成的。
解决办法(1)退出当前VS,重新以管理员身份打开再运行即可。
(2)还有一种办法,通过cmd命令窗口手工进行注册(注意,cmd命令窗口同样需要以管理员身份运行)
D:\code\ActiveXDemo\Release>regsvr32 ActiveXDemo.ocx
注册成功后会弹出下面的提示
同理,如果需要手工卸载某个控件用如下cmd命令即可
D:\code\ActiveXDemo\Release>regsvr32 /u ActiveXDemo.ocx
2.创建html页面并导入ActiveX控件
页面代码如下
<HTML>
<HEAD>
<TITLE>基于MFC的ActiveX控件全程实录</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
</HEAD>
<BODY>
<OBJECT ID="Test_js" WIDTH=200 HEIGHT=300
CLASSID="CLSID:B852A7D3-3356-400E-A2BF-A15F7D0F99CB">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2646">
<PARAM NAME="_ExtentY" VALUE="1323">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
</BODY>
</HTML>
这里唯一需要注意的地方就是对应的CLASSID号
我们找到刚才建的ActiveX,在源文件中找到ActiveXDemo.idl,双击打开即可找到该ID号
这里主要,会有好几个uuid号,我们需要的是注释 “// CActiveXDemoCtrl的类信息” 下面的uuid号。把这个uuid号复制到html文件中指定的位置即可。
用IE浏览器打开刚才的html页面
一般情况下,由于IE保护机制,打开网页后会出现下图所示对话框
这里我们先不管,点击是。然后会出现我们的activex控件,点击测试按钮,出现下图
另外,有些人的机器每次加载时还会提示是否允许加载activeX控件的提示,老是显示这个就比较讨厌。解决方法如下:
IE浏览器——internet选项——高级,勾选“允许活动内容在我的电脑的文件中运行”
3. 修改控件的信息安全
为了避免每次打开网页都弹出下面的对话框,我们需要对控件进行信息安全认证
具体步骤如下
(1)在ActiveXDemoCtrl.h文件中引入文件
#include <objsafe.h>
然后在CActiveXDemoCtrl类的protected部分添加下面的代码
//去掉安全警告 BEGIN
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(ObjectSafety, IObjectSafety)
STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions);
STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions);
END_INTERFACE_PART(ObjectSafety)
//去掉安全警告 END
最后在ActiveXDemoCtrl.cpp文件的 “IMPLEMENT_DYNCREATE(CActiveXDemoCtrl, COleControl)” 下面添加下述代码
//去掉安全警告 BEGIN
BEGIN_INTERFACE_MAP(CActiveXDemoCtrl, COleControl)
INTERFACE_PART(CActiveXDemoCtrl, IID_IObjectSafety, ObjectSafety)
END_INTERFACE_MAP()
// Implementation of IObjectSafety
STDMETHODIMP CActiveXDemoCtrl::XObjectSafety::GetInterfaceSafetyOptions(
REFIID riid,
DWORD __RPC_FAR *pdwSupportedOptions,
DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE_EX(CActiveXDemoCtrl, ObjectSafety)
if (!pdwSupportedOptions || !pdwEnabledOptions)
{
return E_POINTER;
}
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER
| INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = 0;
if (NULL == pThis->GetInterface(&riid))
{
TRACE("Requested interface is not supported.\n");
return E_NOINTERFACE;
}
// What interface is being checked out anyhow?
OLECHAR szGUID[39];
int i = StringFromGUID2(riid, szGUID, 39);
if (riid == IID_IDispatch)
{
// Client wants to know if object is safe for scripting
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
return S_OK;
}
else if (riid == IID_IPersistPropertyBag
|| riid == IID_IPersistStreamInit
|| riid == IID_IPersistStorage
|| riid == IID_IPersistMemory)
{
// Those are the persistence interfaces COleControl derived controls support
// as indicated in AFXCTL.H
// Client wants to know if object is safe for initializing from persistent data
*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
return S_OK;
}
else
{
// Find out what interface this is, and decide what options to enable
TRACE("");
return E_NOINTERFACE;
}
}
STDMETHODIMP CActiveXDemoCtrl::XObjectSafety::SetInterfaceSafetyOptions(
REFIID riid,
DWORD dwOptionSetMask,
DWORD dwEnabledOptions)
{
METHOD_PROLOGUE_EX(CActiveXDemoCtrl, ObjectSafety)
OLECHAR szGUID[39];
// What is this interface anyway?
// We can do a quick lookup in the registry under HKEY_CLASSES_ROOT\Interface
int i = StringFromGUID2(riid, szGUID, 39);
if (0 == dwOptionSetMask && 0 == dwEnabledOptions)
{
// the control certainly supports NO requests through the specified interface
// so it"s safe to return S_OK even if the interface isn"t supported.
return S_OK;
}
// Do we support the specified interface?
if (NULL == pThis->GetInterface(&riid))
{
TRACE1("%s is not support.\n", szGUID);
return E_FAIL;
}
if (riid == IID_IDispatch)
{
TRACE("");
TRACE("In other words, is the control safe for scripting?\n");
if (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask
&& INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions)
{
return S_OK;
}
else
{
return E_FAIL;
}
}
else if (riid == IID_IPersistPropertyBag
|| riid == IID_IPersistStreamInit
|| riid == IID_IPersistStorage
|| riid == IID_IPersistMemory)
{
TRACE("");
TRACE("In other words, is the control safe for initializing from persistent data?\n");
if (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask
&& INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions)
{
return NOERROR;
}
else
{
return E_FAIL;
}
}
else
{
TRACE1("", szGUID);
return E_FAIL;
}
}
STDMETHODIMP_(ULONG) CActiveXDemoCtrl::XObjectSafety::AddRef()
{
METHOD_PROLOGUE_EX_(CActiveXDemoCtrl, ObjectSafety)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CActiveXDemoCtrl::XObjectSafety::Release()
{
METHOD_PROLOGUE_EX_(CActiveXDemoCtrl, ObjectSafety)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CActiveXDemoCtrl::XObjectSafety::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(CActiveXDemoCtrl, ObjectSafety)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
//去掉安全警告 END
重新生成解决方案即可
最后给出代码链接 https://download.csdn.net/download/qianbin3200896/10585896 还不明白的朋友可以参照该代码(vs2010)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)