自动化 MSN Messenger
解释了关于事件接收和 MSN Messenger 事件的一些知识
引言
这基本上是为了解释如何使用一个进程外服务器的自动化。所以我使用了 MSN Messenger。我的文章解释了关于 MSN Messenger 的一些事情。它有一个 ATL 类 CIMSGEvents
,它处理 MSN Messenger 触发的事件。它捕获 MSN Messenger 触发的事件,并只在一个 EditBox 中输出相关信息。
使用 MSN Messenger 的步骤
- 创建一个默认的 MFC 项目(基于对话框,不使用自动化选项)。
- 打开 ClassWizard,选择自动化选项卡,选择 dlg 类,然后单击“从类型库添加类”,通过 Messenger 的类型库,即 c:\program files\messenger\msmsgs.exe。从列表框中选择以下类
IMessengerApp3
IMsgrObject2
DMsgrObjectEvents
(不太重要,但插入它以查看每个事件的 dispid。您也可以使用 OLE View 来查看它们) - 插入一个新 ATL 对象,并将其命名为类似于
IMSGEvents
的名称。
进入代码
IMessengerApp3
和 IMsgrObject2
都是其 CoClasses 的默认接口。在 OLE View 中检查它。IMessengerApp3
dispinterface 可用于控制 MSN 应用程序,因此首先要处理它。如果您在生成的代码中看到它,您会发现它派生自 COleDispatchDriver
。因此,现在我们需要调用 CoCreateInstance
来初始化 MSN Messenger 应用程序,像这样
HRESULT hres=CoCreateInstance(__uuidof(CLSID_MessengerApp), NULL,CLSCTX_LOCAL_SERVER, __uuidof(IID_IMessengerApp3), (void**)&m_MsnApp); // CLSID's and IID's are defined in // dialog header if(FAILED(hres))AfxMessageBox("Cannot start msn app");
现在到第二个 dispinterface IMsgrObject2
。这更重要一些。我们也必须初始化它,所以再次使用 CoCreateInstance
HRESULT hres=CoCreateInstance(__uuidof(CLSID_MsgrObject), NULL,CLSCTX_LOCAL_SERVER, __uuidof(IID_IMsgrObject2),(void**)&m_MsgObject); if(FAILED(hres))AfxMessageBox("Cannot get msgr Object");
第三个任务,稍微复杂一点,是建立连接并通知 Messenger。我们必须找到 IID_DMsgrObjectEvents
接口并获取事件通知。我使用了以下代码
IConnectionPoint* spCPC; IUnknown* mpUnk; IConnectionPointContainer* punkICPC; mpUnk=m_MsgObject; HRESULT hres=mpUnk->QueryInterface(IID_IConnectionPointContainer, (void**)&punkICPC); // query the iunknown for connectionpointcontainer if(FAILED(hres))AfxMessageBox("Cannot get IConnectionPoint interface"); // find the IID_DMsgrObjectEvents to see if it is supported hres=punkICPC->FindConnectionPoint( __uuidof(IID_DMsgrObjectEvents),&spCPC); if(FAILED(hres)) AfxMessageBox("Cannot get IID_DMsgrObjectEvents interface"); //finally advise the MsgrObject to get events hres=spCPC->Advise(pMsgEvents,&m_dwAdviseCookie); if(FAILED(hres))AfxMessageBox("Failed to advise");
现在移动到 CIMSGEvents
并重写 Invoke
方法,以查看正在发生什么事件。在头文件和源文件中声明它
// in header file STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*); // in cpp file HRESULT CIMSGEvents::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) { return S_OK; }
现在要查看哪个事件正在被触发,您可以检查 dispidMember
。有关更多信息,请参阅源代码。非常重要的是要注意,您在 OLE View 中看到的参数是反向访问的。因此,要访问最后一个参数,您必须使用如下代码
pDispParams->rgvarg[0]
并且要访问第一个参数,您必须使用参数的最大数量,例如对于第 4 个参数,您必须使用 pDispParams->rgvarg[3]
。所以我试图捕获所有事件,然后将它输出到 EditBox 中,只是为了看看当用户执行某些操作时会发生什么。它就像一个间谍。
感谢并请原谅
我想感谢 Michael Dunn 撰写的关于 COM 的精彩文章,否则我就不会开始使用 COM,并感谢 Mumtaz Zaheer 总是帮助我。我从十六岁就开始尝试编程,现在我正好十八岁。我过去 2 个月一直在编程 COM,所以您会看到这是一个很长的时期。好吧,我提交这篇文章是为了问问大家我是否做对了。所以,如果我做错了什么,请原谅我,因为我是一个初学者。我基本上是巴基斯坦的一名特许会计师学生,因此我还需要一些关于我应该更多关注哪个编程课程的评论,例如 MTS 与我的会计技能相关。请发表评论。