注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

使用OCX和Web的交互一事件和方法基本的操作  

2015-01-12 15:15:19|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

使用OCXWeb的交互一事件和方法基本的操作

有个小活儿,要求能够在本地的网页上使用摄像头来取图。大家都知道,由于安全的原因,在网页上一般是禁止访问本地的文件或者设备的。但也不是一点办法都没有,可以使用ActiveX控件(OCX)来处理这件事情。

使用VC2013创建一个MFC ActiveX项目。然后增加调用方法和回调函数机制的事件。这两个结合,基本上就可以达到从WEBC++的互相沟通和互相调用。

这里首先说一下创建事件,在类视图上右击你想添加事件的类,打开CW(类向导),点击事件,或者直接点击添加事件:

在里添加事件名称,内部名称(这个可以使用默认),看下面的图:

使用OCX和Web的交互一事件和方法基本的操作 - 还东国 - 还东国的博客

 

其会形成下面的代码:

.h文件:

void EventInden(LONG indexL, LONG indexR, LONG result)

         {

                   FireEvent(eventidEventInden, EVENT_PARAM(VTS_I4 VTS_I4 VTS_I4), indexL, indexR, result);

         }

.cpp文件:

// 事件映射

 

BEGIN_EVENT_MAP(CAXIKEmb100SCtrl, COleControl)

         EVENT_CUSTOM_ID("EventInden", eventidEventInden, EventInden, VTS_I4 VTS_I4 VTS_I4)

         EVENT_CUSTOM_ID("EventEnroll", eventidEventEnroll, EventEnroll, VTS_BSTR VTS_BSTR VTS_I4)

END_EVENT_MAP()

细心的可以发现,其对数据类型的处理采用了不同的宏定义,这是为了兼容平台所做的。

然后再用在类向导中,增加调用的方法,这里不再截图,基本相似:

int CAXIKEmb100SCtrl::TestFun()

{

         MessageBox(_T("Test"));

         this->EventInden(200,200,199);//调用回调的事件

         return 0;

}

于是开始测试,这里发现了个问题,在HTML中调用的话,死活也不出来这个对话框,一开始怀疑是不是这个对话框的调用不同,查了半天资料,也没有见有说什么的。在网上看到别人说了一句话,如果调用函数既不出错也没反应,可能是IEOCX控件有所限制,也即安全等级比较高,于是在IE里降低了等级,启用了ActiveX,并允许交互,结果还是不行。

这时又看一个人说直接调用AboutDialog没问题,于是这里也就直接调用,结果发现还真是没有问题。而且这个函数也没有什么特殊之处,于是拿出来了自己的函数比较,也没有发现什么问题。

这时候在网上看到了一些老版本的诸如VC6,VC2005,VC2008上面的介绍的方法,又查到了MSDN上的说明,都不约而同的提到了DISP_FUNCTION这个消息宏。这时再查AboutDialog和自己函数的不同,终于发现了:(下面是正确的

BEGIN_DISPATCH_MAP(CAXIKEmb100SCtrl, COleControl)

         DISP_FUNCTION(CAXIKEmb100SCtrl, "StartInden", StartInden, VT_BSTR, VTS_BSTR VTS_I4 VTS_BSTR VTS_I4 VTS_I4)

         DISP_FUNCTION(CAXIKEmb100SCtrl, "TestFun", TestFun, VT_EMPTY, VTS_NONE)

         DISP_FUNCTION_ID(CAXIKEmb100SCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)

END_DISPATCH_MAP()

于是尝试着也写了一个相应的分发宏,调用成功了。于是又增加了一个带参又有返回值的调用函数,又惹了麻烦了。首先仿照事件写了的参数,又看了宏定义,发现第一个是返回值,于是就想当然的一个个的用逗号隔开:(下面这个是原来错误的

DISP_FUNCTION(CAXIKEmb100SCtrl, "StartInden", StartInden, VTS_BSTR, VTS_BSTR VTS_I4 VTS_BSTR VTS_I4 VTS_I4)

结果总报:无法从“const char [2]”转换为“WORD””,加逗号会有一个警告,说参数过多。

后来没管他,去干别的,然后弄完了再回来弄,结果在网上查到了其用法:

DISP_FUNCTION(theClass, pszName, pfnMember, vtRetVal, vtsParams )

参数

theClass

类名。

pszName

扩展函数名。

pfnMember

成员函数名。

vtRetVal

指定函数的返回类型的值。

vtsParams

指定函数的参数列表中的一种或更多常数组成的空格分隔列表

vtsParams支持多个参数。

VTS_ 常数及其含义定义详见:http://msdn.microsoft.com/zh-cn/library/087e0w00

跳到官网上才发现,返回值不带S,而后面的参数又不用加逗号(看前面正确的)。

整个HTMLOCX的交互看下面代码:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

    <title>免驱虹膜测试页面</title>

    <script language="JavaScript" type="text/javascript">

    function js_init() {

AXIKEmb100S.AboutBox();

alert("注册成功");

//AXIKEmb100S.TestFun();

       

    }

function js_call()

{

alert("开始调试");

AXIKEmb100S.TestFun();

AXIKEmb100S.StartInden("321",8,"123",6,3);

}

 

    </script>

      <script language="javascript" type="text/javascript" for="AXIKEmb100S" event="EventInden (sleft,sright,r)">

    alert( r.toString());

         </script>

   

</head>

<body>

 

<p>

 

<object  classid="clsid:58F7D7C7-88E5-48A8-82D6-52E2612A3FA1" id="AXIKEmb100S"  style="width: 347px; height: 265px" >

 <PARAM NAME="_Version" VALUE="65536">

    <PARAM NAME="_ExtentX" VALUE="2646">

    <PARAM NAME="_ExtentY" VALUE="1323">

    <PARAM NAME="_StockProps" VALUE="0">

</object>

</p>

 

<form id="form1" method="POST" action="">

    <p>

             <input id="ButtonStop" type="button" value="初始化" onclick="return js_init()" />

</p>

       <p>

             <input id="ButtonStart" type="button" value="调用" onclick="return js_call()" />

</p>  

</form>       

</body>

</html>

 

然后是最关践的,是绘图部分,原来的图形是在Picture控件中绘制的,现在则是在OnDraw消息中绘制:

就不能采用原来的PicCDC了,得使用Paint里面的CDC,方法是一致的,重点是线程通过:

int CAXIKEmb100SCtrl::UpdateImage()
{
this->Invalidate();
this->UpdateWindow();
return 0;
}

来控制OnDraw定时刷新界面。

总是干活很急,没有办法。

  评论这张
 
阅读(3412)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017