多谢<简单的DCOM实例(公司预研文档)>的作者,文章里说过能够实现事件广播.我做了一个例子,已经能够实现事件,但不能实现事件广播.请指教.
我定义了一个Query组件,组件的IQuery接口提供GetName2(),GetName2()模拟长时间操作的异步性,返回字符串给客户端.各客户端能够正确的发出请求,接收事件,显示信息.程序还显示一个组件接口的地址,各个客户端都是相同的.这是我的Query组件的定义.h文件
class ATL_NO_VTABLE CQuery : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CQuery, &CLSID_Query>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CQuery>,
// public IDispatchImpl<IQuery, &IID_IQuery, &LIBID_CONNECTIONLib>,
public IDispatchImpl<IQuery2, &IID_IQuery2, LIBID_CONNECTIONLib>,
public CProxy_IQueryEvents< CQuery >
{
CComBSTR m_szName;
public:
CQuery()
{
m_szName = L"xlander";
}DECLARE_CLASSFACTORY_SINGLETON(CQuery)
DECLARE_REGISTRY_RESOURCEID(IDR_QUERY)
DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CQuery)
COM_INTERFACE_ENTRY(IQuery)
COM_INTERFACE_ENTRY(IQuery2)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()BEGIN_CONNECTION_POINT_MAP(CQuery)
CONNECTION_POINT_ENTRY(DIID__IQueryEvents)
END_CONNECTION_POINT_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);// IQuery
public:
STDMETHOD(DisplayName)(/*[in]*/BSTR szName);
STDMETHOD(SetName)(/*[in]*/BSTR szName);
STDMETHOD(GetName)();
STDMETHOD(GetName2)();
};
其中的一个实现函数:
STDMETHODIMP CQuery::GetName2()
{
Fire_OnGetName(m_szName);
return S_OK;
}
Fire_OnGetName()的实现是ATL向导加进去的,没改过.客户端的实现是这样的:
.h文件
IQuery2Ptr m_ptrQuery;
IQueryPtrWithEvents<1, CClientDlg> m_ptrQuerySink;
IQueryPtrWithEvents是我定义的一个接收器,负责将接收到的事件传递给窗口.
template<UINT I, class T>
class IQueryPtrWithEvents :
public IQueryEventImpl//,
// public IQueryPtr
{
public:
IQueryPtrWithEvents(){};
~IQueryPtrWithEvents(){};
public:
BEGIN_SINK_MAP(IQueryPtrWithEvents)
SINK_ENTRY_EX(I, __uuidof(_IQueryEvents), 1, OnGetName)
END_SINK_MAP()
public:
STDMETHOD(OnGetName)(BSTR bstrName)
{
return m_pSink->OnGetName(bstrName);
};
HRESULT DispEventAdvise(T* pDisplay, IUnknown *pUnk)
{
m_pSink = pDisplay;
HRESULT hr = IQueryEventImpl::DispEventAdvise(pUnk);
return hr;
};
HRESULT DispEventUnadvise(IUnknown *pUnk)
{
m_pSink = NULL;
HRESULT hr = IQueryEventImpl::DispEventUnadvise(pUnk);
return hr;
};
private:
T *m_pSink;
};.cpp
CClientDlg::OnInitDialog()
{
...
HRESULT hr = S_OK;
hr = m_ptrQuery.CreateInstance(__uuidof(Query)); UpdateData(true);
m_lInterface = (long)m_ptrQuery.GetInterfacePtr();
UpdateData(false); if(SUCCEEDED(hr))
{
IUnknown *pUnk = m_ptrQuery;
m_ptrQuerySink.DispEventAdvise(this, pUnk);
}
}void CClientDlg::OnOK() 
{
m_ptrQuery->GetName2();
}STDMETHODIMP CClientDlg::OnGetName(BSTR bstrName)
{
MessageBox(CString(bstrName));
return 1;
}

解决方案 »

  1.   

    另外,我调试Fire_OnGetName的时候,里面有一句int nConnections = m_vec.GetSize();
    我想知道这个nConnections代表什么?是连接的客户端数目么?为什么不管我连多少客户端nConnections始终等与1
      

  2.   

    给我个例子也可以阿?再或者把你们读<简单的DCOM实例(公司预研文档)>的体会告诉我也行啊?
      

  3.   

    本人绝对守信用,信用值一直是100,各位高手千万别被那帮不结贴的XXX们吓趴下了:P
      

  4.   

    <简单的DCOM实例(公司预研文档)>给我一份好吗?
    [email protected]
    谢谢!