热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

COM触发事件的常用方式

一般分为两种:1、直接调用HRESULTCFirePropNotifyEvent::FireOnRequestEdit(IUnknown*pUnk,DISPIDdi

一般分为两种:

1、直接调用


  1. HRESULT CFirePropNotifyEvent::FireOnRequestEdit(IUnknown* pUnk, DISPID dispID)
  2. {
  3.     CComQIPtr pCPC(pUnk);
  4.     if (!pCPC)
  5.         return S_OK;
  6.     CComPtr pCP;
  7.     pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);
  8.     if (!pCP)
  9.         return S_OK;
  10.     CComPtr pEnum;
  11.     if (FAILED(pCP->EnumConnections(&pEnum)))
  12.         return S_OK;
  13.     CONNECTDATA cd;
  14.     while (pEnum->Next(1, &cd, NULL) == S_OK)
  15.     {
  16.         if (cd.pUnk)
  17.         {
  18.             HRESULT hr = S_OK;
  19.             CComQIPtr pSink(cd.pUnk);
  20.             if (pSink)
  21.                 hr = pSink->OnRequestEdit(dispID);
  22.             cd.pUnk->Release();
  23.             if (hr == S_FALSE)
  24.                 return S_FALSE;
  25.         }
  26.     }
  27.     return S_OK;
  28. }

获得连接容器接口,进而获得容器中接收器IID_IPropertyNotifySink类型的连接点,再遍历这个连接点中各个IID_IPropertyNotifySink接收器,进而调用相应某事件。

这里的关键是:在事件对象中继承IID_IPropertyNotifySink接收器接口,并实现OnRequestEdit等事件函数。

