编写了一个组建:内涵定时器,定时调用组建接口函数,向客户端发送事件信息。问题:
作为进程组件时,一切正常!!
但作为进程外组件时,却不能向客户端发送事件信息。怎么回事?

解决方案 »

  1.   

    Invoke()函数中的第一个参数是否正常?
    用MessageBox()跟踪一下走到哪一不?
      

  2.   

    不用发消息改为socket或者管道如何
      

  3.   

    跟进去了,看起来一切正常!!
    但有个问题:
    Invoke的第三个参数做什么的?现在我的程序为:LOCAL_USER_DEFAULT
      

  4.   

    如果你跟到Server的Invoke()了,就去客户端那边的Invoke函数中看是不是有响应。因为你的客户端的那个新建的类是继承的_I事件名Events_I事件名Events : public IDispatch 所以你必须在类名.CPP中实现这些方法     
               HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);
      ULONG STDMETHODCALLTYPE AddRef();
      ULONG STDMETHODCALLTYPE Release();


      HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pI);
      HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID  riid, 
    OLECHAR FAR* FAR*  rgszNames, 
    unsigned int  cNames, 
    LCID   lcid,
    DISPID FAR*  rgDispId) ;
      HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTinfo, LCID lcid, ITypeInfo FAR **ppTIinfo);
      HRESULT STDMETHODCALLTYPE Invoke(DISPID  dispIdMember, 
    REFIID  riid, 
    LCID  lcid, 
    WORD  wFlags,
    DISPPARAMS FAR*  pDispParams, 
    VARIANT FAR*  pVarResult,
    EXCEPINFO FAR*  pExcepInfo,
    unsigned int FAR*  puArgErr);
    其中只有Invoke()的调用客户端函数是需要你自己来完成。其他的可以直接拷过去。
    给你我的一个模板:
    #if !defined(AFX_ALLBACK_H__0DF7C374_AB83_452C_9A1B_131AB926895D__INCLUDED_)
    #define AFX_ALLBACK_H__0DF7C374_AB83_452C_9A1B_131AB926895D__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#include "stdafx.h"
    #include <atlbase.h>#include "AtlConnectionAddressGuidance.h"#import "AtlConnectionAddressGuidance.tlb"  named_guids raw_interfaces_onlyusing namespace ATL;
    class CallBack : public _IGuidanceEvents 
    {
    public:
    CallBack();
    virtual ~CallBack();
    public:
      DWORD  m_dwRefCount;
         // BSTR AddressResult;//return result
      CString mguidance;
      STDMETHODIMP CallClientResponse(BSTR GuidanceSentence);
          HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject);
      ULONG STDMETHODCALLTYPE AddRef();
      ULONG STDMETHODCALLTYPE Release();


      HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pI);
      HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID  riid, 
    OLECHAR FAR* FAR*  rgszNames, 
    unsigned int  cNames, 
    LCID   lcid,
    DISPID FAR*  rgDispId) ;
      HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTinfo, LCID lcid, ITypeInfo FAR **ppTIinfo);
      HRESULT STDMETHODCALLTYPE Invoke(DISPID  dispIdMember, 
    REFIID  riid, 
    LCID  lcid, 
    WORD  wFlags,
    DISPPARAMS FAR*  pDispParams, 
    VARIANT FAR*  pVarResult,
    EXCEPINFO FAR*  pExcepInfo,
    unsigned int FAR*  puArgErr);
    };#endif
    CPP中:
    #include "stdafx.h"
    #include "AtlConnectionAddressGuidanceClient.h"
    #include "allBack.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CallBack::CallBack()
    {
       m_dwRefCount = 0;
      // AddressResult=0;
    }CallBack::~CallBack()
    {}
    STDMETHODIMP CallBack::CallClientResponse(BSTR  GuidanceSentence)
    {  
        
    CComBSTR   combstr(GuidanceSentence);   
     CString strTemp=GuidanceSentence;
     CString Client="Client Guidance Response:";
     //    AfxMessageBox("AtlConnectionAddressGuidanceClient Response"); 
    Client+=strTemp;
     AfxMessageBox(Client); 
     mguidance+=strTemp;

      CString str="AtlConnectionAddressGuidanceClient"; 
     CWnd *pWnd=CWnd::FindWindow(NULL,str); 
    //  if(pWnd) 
     // pWnd->PostMessage(WM_CLOSE,0,0); 
      Sleep(1000);
     ::SendMessage(pWnd->m_hWnd,WM_QUIT,0,0);
    // HWND   hwnd =::GetActiveWindow();   
     //   Sleep(200);
    // PostMessage(NULL,WM_QUIT,0,0); //"AtlConnectionAddressGuidanceClient"    
         return S_OK;;   };
    HRESULT STDMETHODCALLTYPE CallBack::QueryInterface(REFIID iid, void **ppvObject)
        

    if (iid == DIID__IGuidanceEvents)
        {
          m_dwRefCount++;
          *ppvObject = (void *)this;
          return S_OK;
        }
        if (iid == IID_IUnknown)
        {
          m_dwRefCount++;
          *ppvObject = (void *)this;
          return S_OK;
        }
        
    else
    return E_NOINTERFACE;  /*
      This Method Can't return right value  */
      //Example show it this way
    /*    m_dwRefCount++;            
            *ppvObject = (void *)this;
            return S_OK;
    */    }ULONG STDMETHODCALLTYPE CallBack::AddRef()
      {
        m_dwRefCount++;
        return m_dwRefCount;
      }ULONG STDMETHODCALLTYPE CallBack::Release()
      {
        ULONG l;
        l  = m_dwRefCount--;
        if ( 0 == m_dwRefCount)
           delete this;    return l;
      }HRESULT STDMETHODCALLTYPE CallBack::GetTypeInfoCount(UINT *pI)
    {
    return E_NOTIMPL;
    }; HRESULT STDMETHODCALLTYPE CallBack::GetIDsOfNames(REFIID  riid, 
    OLECHAR FAR* FAR*  rgszNames, 
    unsigned int  cNames, 
    LCID   lcid,
    DISPID FAR*  rgDispId)       
    {
    return E_NOTIMPL;
    }
    HRESULT STDMETHODCALLTYPE CallBack::GetTypeInfo(UINT iTinfo, LCID lcid, ITypeInfo FAR **ppTIinfo)
    {
    return E_NOTIMPL;
    } HRESULT STDMETHODCALLTYPE CallBack::Invoke(DISPID  dispIdMember, 
    REFIID  riid, 
    LCID  lcid, 
    WORD  wFlags,
    DISPPARAMS FAR*  pDispParams, 
    VARIANT FAR*  pVarResult,
    EXCEPINFO FAR*  pExcepInfo,
    unsigned int FAR*  puArgErr)
    {
    HRESULT hr = S_OK;
    if(pDispParams)

    // switch (dispIdMember)
    // {
    // case 1:
    // return AdditionStarted();
    {if(dispIdMember==1)
    // case 2:

    {  
    //AfxMessageBox("AtlConnectionAddressGuidanceClient Response"); 
           //(unsigned short *) 
    return CallClientResponse(pDispParams->rgvarg[0].bstrVal);  //Transport Error 
    }
    else 
    return E_NOTIMPL;
    // default:
    // return E_NOTIMPL;
    }

    else   return E_NOTIMPL;

    };
      

  5.   

    组件A,实现接口Call。A::Call{
       Fire_call();    // 发出事件
    }当定时器调用a->call时,客户端没有响应
    但当客户端主动调用a->call时,客户端有相应。奇怪!!
      

  6.   

    因为你定义的客户端接受器对象也有call();   函数事件。
    肯定是你在传递消息时错了。就在服务端调用invoke后, 客户端接受器对象call()事件里是应该有消息响应的,如果没有在客户端接受器对象的invoke函数中也应该有响应。如果这里也没有的话,就应该是消息没有传过来。
      

  7.   

    >>hbuzzd谢谢你的热心回答!!能否给个demo,只要实现一个进程外组件向客户端定时发送事件信息即可。
    谢谢!!mail:[email protected] 
      

  8.   

    收到!谢谢!可以运行.当客户端调用server组件的LogAddressData时, server组件通过Firewall_CallClientReponse向client发出事件信息.我的问题:如果server端主动调用LogAddressData(比如每隔3分钟调用一次),是否还可以成功向client发出事件信息?
    这就是我现在面临的主要问题!!!再次感谢!!
      

  9.   

    也就是这样:
    1。客户端成功与server建立连接后,什么也不做,等待server发送事件信息。
    2。server每隔三分钟主动调用LogAddressData,通过Firewall_CallClientReponse向client发出事件信息这时,client是否可以收到信息?
      

  10.   

    也就是这样:
    1。客户端成功与server建立连接后,什么也不做,等待server发送事件信息。
    2。server每隔三分钟主动调用LogAddressData,通过Firewall_CallClientReponse向client发出事件信息这时,client是否可以收到信息?
      

  11.   

    也就是这样:
    1。客户端成功与server建立连接后,什么也不做,等待server发送事件信息。
    2。server每隔三分钟主动调用LogAddressData,通过Firewall_CallClientReponse向client发出事件信息这时,client是否可以收到信息?
      

  12.   

    可以。请确保定时器消息响应函数运行在与组件相同的线程中,否则FireXXX调用没有效果
      

  13.   

    像jameshooo 说的。可以但是得在同一个线程中。
    我有一个问题问问jameshooo:如果我跳到了子线程中去调用Firexxx肯定编译不通过,该如何解决?(传递对象指针好像也没有用。)
      

  14.   

    在子线程中不能直接传递接口指针,你可以选择创建一个组件,或者把原始组件列集后在子线程中散列,但这时的问题是,你得到的是接口指针(不是组件类实例的指针),只能调用接口方法,不能调用FireXXX
      

  15.   

    To:jameshooo
        这是我的开子线程代码,能调用Firexxx了,但是在执行到Invoke()方法时,客户端的invoke()事件却没有响应,这是为什么?我的参数也已经传到了服务端Invoke()中。
      

  16.   

    DWORD WINAPI ThreadServer(LPVOID lpParameter)//子线程函数
    {
    CGuidance *myAtl = (CGuidance*)lpParameter;
    myAtl->Fire_CallClientResponse(GuidanceData.AllocSysString());
    CoUninitialize();
    return 0;
    }
    服务端的接口处理函数(主线程)部分代码:
    HANDLE hThrd;
     DWORD idd;
     CoInitializeEx(NULL,(COINIT_MULTITHREADED)) ;  
     if((hThrd = CreateThread(
                     0,
                     0,
                     (LPTHREAD_START_ROUTINE)ThreadServer,
                     (void *)this,
                     0,
                     &idd)) == NULL)
             {
                 AfxMessageBox("Creare Thread Error");
             }
                CloseHandle(hThrd);
    然后在CProxy_IGuidanceEvents的Fire_CallClientResponse()中有响应,但是在
    pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL);
    这句话后本来客户端接收器对象中的invoke函数会响应但是现在却没有反应,这是为什么?
    我发现disp参数中已经赋有正确的值了,说明调用Fire_CallClientResponse()应该是成功了啊?这是为什么?谢谢!
      

  17.   

    我已经解决了。按照这里的介绍:http://support.microsoft.com/kb/q280512/
    这个问题好像比较普遍,供后来者参考
      

  18.   

    按照这里的介绍:http://support.microsoft.com/kb/q280512/ 
    修改CProxy_IAppleEvents后,编译出错---error C2352: “ATL::CComDynamicUnkArray::GetCookie” : 非静态成员函数的非法调用怎么回事?#pragma once
    #include "ATLCPImplMT.h"//template<class T>
    //class CProxy_IAppleEvents :
    // public IConnectionPointImpl<T, &__uuidof(_IAppleEvents)>template <class T>
    class CProxy_IAppleEvents : public IConnectionPointImplMT<T, &__uuidof(_IAppleEvents), CComDynamicUnkArray>

    {
    public:
    HRESULT Fire_Reponse()
    {
    HRESULT hr = S_OK;
    T * pThis = static_cast<T *>(this);
    int cConnections = m_vec.GetSize(); for (int iConnection = 0; iConnection < cConnections; iConnection++)
    {
    pThis->Lock();
    CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
    pThis->Unlock(); IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p); if (pConnection)
    {
    CComVariant varResult; DISPPARAMS params = { NULL, NULL, 0, 0 };
    hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
    }
    }
    return hr;
    }
    };
      

  19.   

    改下面:pT->Lock();CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);pT->Unlock();
    改成:CComPtr<IUnknown> sp;sp.Attach (GetInterfaceAt(nConnectionIndex));IDispatch* pConnection = reinterpret_cast<IDispatch*>(sp.p);
    试试。
      

  20.   

    我用2008开发,为什么按照如上修改后,程序在"ATLCPImplMT.h"文件中的两处报
    error C2352: “ATL::CComDynamicUnkArray::GetCookie”: 非静态成员函数的非法调用
    error C2352: “ATL::CComDynamicUnkArray::GetUnknown”: 非静态成员函数的非法调用