ActiveX工程创建与开发详解

前言

当有些网页应用出于性能、保密等考虑,需要额外开发插件,不同的浏览器支持的插件是不一样的,下面以IE的插件开发进行详细说明。

插件的IDE工具是VS2012.

创建ActiveX工程

打开VS2012,创建新工程,选择如下工程类型:

点击确定后,按照默认设置,点击完成,自动生成如下文件。

其中,UUID是插件的ID,它用于网页的调用:

在网页中调用如下代码所示:

<center>
	<object ID="MFCActiveX" height=768 width=1024
		CLASSID="CLSID:E976D19A-D0DA-4DFE-AC83-C155AB0EE7C9"
		CODEBASE="./MFCActiveX.cab#Version=1,0,0,0">
	</object>
</center>

供网页调用的外部接口

插件需要提供外部接口,供网页调用,例如登录接口。可以参考【AboutBox】接口进行添加,在【MFCActiveXControl1.idl】文件里添加接口声明:

//  CMFCActiveXControl1Ctrl 的主调度接口
	[ 
		uuid(8497EC9C-262F-4A76-8B24-40244D39A63B)	
	]
	dispinterface _DMFCActiveXControl1
	{
		properties:
		methods:

			[id(DISPID_ABOUTBOX)] void AboutBox();
			// 登录
			[id(1), helpstring("method Login")] void Login(BSTR swzUserName, BSTR swzUserPw, BSTR swzIP, short iLang);
	};

在【MFCActiveXControl1Ctrl.cpp】文件添加接口的实现里:

// 调度映射

