`

VC6 COM控件增加事件支持

阅读更多

 

前一阵子写一个控件,感觉接口有些地方使用返回值控制不大方便使用,所以打算给控件增加上几个事件,结果在网上搜了很久,也看不到合适的方法,网上说的一些东西,在我的VC环境中看的时候,根本就没有办法那么操作(包括VC6和VC2010)。于是找了一个示例程序,反反复复试验了好多次,终于自己的控件能够通过事件回调了,现在把我的试验方法记录下来。(网上说的更多是在建立控件工程时增加事件,如果对于一个建立工程时没有时间支持的控件,根本没有提到的)。

 

我的试验中提到的内容,不知道是否都是必要的,我也没有在这方面再去尝试。

 

(1)修改控件类的继承列表,如果需要有事件支持,需要继承以下的类:

 

IDispatchImpl

IProvideClassInfo2Impl

IConnectionPointContainerImpl

 

 

继承这些类,有可能还需要在 BEGIN_COM_MAP 和END_COM_MAP加入相应的宏。

加入连接点支持,需要使用 BEGIN_CONNECTION_POINT_MAP、CONNECTION_POINT_ENTRY和END_CONNECTION_POINT_MAP加入连接点的宏

 

 

 

 

 

(2)IDL中声明事件支持,在Library一节中,CoClass上面,如下方式说明:

 

    importlib("stdole32.tlb");
    importlib("stdole2.tlb");
    [
        uuid(95F04622-2670-4206-AB52-03CDE8CA8074),
        helpstring("_IMyCtrlEvents Interface")
    ]

    dispinterface _IMyCtrlEvents
    {
        properties:
        methods:
        [id(1), helpstring("method OnOK")] HRESULT OnOK();
        [id(2), helpstring("method OnError")] HRESULT OnError(LONG err,BSTR msg);
    };

 

 

 

(3)实现代理类,在其中实现触发事件的代码,例如:

 


template <class T>
class CProxy_IMyCtrlEvents : public IConnectionPointImpl<T, &DIID__IMyCtrlEvents, CComDynamicUnkArray>
{
    //Warning this class may be recreated by the wizard.
public:
    HRESULT __stdcall Fire_OnOK()
    {
        CComVariant varResult;
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        int nConnections = m_vec.GetSize();
       
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                VariantClear(&varResult);
                DISPPARAMS disp = { NULL, NULL, 0, 0 };
                pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
            }
        }
        return varResult.scode;
   
    }


    HRESULT __stdcall Fire_OnError(LONG err,BSTR msg)
    {
        CComVariant varResult;
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        int nConnections = m_vec.GetSize();
       
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                VariantClear(&varResult);
                //DISPPARAMS disp = { NULL, NULL, 0, 0 };
                DISPPARAMS dispparams;
               memset(&dispparams, 0, sizeof(dispparams));
               dispparams.cArgs=2;   // 设置参数个数
               dispparams.rgvarg=new VARIANTARG[1]; // 初始化参数数组
               dispparams.rgvarg[0].vt=VT_UI4; // 第一个参数的类型
               dispparams.rgvarg[0].uintVal=(UINT)err;
               dispparams.rgvarg[1].vt=VT_BSTR; // 第一个参数的类型
               dispparams.rgvarg[1].bstrVal=(BSTR)msg;              

                pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, NULL, NULL);
            }
        }
        return varResult.scode;
   
    }
};

 

 

 

我们可以看到,触发事件的FireEvent实现中,特殊之处在于,要把参数进行赋值,再调用定义的事件,0x1、0x2就是定义的事件。

 

 

实现之后,还需要在控件类定义处加入代理类,如(1)中需继承的其他类。

 

(4)有了这些之后,就可以在需要的地方触发事件,例如,在出现某种错误或情况时触发onError事件

 

(5)请注意,不要在控件所起的线程中触发事件,如果需要的话,请在线程中需要触发事件的地方给控件窗口(仅限控件有窗口的情况)发送自定义的消息,由控件窗口接收到消息后触发事件。要使用线程消息,需要在控件类定义时,在BEGIN_MSG_MAP和END_MSG_MAP中定义消息处理函数。

 

 

 

(6)一个题外话,控件类还应该继承 IObjectSafetyImpl,并在COM_MAP中声明宏,这样在浏览器中使用时,就不会弹出“在此页上的ActiveX控件和本页上的其它部分交互可能不安全”这样的提示。当然,要更好的解决安全问题,还需要考虑对控件数字签名等等方式。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1
0
分享到:
评论
4 楼 windshome 2013-12-04  
有十年不搞COM这东西了
3 楼 leaow567 2013-12-04  
同感同感啊
2 楼 windshome 2013-12-04  
其实多年前做COM类的开发时遇到过很多问题,很多也通过探索解决了,不过现在好像大部分都忘记了,而且忘得干干净净。所以从此遇到问题,解决之后就记录下来。
1 楼 leaow567 2013-12-03  
com成体系的资料太少了

相关推荐

    VC 在窗体上动态添加文本框、标签及按钮控件.rar

    一个支持事件响应 保存 读取的VC 动态控件应用示例,可以在窗体上动态添加文本框、标签及按钮控件,可以循环的添加下去,每点击一次添加按钮,就会动态添加一个控件对象,如演示截图所示的运行窗口,动态控件可被...

    vc实例精通源码,windows基本控件的使用Demo

    02_MyActiveX2 为ActiveX控件增加属性和方法。 03_ActiveXInDlg 在应用程序中使用ActiveX控件。 04_ActiveXInWeb 在浏览器中使用ActiveX控件。 05_MyActiveX3 在VC中显示动态的GIF动画。 06_RegOCX 在...

    VC60、控件、ADO、MSFlexGrid、虚表、鼠标滚动

    VC60下开发的控件,采用ADO数据库访问,根据过滤条件获取结果集并按时间顺序显示在MSFlexGrid表格上,并展现MSFlexGrid所有关键函数,同时对MSFlexGrid增加了鼠标滚动支持;为提高显示速度建立了虚表管理。

    2013 DSOFramer 最新修改控件

    自己下了网传的2.3的代码,动手修改了一下,增加了如下内容,有需要的朋友可以下来用用,代码我就不传了,还是VC6的,想升级到.net 2010但问题太多,就没升,但功能算是支持了: 1、增加了WindowSelectionChange事件...

    web截图activex控件

    新颖网络截屏插件是一款能够非常方便的将屏幕截屏图片发送到WEB服务器中的轻量级ActiveX控件,它可以...VC运行库:http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf

    Microdraw图形控件开发版本-试用版

    4. 支持多种缺省工具操作事件,缺省工具对元素进行操作都会触发相应事件; 5. 保存、打开、打印文件触发相应事件; 6. 文件上传和下载触发相应事件; 7. 选择操作后会触发相应事件; 元素支持功能: 1. 点;直线,...

    VB编程资源大全(控件 其它3)

    工业监控,数据采集,股市分析等领域的数据显示、分析、打印(305KB) 6,dxcontrol.ZIP API 函数控件,包含输入、声音、图形等(358KB) 7,gauge.ZIP 控件支持多数据处理和鼠标控制操作(232KB) 8,...

    VB编程资源大全(控件 其它1)

    工业监控,数据采集,股市分析等领域的数据显示、分析、打印(305KB) 6,dxcontrol.ZIP API 函数控件,包含输入、声音、图形等(358KB) 7,gauge.ZIP 控件支持多数据处理和鼠标控制操作(232KB) 8,...

    OSD叠加控件5.0版

    OSD叠加控件4.0版新增功能:增加了VB,CB,VC,Delphi的演示调用程序。1、解决了WIN98下文字,图片不透明的问题。2、可以叠加文字,叠加图片,可以上下左右滚动文字。3、解决了叠加时,死机的情况,文字,图片可以...

    OSD叠加控件系列7.0版

    OSD叠加控件系列7.0版 1、...6、增加了文字滚动速度,步长属性。7、支持神龙5代卡、神龙新一代、神龙新二代卡。8、网络版无须再改动以前的点歌系统,只要挂上就可以使用。注意:控件提供VB,CB,DELPHI,VC的演示程序。

    VC++实现工具栏上添加平面组合框控件

    虽然Visual C++开发工具也提供了对工具条的支持,但通常只是按纽的集合,不能直接加入组合框等控件,实现OFFICE2000风格的工具条。本实例针对其中的一个细节,讲述了在Windows环境下用Visual C++6.0在工具条中加入...

    梅花雪日历控件,支持Firefox

    2、修改引用代码,增加charset属性,例如: &lt;script type="text/javascript" src="calendar.js" charset="GB2312"&gt;&lt;/script&gt; 或 &lt;script type="text/javascript" src="calendar.js" charset="UTF-8"&gt;&lt;/script&gt;

    VB编程资源大全(控件 窗体1)

    vbocx10.zip 以及窗体内的控件是否随窗体大小的改变而改变,以及设置窗体是否处于最上方,以及设置窗体是否以爆炸式方式显示(19KB) 72,Easyscroll.zip 为任何控件增加滚动条(41KB) 73,Zcg_3DLabel.zip ...

    VB编程资源大全(控件 窗体2)

    vbocx10.zip 以及窗体内的控件是否随窗体大小的改变而改变,以及设置窗体是否处于最上方,以及设置窗体是否以爆炸式方式显示(19KB) 72,Easyscroll.zip 为任何控件增加滚动条(41KB) 73,Zcg_3DLabel.zip ...

    ACReport中国式报表控件2010(Ver2.25)

    包含使用和开发接口文档,及Delphi、VB、VC++、...十、 增加了SetAppConnectionString方法,数据库连接控件增加了AlwaysUseAppConnString等相关属性,在报表中直接访问数据库更加方便。 十一、清单报表明细支持横向分栏

    CBbqGrid网格控件及其应用于运动会积分统计示例程序

    1、原来的控件对中文词组输入支持不好,现已修正;如单元格在选中,Edit框未出现的情况下输入中文词组会出现文字出错的现象; 2、修改复制、粘贴的代码,使控件能对于复制于Excel的区域数据正确粘贴; 3、增加...

    VB编程资源大全(控件 其它2)

    工业监控,数据采集,股市分析等领域的数据显示、分析、打印(305KB) 6,dxcontrol.ZIP API 函数控件,包含输入、声音、图形等(358KB) 7,gauge.ZIP 控件支持多数据处理和鼠标控制操作(232KB) 8,...

    VC学习大纲 VC学习讲义

    ActiveX控件的应用与工作原理,ActiveX控件的编写,如何为控件安排属性,方法,事件,属性页,持久性存储。如何注册控件与取消控件注册。如何测试与调试控件。 第二十课: 综合答疑与一些高深主题的介绍,包括如何...

    Visual C++实践与提高-COM和COM+篇『PDF』

    第6章 用VC 4开发COM应用 6.1 VC对COM的支持 6.1.1 类库支持:MFC和ATL 6.1.2 比较MFC和ATL 6.2 MFC对COM开发的支持 6.2.1 MFC简介 6.2.2 MFC对自动化的支持 6.2.2.1 MFC AppWizard支持 6.2.2.2 CCmdTarget类支持 ...

    JS截屏控件

    新颖网络截屏插件是一款能够非常方便的将屏幕截屏图片发送到WEB服务器中的轻量级ActiveX控件,它可以非常方便的集成到您的博客,BBS,论坛,OA,或电子商务网站中,带给用户前所未有的用户体验。 同时新颖网络提供了...

Global site tag (gtag.js) - Google Analytics