2、间接调用。


  1. template<typename host_t, const IID* pIID_ToHookEvent>
  2. class ComEventIntercepter : public IDispatch
  3. {
  4. typedef HRESULT (STDMETHODCALLTYPE host_t::*invok_t)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
  5.             DISPPARAMS FAR* pDispParams, VARIANT FAR* parResult,EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr);
  6. public:
  7.     ComEventIntercepter(host_t* pHost &#61; NULL, invok_t notifier &#61; NULL) :
  8.         m_pHost(pHost), m_notifier(notifier), m_dwCOOKIE(0)
  9.     {
  10.     }
  11.     HRESULT Intercept(IUnknown* pUnkCP)
  12.     {
  13.         if(pUnkCP &#61;&#61; NULL)
  14.             return E_INVALIDARG;
  15.         CComPtr pCPC;
  16.         CComPtr pCP;
  17.         HRESULT hRes &#61; pUnkCP->QueryInterface(__uuidof(IConnectionPointContainer), (void**)&pCPC);
  18.         if (SUCCEEDED(hRes))
  19.             hRes &#61; pCPC->FindConnectionPoint(*pIID_ToHookEvent, &pCP);
  20.         if (SUCCEEDED(hRes))
  21.             hRes &#61; pCP->Advise(this, &m_dwCOOKIE);
  22.         return hRes;
  23.     }
  24. public:
  25.     STDMETHODIMP QueryInterface(REFIID iid, void ** ppvObject)
  26.     {
  27.         if(ppvObject &#61;&#61; NULL) return E_INVALIDARG;
  28.         *ppvObject &#61; NULL;
  29.         if(iid &#61;&#61; IID_IUnknown)
  30.             *ppvObject &#61; (IUnknown*)this;
  31.         else if(iid &#61;&#61; *pIID_ToHookEvent || iid &#61;&#61; IID_IDispatch)
  32.             *ppvObject &#61; this;
  33.         if(*ppvObject &#61;&#61; NULL) return E_NOINTERFACE;
  34.         return S_OK;
  35.     }
  36.     ULONG STDMETHODCALLTYPE AddRef()
  37.     {
  38.         return 0;
  39.     }
  40.     ULONG STDMETHODCALLTYPE Release()
  41.     {
  42.         return 0;
  43.     }
  44.     HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int FAR* pctinfo)
  45.     { return E_NOTIMPL; }
  46.     HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int iTInfo, LCID  lcid,
  47.         ITypeInfo FAR* FAR*  ppTInfo)
  48.     { return E_NOTIMPL; }
  49.     HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
  50.         OLECHAR FAR* FAR* rgszNames,
  51.         unsigned int cNames,
  52.         LCID lcid,
  53.         DISPID FAR* rgDispId)
  54.     { return E_NOTIMPL; }
  55.     HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
  56.         DISPPARAMS FAR* pDispParams, VARIANT FAR* parResult,
  57.         EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr)
  58.     {
  59.         if(m_pHost && m_notifier)
  60.         {
  61.             return (m_pHost->*m_notifier)(dispIdMember, riid, lcid, wFlags, pDispParams, parResult, pExcepInfo, puArgErr);
  62.         }
  63.         return E_NOTIMPL;
  64.     }
  65. protected:
  66.     host_t* m_pHost;
  67.     invok_t m_notifier;
  68.     DWORD   m_dwCOOKIE;
  69. };


  1. HRESULT CWebBrowser::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
  2.                                      DISPPARAMS FAR* pDispParams, VARIANT FAR* parResult,
  3.                                      EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr)
  4. {
  5.     switch (dispIdMember)
  6.     {
  7.     case DISPID_DOCUMENTCOMPLETE:
  8.         //ATLTRACE("DISPID_DOCUMENTCOMPLETE/n");
  9.         break;
  10.     case DISPID_DOWNLOADBEGIN:
  11.         // Enable the stop menu item and toolbar button
  12.         //EnableMenuItem(m_hMenu, ID_VIEW_STOP, MF_BYCOMMAND|MF_ENABLED);
  13.         //m_wndToolBar.SendMessage(TB_ENABLEBUTTON, ID_VIEW_STOP, MAKELONG(TRUE, 0));
  14.         break;
  15.     case DISPID_NAVIGATECOMPLETE:
  16.         {
  17.             // Set the text of the combobox to the current URL
  18.             //CComBSTR bstrURL;
  19.             //m_spWebBrowser->get_LocationURL(&bstrURL);
  20.             //m_wndUrlCombo.SetWindowText(OLE2T(bstrURL));
  21.         }
  22.         break;
  23.     case DISPID_NAVIGATECOMPLETE2:
  24.         {
  25.             // Set the text of the combobox to the current URL
  26.             //CComBSTR bstrURL;
  27.             //m_spWebBrowser->get_LocationURL(&bstrURL);
  28.             //m_wndUrlCombo.SetWindowText(OLE2T(bstrURL));
  29.         }
  30.         break;
  31.     case DISPID_DOWNLOADCOMPLETE:
  32.         // Disable the stop menu item and toolbar button
  33.         //EnableMenuItem(m_hMenu, ID_VIEW_STOP, MF_BYCOMMAND|MF_GRAYED);
  34.         //m_wndToolBar.SendMessage(TB_ENABLEBUTTON, ID_VIEW_STOP, MAKELONG(FALSE, 0));
  35.         break;
  36.         //
  37.         // The parameters for this DISPID:
  38.         // [0]: New status bar text - VT_BSTR
  39.         //
  40.     case DISPID_STATUSTEXTCHANGE:
  41.         //m_wndStatusBar.SetWindowText(OLE2T(pDispParams->rgvarg[0].bstrVal));
  42.         break;
  43.         //
  44.         // The parameters for this DISPID:
  45.         // [0]: Document title - VT_BSTR
  46.         //
  47.     case DISPID_TITLECHANGE:
  48.         {
  49.             //strstream strTitle;
  50.             //if (pDispParams->cArgs > 0 && pDispParams->rgvarg[0].vt &#61;&#61; VT_BSTR)
  51.             //{
  52.             //    strTitle << OLE2T(pDispParams->rgvarg[0].bstrVal);
  53.             //    strTitle << " - AtlBrowser";
  54.             //}
  55.             //else
  56.             //{
  57.             //    strTitle << "AtlBrowser";
  58.             //}
  59.             //strTitle << ends;
  60.             //SetWindowText(strTitle.str());
  61.         }
  62.         break;
  63.         //
  64.         // DISPID for Download Control
  65.         //
  66.     case DISPID_AMBIENT_DLCONTROL:
  67.         {
  68.             //CComVariant vtResult(static_cast(m_dwDLControl));
  69.             //*pvarResult &#61; vtResult;
  70.         }
  71.         break;
  72.     default:
  73.         return DISP_E_MEMBERNOTFOUND;
  74.     }
  75.     return S_OK;
  76. }

这里的关键是&#xff1a;在事件对象中定义IDispatch接口&#xff0c;通过在Invoke()函数中实现各事件分支语句&#xff0c;实现各事件具体功能。

而上一种需要为各个事件实现各自的函数&#xff0c;针对某个事件&#xff0c;会有相应的触发函数和响应函数。

而间接调用中&#xff0c;Invoke()把所有事件响应都集成在自己函数里&#xff0c;通过dispid的不同来进行分支处理。触发函数也只需一个&#xff0c;只需在输入参数中用dispid来区别。

间接调用的好处就是可以方便脚本语言中的实现&#xff0c;只是效率低很多而已。


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • Python的参数解析argparse模块的学习
    本文介绍了Python中参数解析的重要模块argparse的学习内容。包括位置参数和可选参数的定义和使用方式,以及add_argument()函数的详细参数关键字解释。同时还介绍了命令行参数的操作和可接受数量的设置,其中包括整数类型的参数。通过学习本文内容,可以更好地理解和使用argparse模块进行参数解析。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
author-avatar
lingling2502852417
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有