client端:
class CEvent: public IUnknown
{
public:
CEvent()
{};
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
long onspeak(BSTR leirong);//回叫函数
ULONG __stdcall AddRef();
ULONG __stdcall Release();
long m_cRef; };//接收器 GUID emapCLSID;
HRESULT hresult= CoInitialize( NULL );
Im *pUnknown;
hresult = ::CLSIDFromProgID(L"Project1.mycomclass",&emapCLSID);
hresult = CoCreateInstance(emapCLSID,NULL,CLSCTX_ALL,IID_Im,(void**)&pUnknown);
//注册回调
CEvent * pEvent= new CEvent();
pEvent->AddRef();
IConnectionPointContainer* pConnectionPointContainer = NULL;
IConnectionPoint* pConnectionPoint = NULL ;
DWORD dwCookie;
hresult = pUnknown->QueryInterface(IID_IConnectionPointContainer, (void**) &pConnectionPointContainer); hresult = pConnectionPointContainer->FindConnectionPoint(DIID_ImycomclassEvents, &pConnectionPoint);
if(SUCCEEDED(hresult))
hresult=pConnectionPoint->Advise((IUnknown*)pEvent, &dwCookie);//这这一步时候,返回错误值,hresult= -2147220990,错误是“不能打开当前线程的存取令牌 ”
pConnectionPoint->Release(); 服务器端视这样的:
class ATL_NO_VTABLE TmycomclassImpl :
public CComObjectRootEx <CComSingleThreadModel>,
public CComCoClass <TmycomclassImpl, &CLSID_mycomclass>,
public IConnectionPointContainerImpl <TmycomclassImpl>,
public TEvents_mycomclass <TmycomclassImpl>,
public Im
{
public:
TmycomclassImpl()
{
} // Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("Project1.mycomclass");
DECLARE_DESCRIPTION(""); // Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TTypedComServerRegistrarT <TmycomclassImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}
BEGIN_COM_MAP(TmycomclassImpl)
COM_INTERFACE_ENTRY(Im)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(TmycomclassImpl)
CONNECTION_POINT_ENTRY(DIID_ImycomclassEvents)
END_CONNECTION_POINT_MAP() // Im
public: int STDMETHODCALLTYPE mytest(int test);
};
extern "C" const __declspec(selectany) GUID LIBID_Project1 = {0x74EB1205, 0x8D05, 0x43EE,{ 0x8A, 0x88, 0x6F,0x01, 0x70, 0xE8,0x93, 0x78} };
extern "C" const __declspec(selectany) GUID IID_Im = {0xE8C6F90B, 0x2008, 0x4F0F,{ 0x82, 0x45, 0x5E,0xA2, 0x12, 0x99,0x2F, 0x73} };
extern "C" const __declspec(selectany) GUID DIID_ImycomclassEvents = {0x0D1685B3, 0x4B28, 0x4C03,{ 0xA5, 0xB3, 0x90,0xE5, 0xE2, 0x8A,0x47, 0x1B} };
extern "C" const __declspec(selectany) GUID CLSID_mycomclass = {0xE9F55514, 0xDB1B, 0x4DF9,{ 0xB0, 0xCB, 0xC0,0x57, 0xEA, 0xEE,0xB6, 0xE1} }; idl:
[
uuid(74EB1205-8D05-43EE-8A88-6F0170E89378),
version(1.0),
helpstring("Project1 Library") ]
library Project1
{ importlib("stdole2.tlb"); [
uuid(E8C6F90B-2008-4F0F-8245-5EA212992F73),
version(1.0),
helpstring("Interface for mycomclass Object"),
oleautomation
]
interface Im: IUnknown
{
[
id(0x00000001)
]
int _stdcall mytest([in] int test );
}; [
uuid(0D1685B3-4B28-4C03-A5B3-90E5E28A471B),
version(1.0),
helpstring("Events interface for mycomclass Object")
]
dispinterface ImycomclassEvents
{
properties:
methods:
[
id(0x00000001)
]
HRESULT onspeak([in] BSTR leirong );
}; [
uuid(E9F55514-DB1B-4DF9-B0CB-C057EAEEB6E1),
version(1.0),
helpstring("mycomclass")
]
coclass mycomclass
{
[default] interface Im;
[default, source] dispinterface ImycomclassEvents;
}; }; //这是服务端的回叫类.bcb自己生成的.
template <class T>
class TEvents_mycomclass : public IConnectionPointImpl <T,
&DIID_ImycomclassEvents,
CComUnkArray <CONNECTIONPOINT_ARRAY_SIZE> >
/* Note: if encountering problems with events, please change CComUnkArray to CComDynamicUnkArray in the line above. */
{
public:
HRESULT Fire_onspeak(BSTR leirong);
protected:
ImycomclassEventsDisp m_EventIntfObj;
}; template <class T> HRESULT
TEvents_mycomclass <T>::Fire_onspeak(BSTR leirong)
{
T * pT = (T*)this;
pT->Lock();
IUnknown ** pp = m_vec.begin();
while (pp < m_vec.end())
{
if (*pp != NULL)
{
m_EventIntfObj.Attach(*pp);
m_EventIntfObj.onspeak(leirong);
m_EventIntfObj.Attach(0);
}
pp++;
}
pT->Unlock();
}
想用连接点,实现服务器回叫客户端事件,不知道是出什么错误了,高手指教啊!
class CEvent: public IUnknown
{
public:
CEvent()
{};
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
long onspeak(BSTR leirong);//回叫函数
ULONG __stdcall AddRef();
ULONG __stdcall Release();
long m_cRef; };//接收器 GUID emapCLSID;
HRESULT hresult= CoInitialize( NULL );
Im *pUnknown;
hresult = ::CLSIDFromProgID(L"Project1.mycomclass",&emapCLSID);
hresult = CoCreateInstance(emapCLSID,NULL,CLSCTX_ALL,IID_Im,(void**)&pUnknown);
//注册回调
CEvent * pEvent= new CEvent();
pEvent->AddRef();
IConnectionPointContainer* pConnectionPointContainer = NULL;
IConnectionPoint* pConnectionPoint = NULL ;
DWORD dwCookie;
hresult = pUnknown->QueryInterface(IID_IConnectionPointContainer, (void**) &pConnectionPointContainer); hresult = pConnectionPointContainer->FindConnectionPoint(DIID_ImycomclassEvents, &pConnectionPoint);
if(SUCCEEDED(hresult))
hresult=pConnectionPoint->Advise((IUnknown*)pEvent, &dwCookie);//这这一步时候,返回错误值,hresult= -2147220990,错误是“不能打开当前线程的存取令牌 ”
pConnectionPoint->Release(); 服务器端视这样的:
class ATL_NO_VTABLE TmycomclassImpl :
public CComObjectRootEx <CComSingleThreadModel>,
public CComCoClass <TmycomclassImpl, &CLSID_mycomclass>,
public IConnectionPointContainerImpl <TmycomclassImpl>,
public TEvents_mycomclass <TmycomclassImpl>,
public Im
{
public:
TmycomclassImpl()
{
} // Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("Project1.mycomclass");
DECLARE_DESCRIPTION(""); // Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TTypedComServerRegistrarT <TmycomclassImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}
BEGIN_COM_MAP(TmycomclassImpl)
COM_INTERFACE_ENTRY(Im)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(TmycomclassImpl)
CONNECTION_POINT_ENTRY(DIID_ImycomclassEvents)
END_CONNECTION_POINT_MAP() // Im
public: int STDMETHODCALLTYPE mytest(int test);
};
extern "C" const __declspec(selectany) GUID LIBID_Project1 = {0x74EB1205, 0x8D05, 0x43EE,{ 0x8A, 0x88, 0x6F,0x01, 0x70, 0xE8,0x93, 0x78} };
extern "C" const __declspec(selectany) GUID IID_Im = {0xE8C6F90B, 0x2008, 0x4F0F,{ 0x82, 0x45, 0x5E,0xA2, 0x12, 0x99,0x2F, 0x73} };
extern "C" const __declspec(selectany) GUID DIID_ImycomclassEvents = {0x0D1685B3, 0x4B28, 0x4C03,{ 0xA5, 0xB3, 0x90,0xE5, 0xE2, 0x8A,0x47, 0x1B} };
extern "C" const __declspec(selectany) GUID CLSID_mycomclass = {0xE9F55514, 0xDB1B, 0x4DF9,{ 0xB0, 0xCB, 0xC0,0x57, 0xEA, 0xEE,0xB6, 0xE1} }; idl:
[
uuid(74EB1205-8D05-43EE-8A88-6F0170E89378),
version(1.0),
helpstring("Project1 Library") ]
library Project1
{ importlib("stdole2.tlb"); [
uuid(E8C6F90B-2008-4F0F-8245-5EA212992F73),
version(1.0),
helpstring("Interface for mycomclass Object"),
oleautomation
]
interface Im: IUnknown
{
[
id(0x00000001)
]
int _stdcall mytest([in] int test );
}; [
uuid(0D1685B3-4B28-4C03-A5B3-90E5E28A471B),
version(1.0),
helpstring("Events interface for mycomclass Object")
]
dispinterface ImycomclassEvents
{
properties:
methods:
[
id(0x00000001)
]
HRESULT onspeak([in] BSTR leirong );
}; [
uuid(E9F55514-DB1B-4DF9-B0CB-C057EAEEB6E1),
version(1.0),
helpstring("mycomclass")
]
coclass mycomclass
{
[default] interface Im;
[default, source] dispinterface ImycomclassEvents;
}; }; //这是服务端的回叫类.bcb自己生成的.
template <class T>
class TEvents_mycomclass : public IConnectionPointImpl <T,
&DIID_ImycomclassEvents,
CComUnkArray <CONNECTIONPOINT_ARRAY_SIZE> >
/* Note: if encountering problems with events, please change CComUnkArray to CComDynamicUnkArray in the line above. */
{
public:
HRESULT Fire_onspeak(BSTR leirong);
protected:
ImycomclassEventsDisp m_EventIntfObj;
}; template <class T> HRESULT
TEvents_mycomclass <T>::Fire_onspeak(BSTR leirong)
{
T * pT = (T*)this;
pT->Lock();
IUnknown ** pp = m_vec.begin();
while (pp < m_vec.end())
{
if (*pp != NULL)
{
m_EventIntfObj.Attach(*pp);
m_EventIntfObj.onspeak(leirong);
m_EventIntfObj.Attach(0);
}
pp++;
}
pT->Unlock();
}
想用连接点,实现服务器回叫客户端事件,不知道是出什么错误了,高手指教啊!
解决方案 »
- 仅知HBITMAP变量,怎样获取该变量指向的图片的高和宽?望大虾们指点一下!!!!
- MFC 多文档 DOC中一个函数如何输出文字和数字到一个指定的静态文本框中?
- CSDN验证码太郁闷了,散分,见者有份.
- window上经常用到的一种列表,怎么实现,急急急!!
- 高手近来看看!!!!!!!!!!!!!!!!
- ***********小妹刚学VC,VC操作Oracle,_RecordsetPtr型变量rsd,rsd执行Open,取出数据,执行AddNew时报措说当前Recordset不支持更新操
- ASPack 2.11 加壳的软件用什么工具脱壳?
- SDK初学者问题!(在线等候)送高分
- msdn的问题
- 一个关于ORIGIN的问题。。。
- 求救 VC AO
- 如何在移动鼠标时显示tips? 急急急!!!!!
我想是我的接收器谢的有问题!
if(SUCCEEDED(hresult))
hresult=pConnectionPoint->Advise((IUnknown*)pEvent, &dwCookie);//这这一步时候,返回错误值,hresult= -2147220990,错误是“不能打开当前线程的存取令牌 ”接收器有什么特殊要求吗?
class CEvent: public IDispatch
现在是pConnectionPoint->Advise((IUnknown*)pEvent, &dwCookie);//没问题了
但是:
class CEvent: public ImycomclassEvents//ImycomclassEvents是服务器的event接口,他继承了 IDispatch的函数
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr) = 0;
是纯虚函数 CEvent要实现它,要不服务器会报错
我联调了是这个函数导致服务器报错的,这个函数怎么实现呢?
ULONG __stdcall CSink::AddRef(void);
ULONG __stdcall CSink::Release(void);
STDMETHOD raw_Fire_onspeak(BSTR leirong);//
STDMETHODIMP CEvent::raw_Fire_onspeak(BSTR leirong)
{
}