串口通信

       调试一个MSComm的串口通信程序一直报错"f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\occcont.cpp Line:926",网上搜了下说是控件没有注册,然后"regsvr32 MSComm32.ocx"注册后就正常了。可能是程序用到这个activeX控件但是之前没有注册导致调试出现错误。

        关键字"activex 网页插件"搜到文章<使用VS2010开发ActiveX(MFC)控件(2)>,在该系列文章的第二篇"界面显示"部分指出要对新建的一个对话框,将其属性System改为False,对话框资源没有这个属性可能是"System Menu"属性。在文章的最后用一个html文件测试,其中classid要与创建的activex工程的uuid参数匹配,打开工程的idl文件一开始想当然以为是该文件的第一个uuid,然后用ie打开html后没有任何反应,后来参考了文章<vs2010开发activex(MFC)控件/ie插件(一)>发现其实是文章的最后一个uuid,修改后将测试的html拖动到ie上然后会提示"Internet Explorer已限制此网页运行脚本或ActiveX控件",选择"允许阻止的内容"后会弹出"在此页上的ActiveX控件和本页上的其他部分的交互可能不安全。你想允许这种交互吗?"选择是后就可以看到控件的界面了。然后是参看第三篇文章<添加接口及WEB调用>,在该文章中先定义了一个具体的实现函数,作用就是在编辑框上显示文字,然后类视图下在xxxLib下的_Dxxx右键添加接口,其中xxx代表了activex工程的名字,然后在文章的最后的html中调用了这个接口函数,注意一定要换成自己的接口名称否则没有反应。

       添加属性与添加接口一样,即类视图下在xxxLib下的_Dxxx右键添加属性,其中xxx代表了activex工程的名字。正如<VC++深入详解>ActiveX控件章的自定义属性小节所述,"在添加顺序ing对话框上提供了三个单选按钮,默认选择的是Member variable",如果选择Get/Set methods则并不会自动生成一个与属性名称对应的内部成员变量,如果需要在控件内部保存属性的值则需要自定义一个成员变量,注意在js页面中可以直接以属性名来访问属性,而非与属性名对应的内部成员变量。当选择选择Get/Set methods单选框后,默认会生成与属性对应的Get/Set函数,而且也不需要再添加参数。

       查看xxxCtrl.h文件(xxx代表了MFC的activex工程名),发现该头文件中声明了消息映射(让ActiveX控件程序可以接收系统发送的事件通知,如窗体创建和关闭事件),调度映射(让外部调用程序(包含ActiveX的容器)可以方便地访问ActiveX控件的属性和方法),事件映射(让ActiveX控件可以向外部调用程序(包含ActiveX的容器)发送事件通知)。也就是说对ActiveX控件的窗口操作都将在这个类中完成,包括ActiveX控件的创建,重绘,以及在此类中创建可视MFC窗体。

       用activex插件可以返回字符串给js,具体可以参考文章<一步一步实现ActiveX与js双向调用(二)>,具体做的时候用了一个属性来保存js的函数,在添加属性时候选择属性类型为IDispatch*,然后再自定义一个CComDispatchDriver类型的内部成员变量来保存js的函数,当需要调用js的函数时候直接通过这个自定义的内部成员变量执行InvokeN函数,待传递给js的字符串直接赋值给VARIANT类型变量的bstrVal字段。或者按照文章中的方式,定义一个CComPtr<IDispatch>类型的变量spCallback,判断参数的vt成员为VT_DISPATCH,然后将参数的pdispVal保存到变量spCallback中,通过该变量执行Invoke就可以调用到js的函数。但是在activeX控件中创建线程,想在线程中通过这两种方式来调用js函数就没有成功。后来先调用RegisterWindowMessage创建一个消息,然后通过ON_REGISTERED_MESSAGE宏来绑定消息的响应,当线程中需要调用js函数时执行PostMessage函数将注册消息发送到当前窗口,然后在注册消息的绑定函数中就可以成功调用js函数了,这一方式参考了libjingle中的windows异步socket的实现方法。

       js去解析json数据,这个地方网上搜了两个小时也没有搞定,后来关键字"html json 遍历"搜到文章<jquery对Json的各种遍历>,又结合文章<JavaScript中解析JSON数据的三种方法>,一开始根据这篇文章用new Function方法用vs编写html文件会有一些红色的波浪线,所以就放弃了后来结合文章<jquery对Json的各种遍历>发现还是需要先通过new Function方法将activex插件返回给js的字符串转换成json对象,然后就可以解析了。

       在html中select代表的是一个下拉框,关键字"select option 添加"搜索发现好像有两种方式JS和jQuery来添加选项,后来前端同事帮忙实现了页面加载之后将插件返回的数据动态添加到select控件中,主要是下载jquery-3.2.1.min.js然后放到测试html的同一目录下,然后在$(function(){…})这个函数中添加页面加载的代码,之前的方式是在<body onload="load()">的function load()函数中添加页面加载代码。

       sprintf_s去格式化一个CString对象时只能将第一个字符格式化,后来发现是vc程序的配置问题,工程右键属性-配置属性-常规-项目默认值-字符集从"使用Unicode字符集"修改为"使用多字节字符集"然后就可以将CString对象的所有字符格式化而非仅仅格式化第一个字符了。在html页面中并不想显示vc创建的activex控件,一开始纠结于把Ctrl类中的OnDraw函数中的代码给屏蔽掉,发现还是会显示控件,后来在html页面中将该控件的宽高属性都设置为0然后就不再显示控件了,即加上"width=0 height=0"。如果该方法不行的话可能就要尝试将vc控件的资源属性页中的对话框资源删除掉再试了。

       程序报错"error C2664: cannot convert argument 1 from 'LPCTSTR' to 'char *'",看了下程序的设置是多字节字符集而非Unicode字符街,所以直接将LPCTSTR变量强制转换为LPSTR即可,而不用调用WideCharToMultiByte函数来实现。 
posted @ 2017-10-22 17:53  wongdu  阅读(300)  评论(0编辑  收藏  举报