开发过程中一些经验总结

以下总结主要由李俊峰(lijunfeng 00165774/huawei,)、李伟(liwei 00165242/huawei,)、姜川(j00132245)总结

1.自定义CListCtrl,使用自定义列表头CHeaderCtrl

在自定义CListCtrl的列表头时,需要替换系统自带的CHeaderCtrl,网上代码的处理方式通常是在自定义的MyListCtrl中重写PreSubclassWindow,并在其中调用(其中m_MyHeaderCtrl是自定义的CHeaderCtrl,作为MyListCtrl的成员变量

if(GetHeaderCtrl())

m_MyHeaderCtrl.SubclassWindow(GetHeaderCtrl()->m_hWnd);

这种方法在MFC桌面程序中可以奏效。但是放到ActiveX中时,此处的GetHeaderCtrl()==NULL,所以无法达到替换表头的效果(具体原理未知,有兴趣的同学可以研究)。解决办法是在创建自定义的MyListCtrl之后手动调用

m_MyHeaderCtrl.SubclassWindow(GetHeaderCtrl()->m_hWnd);

当然需要把这个包装成一个InitMyHeader之类的public方法放到MyListCtrl中。

完整代码请参考VAEListCtrl和VideoListCtrl及其使用。

2.ActiveX窗口上的自定义控件添加ToolTip

为自定义控件添加ToolTip时,一般做法是在PreTranslateMessage中添加如下代码:

if (NULL != m_pToolTipCtrl)

m_pToolTipCtrl->RelayEvent(pMsg);

希望CToolTipCtrl能够捕获鼠标移动等消息,但是结果PreTranslateMessage方法在ActiveX程序中不会执行(经验证在ProjectName+Ctrl(即整个ActiveX获得输入焦点)时PreTranslateMessage方法会执行)。

解决办法是为控件添加OnMouseMove消息响应,在OnMouseMove(UINT nFlags, CPoint point)方法中添加代码:

//构造一个MSG

MSG msg;

msg.hwnd = m_hWnd;

msg.message = WM_MOUSEMOVE;

msg.wParam = LOWORD(point.x);

msg.lParam = LOWORD(point.y);

msg.time = 0;

msg.pt.x = LOWORD(point.y);

msg.pt.y = HIWORD(point.y);

m_ToolTip.RelayEvent(&msg);

这样才会使鼠标在控件上移动时显示ToolTip,但是要求要先点选过该控件才行。如果想要更进一步去掉这个先点选控件的限制,则需要在自定义控件的父窗口中响应OnMouseMove消息,并构造MSG关联到ToolTip。此时需要注意point的坐标转换。

完整的相关代码(PTZControlWnd和BitmapSlider)如下:

父窗口PTZControlWnd:

//成员变量声明

CBitmapSlider m_bsSpeedOrStepsize;

void PTZControlWnd::OnMouseMove(UINT nFlags, CPoint point)

{

   (void)nFlags;

UpdateToolTipText();//更新ToolTip文字

m_bsSpeedOrStepsize->RelayToolTipEventFromParent(point);//此处的point的坐标是相对PTZControlWnd的

    VAEBaseWnd::OnMouseMove(nFlags, point);

}

控件CBitmapSlider

//成员变量声明

CToolTipCtrl m_ToolTip;

void CBitmapSlider::RelayToolTipEventFromParent(CPoint &point)

{

//将相对父窗口的坐标转换成屏幕坐标

GetParent()->ClientToScreen(&point);

//从屏幕坐标转换成相对控件自身CBitmapSlider的坐标

ScreenToClient(&point);

//因为在CBitmapSlider::OnMouseMove中也要用到,所以提取成函数

    RelayToolTipEvent(point);

}

void CBitmapSlider::RelayToolTipEvent(const CPoint &point )

{

    if (m_ToolTip.m_hWnd != NULL)

    {

        //构造一个MSG

        MSG msg;

        msg.hwnd = m_hWnd;

        msg.message = WM_MOUSEMOVE;

        msg.wParam = LOWORD(point.x);

        msg.lParam = LOWORD(point.y);

        msg.time = 0;

        msg.pt.x = LOWORD(point.y);

        msg.pt.y = HIWORD(point.y);

        m_ToolTip.RelayEvent(&msg);

    }

}

为整个ActiveX添加ToolTip的方法可以参考MSDN,同样没有使用PreTranslateMessage方法

http://support.microsoft.com/kb/141871/zh-cn

 

3.MFC ActiveX控件添加对外接口

打开类视图,找到ProjectName+Lib,此处为NVS_VAELib

在_D+ProjectName(此处为_DNVS_VAE)上右键弹出菜单,选择添加方法

弹出窗口如下所示,填写相关内容,注意字符串类型参数需要选择BSTR。

填写完毕点击『完成』,如果出现错误提示,可以关闭VisualStudio,删除解决方案文件夹下的“.ncb”文件,然后重新打开解决方案再添加方法。

修改已经添加的对外接口签名时注意除了声明和实现外还需要在“.idl”文件中更改相应的调度接口。

4.对外接口BSTR参数转换为char *

生成的方法签名中的对应BSTR类型的是LPCTSTR。

将javascript传进来的Unicode字符串转换为内部接口使用的char*,需要使用MFC宏,

USES_CONVERSION;

char * pszCameraID = W2A(bstrCameraID);

5.关于网页的刷新

当ocx加载在网页上时,如果F5刷新,ocx控件会销毁ocx的窗口类,但是ocx的app类是不销毁的,

只有当网页关闭时,才销毁app类。

1 刷新引起的问题

当app类中有成员变量时,请注意刷新回来后变量的值还是刷新前的值。

2 利用刷新app类的不析构恢复刷新前的状态

可在控件的APP类中保存刷新前的值,刷新后恢复刷新前的状态

6.一个网页中加载两次(或者多次)OCX控件

同一进程加载两次控件时,app类调用一次,ocx窗口类调用两次。也就是说两个控件实例使用的是同一个app类的实例,只是有各自的窗口。这时如果app类中有成员变量,值得注意。

7.当将UNICODE字符串转化为多字符集字符串时注意的问题

当unicode字符串中含有汉字时,注意转化前后的字符串长度。

例如:TCHAR* pUnicde=_T("abc例子"); // pUnicde长度5

char* pMutiBtye=T2A(pUnicde); // pMutiBtye长度是7,一个汉字占两个字节

8.开发DLL等控件时,加载字符串/图片等资源失败的原因

MFC的对话框装载资源是通过获取当前线程对应的ModuleState保存的ResourceHandler来装载资源的。

所以,DLL里的代码,需要在函数的入口,首先把当前执行线程的ModuleState换成该Dll的State,这样才能装载该dll的资源

即:使用AFX_MANAGE_STATE(AfxGetStaticModuleState());

9.SetEventPulseEvent的区别

SetEvent为设置事件对象为有信号状态;而PulseEvent也是将指定的事件设为有信号状态,不同的是如果是一个人工重设事件,

正在等候事件的、被挂起的所有线程都会进入活动状态,函数随后将事件设回,并返回;如果是一个自动重设事件,

则正在等候事件的、被挂起的单个线程会进入活动状态,事件随后设回无信号,并且函数返回。

也就是说在自动重置模式下PulseEvent和SetEvent的作用没有什么区别,但在手动模式下PulseEvent就有明显的不同,

可以比较容易的控制程序是单步走,还是连续走。如果让循环按要求执行一次就用PulseEvent,如果想让循环连续不停的运转就用SetEvent,

在要求停止的地方发个ResetEvent就OK了。

转载于:https://www.cnblogs.com/snben/archive/2012/09/25/2701125.html

ActiveX控件开发总结(续二)相关推荐

  1. 使用ActiveX控件开发网页常见的问题

    1. 什么是ActiveX 控件? Microsoft® ActiveX™ 控件是由软件提供商开发的可重用的软件组件.使用 ActiveX控件,可以很快地在网址.台式应用程序.以及开发工具中加入特殊的 ...

  2. VB6.0 ActiveX 控件开发详解 [第一章:创建工程]

    前言 在CSDN的VB论坛上,我总是能够看见有人这样问"有没有这样的控件,一个列表框,每一个项前面有一个按钮"(这是例子),又或者见到这样:"怎么样做一个ActiveX控 ...

  3. ActiveX控件开发总结

    创建ActiveX工程: 可以使用VC建立MFC工程或者ATL工程来进行ActiveX控件开发.使用MFC方式建立,系统会自动实现一些ActiveX控件必须的接口,开发人员只需关注业务就可以了:使用A ...

  4. VC ActiveX 控件 开发总结

    VC 制作ActiveX 控件(OCX) http://ileson.iteye.com/blog/1002910 1.vc6下建立一下activeX工程     详见http://hi.baidu. ...

  5. Visual Studio 2012 C# ActiveX控件开发总结

    目  录 一.ActiveX控件的开发 二.ActiveX控件的部署 三.测试 四.ActiveX控件打包(.cab)与客户端自动安装 ActiveX 控件以前也叫做OLE 控件或OCX 控件,它是一 ...

  6. ActiveX控件开发

    要使用C#实现一个ActiveX控件,需要解决三个问题: 1.使.NET组件能够被COM调用 2.在客户机上注册后,ActiveX控件能通过IE的安全认证 3.未在客户机上注册时,安装包能通过IE的签 ...

  7. ActiveX控件开发(转)

    linek: http://www.cnblogs.com/RCFans/archive/2008/11/15/1333982.html 要使用C#实现一个ActiveX控件,需要解决三个问题: 1. ...

  8. C# ActiveX控件开发_1494

    要使用C#真隐一个ActiveX控件,须要解决三个答题: 1.使.NET组件可以被COM调用 2.在客户机上注册后,ActiveX控件能通功IE的平安认证 3.已在客户机上注册时,安装包能通过IE的签 ...

  9. 基于MFC的ActiveX控件开发

    转自:http://www.cnblogs.com/lidabo/archive/2012/12/04/2800921.html ActiveX 控件是基于组件对象模型 (COM) 的可重用软件组件, ...

最新文章

  1. Delphi XE5 常用功具与下载
  2. 女生零基础学软件测试难不难
  3. String 转 const char*
  4. mvc:default-servlet-handler标签的作用
  5. phpize增加php模块
  6. 大厂都在拆中台了,为什么我们还死磕到底?
  7. 如何快速打通 Docker 镜像发布流程?
  8. Python常用库大全
  9. Docker 搭建 YApi 可视化接口管理平台
  10. IOS流媒体播放器V1.1_rtsp、rmtp、m3u8、mms、mmsh
  11. php话费充值,手机话费充值接口
  12. 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(神奇的数)
  13. 视频编码码率控制:CBR、VBR和ABR
  14. 解决mysql保存数据SQLException: Incorrect string value: ‘\xF0\x9F\x91\x87\xE5\x91...‘ for column ‘错误
  15. 高德地图 街道范围_高德地图推出货车导航,解决3000万货车司机出行痛点
  16. 力扣解题思路:488. 祖玛游戏
  17. ./sbin/start-dfs.sh 开启NameNode 和 DataNode 守护进程报错
  18. SkeyeVSS综合安防视频云服务H5无插件直播点播实现HEVC H265 300毫秒以内低延迟播放
  19. 小蛮与QQ堂的故事 ——外挂作者的缅怀
  20. mybatisplus学习之通用的Service(四)

热门文章

  1. Dart ?? ?.
  2. win7安装mysql5.7.16后,执行update语句导致mysql服务停止
  3. Geometric Search
  4. 天干地支计算公式_天干地支怎么算 计算方法
  5. 申请SSL证书验证域名所有权限的其他方法Alternative Methods of Domain Control Validation (DCV)
  6. Android程序员搭建一个属于自己的服务器
  7. 【转】InstallSheild创建网站的脚本 mkw3site.vbs
  8. Hibernate+Spring+Struts2+ExtJS开发CRUD功能
  9. VS2019修改背景+高度自定义字体颜色
  10. jQuery -- 光阴似箭(二):jQuery效果的使用