CUPSvr是进程外的COM组件,ATL客户是一个.EXE,接收类名为CSUCtrlSink,连接点为m_pISuCtrlConnectionPoint,对应于接口_IUPSvrEvents.
在客户程序中首先创建了一个对话框类CSUCtrlDlg,而后直接执行该对话框类的Initialize方法,其代码如下:
bool CSUCtrlDlg::Initialize()
{
//create COM object of CSuCtrlSink
m_pSuCtrlSink = new CComObject<CSUCtrlSink>; HRESULT hr;
IUnknown* pUnk = NULL;
IConnectionPointContainer* pConnPtContainer = NULL; hr = m_UpCtrl.CoCreateInstance(__uuidof(CUPSvr)); hr = m_UpCtrl->QueryInterface(IID_IConnectionPointContainer, (void**)&pConnPtContainer);

hr = pConnPtContainer->FindConnectionPoint(__uuidof(_IUPSvrEvents), &m_pISuCtrlConnectionPoint);

CComPtr<IUnknown>spUnk;
m_pSuCtrlSink->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk); hr = m_pISuCtrlConnectionPoint->Advise(spUnk, &m_dwCookie); return true;
}
Debug时发现Advise返回S_OK, 而且m_dwCookie=1,但是对于_IUPSvrEvents上的事件,客户程序就是无法响应。
后来看到网上说需要指定客户程序的事件处理函数和连接点上的事件的对应关系,于是在接收类中添加了如下代码
BEGIN_SINK_MAP(CSUCtrlSink)
SINK_ENTRY_EX(0,__uuidof(_IUPSvrEvents), 1, UploadingStarted)
END_SINK_MAP()
但在这种情况下,链接时会出现如下错误:
error C2440: 'static_cast' : cannot convert from '_atl_event_classtype *' to 'ATL::_IDispEventLocator<nID,piid> *'请大虾们帮忙看看,实在搞不定了,多谢多谢!

解决方案 »

  1.   

    跟进去看了一下,发现在服务组件invoke是返回的是“member not found", 但是我在接收类上实现了该接口阿,太奇怪了
      

  2.   

    我在_IUPSvrEvents接口上添加了两个method,fun1和fun2,dispid分别是1和2,然后选择实现连接点后自动生成了回调辅助函数Fire_fun1和Fire_fun2,对应dispid分别指定为1和2,不知道这里有什么问题呢,dispid怎么会指定不对呢?
      

  3.   

    http://www.vckbase.com/document/viewdoc/?id=1538
      

  4.   

    你这里搞错了
    CComPtr<IUnknown>spUnk;
    m_pSuCtrlSink->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);hr = m_pISuCtrlConnectionPoint->Advise(spUnk, &m_dwCookie);应该是:
    CComPtr<IUnknown>spUnk;
    m_pISuCtrlConnectionPoint->QueryInterface(IID_IUnknown, (LPVOID *)&spUnk);m_pSuCtrlSink->Advise(spUnk, &m_dwCookie);因为2个对象Advise方法参数不同,所以报那个连接错误
      

  5.   

    我也碰到 error   C2440, 把下边的0换成资源id, ok
    SINK_ENTRY_EX(0,__uuidof(_IUPSvrEvents),   1,   UploadingStarted) 
      

  6.   

    对了,Advise方法为注册调用接口指针,必须用外部的接收器对象指针。其次如果还有其他的问题你可以用MessageBox()在服务端ExE中跟踪显示一下。