65.9K
CodeProject 正在变化。 阅读更多。
Home

自动化 MSN Messenger

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.24/5 (7投票s)

2001年5月24日

CPOL

3分钟阅读

viewsIcon

272863

downloadIcon

2874

解释了关于事件接收和 MSN Messenger 事件的一些知识

引言

这基本上是为了解释如何使用一个进程外服务器的自动化。所以我使用了 MSN Messenger。我的文章解释了关于 MSN Messenger 的一些事情。它有一个 ATL 类 CIMSGEvents,它处理 MSN Messenger 触发的事件。它捕获 MSN Messenger 触发的事件,并只在一个 EditBox 中输出相关信息。

使用 MSN Messenger 的步骤

  1. 创建一个默认的 MFC 项目(基于对话框,不使用自动化选项)。
  2. 打开 ClassWizard,选择自动化选项卡,选择 dlg 类,然后单击“从类型库添加类”,通过 Messenger 的类型库,即 c:\program files\messenger\msmsgs.exe。从列表框中选择以下类
    IMessengerApp3
    IMsgrObject2
    DMsgrObjectEvents
    (不太重要,但插入它以查看每个事件的 dispid。您也可以使用 OLE View 来查看它们)
  3. 插入一个新 ATL 对象,并将其命名为类似于 IMSGEvents 的名称。

进入代码

IMessengerApp3IMsgrObject2 都是其 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 与我的会计技能相关。请发表评论。

© . All rights reserved.