BEGIN_DISPATCH_MAP(CMFCActiveXControl1Ctrl, COleControl)
	DISP_FUNCTION_ID(CMFCActiveXControl1Ctrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION_ID(CMFCActiveXControl1Ctrl, "Login", 1, Login, VT_EMPTY, VTS_BSTR VTS_BSTR VTS_BSTR VTS_I2)
END_DISPATCH_MAP()

在【MFCActiveXControl1Ctrl.h】文件里声明接口实现的函数头形式:

protected:
	// 登录
	void Login(LPCTSTR swzUserName, LPCTSTR swzUserPw, LPCTSTR swzIP, short iLang);

在【MFCActiveXControl1Ctrl.cpp】文件里实现登录的接口:

// 登录
void CMFCActiveXControl1Ctrl::Login(LPCTSTR swzUserName, LPCTSTR swzUserPw, LPCTSTR swzIP, short iLang)
{

	// TODO: Add your dispatch handler code here
}

此外,还可以通过类视图,自动添加函数、变量和事件,但是这里添加的不是外部接口,不支持网页调用。具体添加如下:

说明:此前我接手一个ActiveX的项目,都是手工描画的页面,没有使用MFC的CDialog。维护非常不方便,感觉很奇怪。时间上ActiveX的内部页面开发跟App的UI开发没什么不一样。

网页调用的ActiveX的接口如下:

<script language="javascript" type="text/javascript" for="MFCActiveX" event="PrepareInitInfo">
		var lang = "cn";
		LogCount++;
		if(LogCount <= 1)
		{
			MFCActiveX.Login(szUserName,szPass,szHostIp,"1");
			document.getElementById("MFCActiveX").height=document.documentElement.clientHeight - 20; 
			document.getElementById("MFCActiveX").width=document.documentElement.clientWidth - 20;
		}
  	</script>

ActiveX推送消息给网页

网页接收ActiveX的事件,在idl文件里声明:

//  CMFCActiveXControl1Ctrl 的事件调度接口

	[ 
		uuid(DF467D9D-D259-4A94-8AA0-CBCE1D9F4A9F)	
	]
	dispinterface _DMFCActiveXControl1Events
	{
		properties:
			//  事件接口没有任何属性

		methods:
			// 登录返回的消息
			[id(1)] void ReLogin(int iError, int iLang);
			// 插件初始化消息
			[id(2)] void PrepareInitInfo(void);
	};

在【MFCActiveXControl1Ctrl.h】文件里实现推送给网页的消息接口:

private:
	// 已经调用Relogin发送错误CODE的标志
	bool	m_hasEmittedReloginError;
// 事件映射
	DECLARE_EVENT_MAP()// Dispatch and event IDs
public:
	enum {
		eventidReLogin = 1L,
		eventidPrepareInitInfo,
		dispidLogin = 1L
	};
protected:
	// 登录
	void Login(LPCTSTR swzUserName, LPCTSTR swzUserPw, LPCTSTR swzIP, short iLang);
public:
	// 推送登录返回消息
	void FireReLogin(int iError, int iLang)
	{
		// 已调用过,则返回
		if (m_hasEmittedReloginError)
		{
			return;
		}
		// 设置标志
		m_hasEmittedReloginError = true;
		FireEvent(eventidReLogin, EVENT_PARAM(VTS_I2 VTS_I2),iError,iLang);
	}
	// 推送初始化消息【网页应该等待插件初始化完成后,再进行登录】
	void FirePrepareInitInfo(void)
	{
		FireEvent(eventidPrepareInitInfo, EVENT_PARAM(VTS_NONE));
	}

最后贴上网页【index.asp】调用的完整示例:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Distributive Vision Control System</title>
</head>

<body>
	<script language="javascript">
		var LogCount = 0;
		var lang = "cn";
		var szUserName = new String("<%=Request.Form("UserName")%>");
		var szPass = new String("<%=Request.Form("Pass1")%>");
		var szHostIp = new String("<%=Request.ServerVariables("SERVER_NAME")%>");//new String("192.168.3.12");//

		if((szUserName == "undefined" || szUserName == null || szUserName == "") && (szPass == "undefined" || szPass == null || szPass == ""))
		{
			self.location="login_cn.asp"; 
		}
	</script>

<center>
	<object ID="MFCActiveX" height=768 width=1024
		CLASSID="CLSID:E976D19A-D0DA-4DFE-AC83-C155AB0EE7C9"
		CODEBASE="./MFCActiveX.cab#Version=1,0,0,0">
	</object>
</center>

	<script language="javascript">
		window.onresize = function () 
		{	
			document.getElementById("MFCActiveX").height=(document.documentElement.clientHeight-20)>768?(document.documentElement.clientHeight-20):768; 
			document.getElementById("MFCActiveX").width=(document.documentElement.clientWidth-20)>1024?(document.documentElement.clientWidth-20):1024;
		}
	</script>
	

	<script language="javascript" type="text/javascript" for="MFCActiveX" event="PrepareInitInfo">
		var lang = "cn";
		LogCount++;
		if(LogCount <= 1)
		{
			MFCActiveX.Login(szUserName,szPass,szHostIp,"1");
			document.getElementById("MFCActiveX").height=document.documentElement.clientHeight - 20; 
			document.getElementById("MFCActiveX").width=document.documentElement.clientWidth - 20;
		}
  	</script> 
 
  	<script language="javascript" type="text/javascript" for="MFCActiveX" event="ReLogin(error,iLang)">
                iLang = 1;	
		if(iLang == 1)
		{
			lang = "cn";
				
			if(error == -1){
				alert("登录超时,请检查网络连接。");
				self.location="login_cn.asp?error="; 
				//
			}
			else if(error == -2){
				alert("用户账户名或密码错误!");
				self.location="login_cn.asp?error="; 

			}
			else if(error == -3){
				alert("登录帐户不存在!");
				self.location="login_cn.asp?error=";

			}
			else{
				self.location="login_cn.asp?error=";
				window.opener=null; window.open('','_self',''); window.close();
			}
		}
		
  	</script> 
 
<script> 
   lock = function(theEvent) {
        if (theEvent != null) {
                event = theEvent;
        }
        // 擋滑鼠右鍵選單事件
        if (event.type == "contextmenu") {
            return false;
        // 擋滑鼠中鍵事件
        } else if (event.type == "mousedown") {
        	// 擋滑鼠左鍵事件
                if (event.button == 1) {
                        return false;
                }
        	// 擋滑鼠右鍵事件
                if (event.button == 2) {
                        return false;
                }
        	// 擋滑鼠中鍵事件
                if (event.button == 4) {
                        return false;
                }
	}
	// 屏蔽按住Ctrl键或者鼠标滚动
	else if (event.ctrlKey || event.type == "mousewheel") {
		return false;
        } 
        // 擋 IE 按下 F1 鈕時會觸發的 onhelp 事件
	else if (event.type == "help") {
            return false;
        // 擋特定按鍵
        } else if (event.type == "keydown") {
		//alert('catch key down['+event.keyCode+']');
		// 屏蔽Backspace、F5
		if (event.keyCode == 8 || event.keyCode == 116) {
                    return false;
		}
            // 擋 alt、ctrl鍵
            if (event.altKey || event.ctrlKey) {
                    return false;
            }
            // 擋 F3 ~ F10 功能鍵,其中此種寫法只能擋 FF 的 F1 鍵,無法擋 IE 的 F1 鍵
            if (event.keyCode >= 114 && event.keyCode <= 121) {
		//alert('catch Fx key['+event.keyCode+']');
                    try {
                            // IE 要將 keyCode 設為 0 才能真正擋功能鍵,
                            // 但 FF 會丟 Exception,所以用 try-cache 擋住
                            event.keyCode = 0; 
                    } catch(e){}
                    return false;
            }
        }
}

document.onmousedown = lock;
document.onmousewheel = lock;
document.onmouseup = lock;
document.oncontextmenu = lock;
document.onkeydown = lock;
window.onhelp = lock; 
 
</script>
</body>
</html>

 

示例代码请参考:

https://download.csdn.net/download/ptrunner/11082512

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值