13 个解决方案
#1
http://www.widgetware.com/ATLFAQ_ConnPoints.htm
#2
参看TestContainer源代码(包含在VC安装盘中)
#3
HRESULT hr;
try{
hr=pApp.GetActiveObject(CLSID_Application);
if(FAILED(hr))
{
pApp.CreateInstance(CLSID_Application);
}
//Instantiate the sink class and hold a pointer to it.
// p=(CThread*)AfxBeginThread(RUNTIME_CLASS(CThread),THREAD_PRIORITY_NORMAL,
// 0,CREATE_SUSPENDED,NULL);
// (p->m_AppEvents).ParentThreadID=GetCurrentThreadId();
// ThreadID=p->m_nThreadID;
m_pSink=new CAppEvents;
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE); //Establish a connection between source and sink.
//m_pUnkSrc is IUnknown of server obtained by CoCreateInstance().
//m_dwCookie is a cookie identifying the connection, and is needed
//to terminate the connection.
m_dwCookie=0;
int ret=AfxConnectionAdvise(pApp, DIID__IApplicationEvents,
pUnkSink, FALSE,&m_dwCookie);
// p->ResumeThread();
UpdateData(true);
}catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
}
try{
hr=pApp.GetActiveObject(CLSID_Application);
if(FAILED(hr))
{
pApp.CreateInstance(CLSID_Application);
}
//Instantiate the sink class and hold a pointer to it.
// p=(CThread*)AfxBeginThread(RUNTIME_CLASS(CThread),THREAD_PRIORITY_NORMAL,
// 0,CREATE_SUSPENDED,NULL);
// (p->m_AppEvents).ParentThreadID=GetCurrentThreadId();
// ThreadID=p->m_nThreadID;
m_pSink=new CAppEvents;
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE); //Establish a connection between source and sink.
//m_pUnkSrc is IUnknown of server obtained by CoCreateInstance().
//m_dwCookie is a cookie identifying the connection, and is needed
//to terminate the connection.
m_dwCookie=0;
int ret=AfxConnectionAdvise(pApp, DIID__IApplicationEvents,
pUnkSink, FALSE,&m_dwCookie);
// p->ResumeThread();
UpdateData(true);
}catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
}
#4
class CAppEvents : public CCmdTarget
{
DECLARE_DYNCREATE(CAppEvents)
CAppEvents(); // protected constructor used by dynamic creation
// Attributes
public:
CTestEterm3_1Dlg *p;
// Operations
public:
void OnStatusChange(long i,BSTR str);
void OnReceiveCurConf(VARIANT config);
virtual ~CAppEvents();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAppEvents)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_APPEVENTS_H__0D28C1F2_C426_40F4_9EA0_16E699E6BA1A__INCLUDED_)
{
DECLARE_DYNCREATE(CAppEvents)
CAppEvents(); // protected constructor used by dynamic creation
// Attributes
public:
CTestEterm3_1Dlg *p;
// Operations
public:
void OnStatusChange(long i,BSTR str);
void OnReceiveCurConf(VARIANT config);
virtual ~CAppEvents();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAppEvents)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_APPEVENTS_H__0D28C1F2_C426_40F4_9EA0_16E699E6BA1A__INCLUDED_)
#5
CAppEvents::CAppEvents()
{
EnableAutomation();
}
CAppEvents::~CAppEvents()
{
}
void CAppEvents::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CCmdTarget::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CAppEvents, CCmdTarget)
//{{AFX_MSG_MAP(CAppEvents)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP( CAppEvents, CCmdTarget)
DISP_FUNCTION_ID(CAppEvents, "ReceiveCurConf", 1, OnReceiveCurConf, VT_EMPTY, VTS_VARIANT)
DISP_FUNCTION_ID(CAppEvents, "StatusChange", 2, OnStatusChange, VT_EMPTY, VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()
// Note: we add support for IID_IAppEvents to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {52C4B2C4-19E6-4D7F-8A5A-11EAB8C2FFF6}
//static const IID DIID__IApplicationEvents =
//{ 0x3c31bf76, 0x2837, 0x4bfa, { 0xa1,0x9e,0x34,0x48,0x5a,0x21,0x3f,0x29}};
BEGIN_INTERFACE_MAP(CAppEvents, CCmdTarget)
INTERFACE_PART(CAppEvents, DIID__IApplicationEvents, Dispatch)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAppEvents message handlers
void CAppEvents::OnReceiveCurConf(VARIANT config)
{
}
void CAppEvents::OnStatusChange(long i, BSTR str)
{
}
#6
MFC中不是已经帮你做好了吗?用Class Wizard就可以了。
#7
添加类时选automation
#8
如果使用ATL方式怎么用?
#9
我给wei97081116(韦小宝)补充几句。
如果用的是MFC wrapper的ActiveX, 那么在创建了CAppEvents后,在连接ActiveX控件的时候可以作如下处理:
LPUNKNOWN lpUnknown = m_pActiveX->GetControlUnknown();
int ret=AfxConnectionAdvise(lpUnknown, DIID__IApplicationEvents,
pUnkSink, FALSE, &m_dwCookie);
就可以了。注意在Destroy的时候作同样的处理哦,AfxConnectionUnadvise(...).
另:在响应消息时,使用DISP_FUNCTION(...)无法获得对应的消息处理。使用DISP_FUNCTION_ID(...)可以获得该事件的处理,我想,估计是明确指定了事件对应的序号的结果。
祝各位好运。
如果用的是MFC wrapper的ActiveX, 那么在创建了CAppEvents后,在连接ActiveX控件的时候可以作如下处理:
LPUNKNOWN lpUnknown = m_pActiveX->GetControlUnknown();
int ret=AfxConnectionAdvise(lpUnknown, DIID__IApplicationEvents,
pUnkSink, FALSE, &m_dwCookie);
就可以了。注意在Destroy的时候作同样的处理哦,AfxConnectionUnadvise(...).
另:在响应消息时,使用DISP_FUNCTION(...)无法获得对应的消息处理。使用DISP_FUNCTION_ID(...)可以获得该事件的处理,我想,估计是明确指定了事件对应的序号的结果。
祝各位好运。
#10
另外在http://www.codeproject.com/com/vbeventswithvc.asp 有对这个问题的一个描述。可以参考,写得很不错,但是需要灵活运用,和实际情况不太一样。
在mdsn中使用ActiveX, 事件等关键字也可以找到有关的文章,也可以参考。
在mdsn中使用ActiveX, 事件等关键字也可以找到有关的文章,也可以参考。
#11
有没有知道怎样使用用OLE自动化封装的事件的使用方法,我现在做一个程序,程序中用了一个用OLE自动化封装的组件,其中包括事件类,这个OLE自动化组件在VB中很好用,用于接收事件的方式也很简单,可是我现在想在VC做的程序中接收这个事件,可是不知道什么原因一直不可用。下面是我的事件接收器的定义:
typedef DWORD OPCHANDLE;
class COPCGroupEvt :
public IDispatchImpl<DIOPCGroupEvent, &DIID_DIOPCGroupEvent,&LIBID_OPCAutomation>,
public CComObjectRoot
{
public:
COPCGroupEvt();
BEGIN_COM_MAP(COPCGroupEvt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(DIOPCGroupEvent)
END_COM_MAP()
// DIOPCGroupEvent
public:
STDMETHOD(OnDataChange)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnReadComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnWriteComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT mastererr,
DWORD count,
OPCHANDLE * clienthandles,
HRESULT * error
);
STDMETHOD(OnCancelComplete)(
DWORD transid,
OPCHANDLE grphandle
);
};
下面是用#import宏导出部分定义:
typedef DWORD OPCHANDLE;
class COPCGroupEvt :
public IDispatchImpl<DIOPCGroupEvent, &DIID_DIOPCGroupEvent,&LIBID_OPCAutomation>,
public CComObjectRoot
{
public:
COPCGroupEvt();
BEGIN_COM_MAP(COPCGroupEvt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(DIOPCGroupEvent)
END_COM_MAP()
// DIOPCGroupEvent
public:
STDMETHOD(OnDataChange)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnReadComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnWriteComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT mastererr,
DWORD count,
OPCHANDLE * clienthandles,
HRESULT * error
);
STDMETHOD(OnCancelComplete)(
DWORD transid,
OPCHANDLE grphandle
);
};
下面是用#import宏导出部分定义:
#12
struct __declspec(uuid("28e68f97-8d75-11d1-8dc3-3c302a000000"))
DIOPCGroupEvent : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT DataChange (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps );
HRESULT AsyncReadComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps,
SAFEARRAY * * Errors );
HRESULT AsyncWriteComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * Errors );
HRESULT AsyncCancelComplete (
long CancelID );
};
extern "C" const GUID __declspec(selectany) LIBID_OPCAutomation =
{0x28e68f91,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroups =
{0x28e68f9e,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroup =
{0x28e68f9b,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItem =
{0x28e68f99,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItems =
{0x28e68f98,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupEvent =
{0x28e68f97,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupsEvent =
{0x28e68f9d,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCBrowser =
{0x28e68f94,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCAutoServer =
{0x28e68f92,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroups =
{0x28e68f95,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroup =
{0x28e68f96,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCServerEvent =
{0x28e68f93,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCServer =
{0x28e68f9a,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
下面是我将事件接收器与OLE自动化封装调用代码,可以正常运行,但是无法接收到事件:
DIOPCGroupEvent : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT DataChange (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps );
HRESULT AsyncReadComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps,
SAFEARRAY * * Errors );
HRESULT AsyncWriteComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * Errors );
HRESULT AsyncCancelComplete (
long CancelID );
};
extern "C" const GUID __declspec(selectany) LIBID_OPCAutomation =
{0x28e68f91,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroups =
{0x28e68f9e,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroup =
{0x28e68f9b,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItem =
{0x28e68f99,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItems =
{0x28e68f98,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupEvent =
{0x28e68f97,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupsEvent =
{0x28e68f9d,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCBrowser =
{0x28e68f94,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCAutoServer =
{0x28e68f92,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroups =
{0x28e68f95,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroup =
{0x28e68f96,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCServerEvent =
{0x28e68f93,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCServer =
{0x28e68f9a,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
下面是我将事件接收器与OLE自动化封装调用代码,可以正常运行,但是无法接收到事件:
#13
IOPCGroupsPtr pOPCGroups;
OPCItemsPtr pOPCItems;
IConnectionPointContainer *pCPC = 0;
IConnectionPoint *pCallbackCP = 0;
HRESULT hres;
try
{
pOPCGroups=pOPCServer->GetOPCGroups();
pOPCGroup=pOPCGroups->Add("UpData");
pOPCGroup->IsActive=TRUE; //设置组活动状态
pOPCGroup->IsSubscribed=TRUE; //取消组非同期通知
pOPCItems=pOPCGroup->GetOPCItems();
(pOPCItems->AddItem("UpData",1))->IsActive=TRUE;
CComObject<COPCGroupEvt>* pOPCGroupEvt;
CComObject<COPCGroupEvt>::CreateInstance(&pOPCGroupEvt);
hres = pOPCGroup->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint suppuer");
return;
}
hres = pCPC->FindConnectionPoint(DIID_DIOPCGroupEvent, &pCallbackCP);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint for OPCCallback:(%lx)\n");
pCPC->Release();
return;
}
hres = pCallbackCP->Advise(pOPCGroupEvt, &m_Advise);
if (FAILED(hres))
{
MessageBox("Advise Failed:(%lx)\n");
pCallbackCP->Release();
pCPC->Release();
return;
}
/* HRESULT hRes = AtlAdvise(pOPCGroup, pOPCGroupEvt->GetUnknown(),DIID_DIOPCGroupEvent, &m_Advise);
if (FAILED(hRes))
{
AfxMessageBox("Advise failed");
}*/
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
return;
}
请各位高手帮忙看一下!
OPCItemsPtr pOPCItems;
IConnectionPointContainer *pCPC = 0;
IConnectionPoint *pCallbackCP = 0;
HRESULT hres;
try
{
pOPCGroups=pOPCServer->GetOPCGroups();
pOPCGroup=pOPCGroups->Add("UpData");
pOPCGroup->IsActive=TRUE; //设置组活动状态
pOPCGroup->IsSubscribed=TRUE; //取消组非同期通知
pOPCItems=pOPCGroup->GetOPCItems();
(pOPCItems->AddItem("UpData",1))->IsActive=TRUE;
CComObject<COPCGroupEvt>* pOPCGroupEvt;
CComObject<COPCGroupEvt>::CreateInstance(&pOPCGroupEvt);
hres = pOPCGroup->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint suppuer");
return;
}
hres = pCPC->FindConnectionPoint(DIID_DIOPCGroupEvent, &pCallbackCP);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint for OPCCallback:(%lx)\n");
pCPC->Release();
return;
}
hres = pCallbackCP->Advise(pOPCGroupEvt, &m_Advise);
if (FAILED(hres))
{
MessageBox("Advise Failed:(%lx)\n");
pCallbackCP->Release();
pCPC->Release();
return;
}
/* HRESULT hRes = AtlAdvise(pOPCGroup, pOPCGroupEvt->GetUnknown(),DIID_DIOPCGroupEvent, &m_Advise);
if (FAILED(hRes))
{
AfxMessageBox("Advise failed");
}*/
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
return;
}
请各位高手帮忙看一下!
#1
http://www.widgetware.com/ATLFAQ_ConnPoints.htm
#2
参看TestContainer源代码(包含在VC安装盘中)
#3
HRESULT hr;
try{
hr=pApp.GetActiveObject(CLSID_Application);
if(FAILED(hr))
{
pApp.CreateInstance(CLSID_Application);
}
//Instantiate the sink class and hold a pointer to it.
// p=(CThread*)AfxBeginThread(RUNTIME_CLASS(CThread),THREAD_PRIORITY_NORMAL,
// 0,CREATE_SUSPENDED,NULL);
// (p->m_AppEvents).ParentThreadID=GetCurrentThreadId();
// ThreadID=p->m_nThreadID;
m_pSink=new CAppEvents;
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE); //Establish a connection between source and sink.
//m_pUnkSrc is IUnknown of server obtained by CoCreateInstance().
//m_dwCookie is a cookie identifying the connection, and is needed
//to terminate the connection.
m_dwCookie=0;
int ret=AfxConnectionAdvise(pApp, DIID__IApplicationEvents,
pUnkSink, FALSE,&m_dwCookie);
// p->ResumeThread();
UpdateData(true);
}catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
}
try{
hr=pApp.GetActiveObject(CLSID_Application);
if(FAILED(hr))
{
pApp.CreateInstance(CLSID_Application);
}
//Instantiate the sink class and hold a pointer to it.
// p=(CThread*)AfxBeginThread(RUNTIME_CLASS(CThread),THREAD_PRIORITY_NORMAL,
// 0,CREATE_SUSPENDED,NULL);
// (p->m_AppEvents).ParentThreadID=GetCurrentThreadId();
// ThreadID=p->m_nThreadID;
m_pSink=new CAppEvents;
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE); //Establish a connection between source and sink.
//m_pUnkSrc is IUnknown of server obtained by CoCreateInstance().
//m_dwCookie is a cookie identifying the connection, and is needed
//to terminate the connection.
m_dwCookie=0;
int ret=AfxConnectionAdvise(pApp, DIID__IApplicationEvents,
pUnkSink, FALSE,&m_dwCookie);
// p->ResumeThread();
UpdateData(true);
}catch(_com_error &e)
{
AfxMessageBox(e.Description());
}
}
#4
class CAppEvents : public CCmdTarget
{
DECLARE_DYNCREATE(CAppEvents)
CAppEvents(); // protected constructor used by dynamic creation
// Attributes
public:
CTestEterm3_1Dlg *p;
// Operations
public:
void OnStatusChange(long i,BSTR str);
void OnReceiveCurConf(VARIANT config);
virtual ~CAppEvents();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAppEvents)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_APPEVENTS_H__0D28C1F2_C426_40F4_9EA0_16E699E6BA1A__INCLUDED_)
{
DECLARE_DYNCREATE(CAppEvents)
CAppEvents(); // protected constructor used by dynamic creation
// Attributes
public:
CTestEterm3_1Dlg *p;
// Operations
public:
void OnStatusChange(long i,BSTR str);
void OnReceiveCurConf(VARIANT config);
virtual ~CAppEvents();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAppEvents)
public:
virtual void OnFinalRelease();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(CAppEvents)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_APPEVENTS_H__0D28C1F2_C426_40F4_9EA0_16E699E6BA1A__INCLUDED_)
#5
CAppEvents::CAppEvents()
{
EnableAutomation();
}
CAppEvents::~CAppEvents()
{
}
void CAppEvents::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CCmdTarget::OnFinalRelease();
}
BEGIN_MESSAGE_MAP(CAppEvents, CCmdTarget)
//{{AFX_MSG_MAP(CAppEvents)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP( CAppEvents, CCmdTarget)
DISP_FUNCTION_ID(CAppEvents, "ReceiveCurConf", 1, OnReceiveCurConf, VT_EMPTY, VTS_VARIANT)
DISP_FUNCTION_ID(CAppEvents, "StatusChange", 2, OnStatusChange, VT_EMPTY, VTS_I4 VTS_BSTR)
END_DISPATCH_MAP()
// Note: we add support for IID_IAppEvents to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {52C4B2C4-19E6-4D7F-8A5A-11EAB8C2FFF6}
//static const IID DIID__IApplicationEvents =
//{ 0x3c31bf76, 0x2837, 0x4bfa, { 0xa1,0x9e,0x34,0x48,0x5a,0x21,0x3f,0x29}};
BEGIN_INTERFACE_MAP(CAppEvents, CCmdTarget)
INTERFACE_PART(CAppEvents, DIID__IApplicationEvents, Dispatch)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAppEvents message handlers
void CAppEvents::OnReceiveCurConf(VARIANT config)
{
}
void CAppEvents::OnStatusChange(long i, BSTR str)
{
}
#6
MFC中不是已经帮你做好了吗?用Class Wizard就可以了。
#7
添加类时选automation
#8
如果使用ATL方式怎么用?
#9
我给wei97081116(韦小宝)补充几句。
如果用的是MFC wrapper的ActiveX, 那么在创建了CAppEvents后,在连接ActiveX控件的时候可以作如下处理:
LPUNKNOWN lpUnknown = m_pActiveX->GetControlUnknown();
int ret=AfxConnectionAdvise(lpUnknown, DIID__IApplicationEvents,
pUnkSink, FALSE, &m_dwCookie);
就可以了。注意在Destroy的时候作同样的处理哦,AfxConnectionUnadvise(...).
另:在响应消息时,使用DISP_FUNCTION(...)无法获得对应的消息处理。使用DISP_FUNCTION_ID(...)可以获得该事件的处理,我想,估计是明确指定了事件对应的序号的结果。
祝各位好运。
如果用的是MFC wrapper的ActiveX, 那么在创建了CAppEvents后,在连接ActiveX控件的时候可以作如下处理:
LPUNKNOWN lpUnknown = m_pActiveX->GetControlUnknown();
int ret=AfxConnectionAdvise(lpUnknown, DIID__IApplicationEvents,
pUnkSink, FALSE, &m_dwCookie);
就可以了。注意在Destroy的时候作同样的处理哦,AfxConnectionUnadvise(...).
另:在响应消息时,使用DISP_FUNCTION(...)无法获得对应的消息处理。使用DISP_FUNCTION_ID(...)可以获得该事件的处理,我想,估计是明确指定了事件对应的序号的结果。
祝各位好运。
#10
另外在http://www.codeproject.com/com/vbeventswithvc.asp 有对这个问题的一个描述。可以参考,写得很不错,但是需要灵活运用,和实际情况不太一样。
在mdsn中使用ActiveX, 事件等关键字也可以找到有关的文章,也可以参考。
在mdsn中使用ActiveX, 事件等关键字也可以找到有关的文章,也可以参考。
#11
有没有知道怎样使用用OLE自动化封装的事件的使用方法,我现在做一个程序,程序中用了一个用OLE自动化封装的组件,其中包括事件类,这个OLE自动化组件在VB中很好用,用于接收事件的方式也很简单,可是我现在想在VC做的程序中接收这个事件,可是不知道什么原因一直不可用。下面是我的事件接收器的定义:
typedef DWORD OPCHANDLE;
class COPCGroupEvt :
public IDispatchImpl<DIOPCGroupEvent, &DIID_DIOPCGroupEvent,&LIBID_OPCAutomation>,
public CComObjectRoot
{
public:
COPCGroupEvt();
BEGIN_COM_MAP(COPCGroupEvt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(DIOPCGroupEvent)
END_COM_MAP()
// DIOPCGroupEvent
public:
STDMETHOD(OnDataChange)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnReadComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnWriteComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT mastererr,
DWORD count,
OPCHANDLE * clienthandles,
HRESULT * error
);
STDMETHOD(OnCancelComplete)(
DWORD transid,
OPCHANDLE grphandle
);
};
下面是用#import宏导出部分定义:
typedef DWORD OPCHANDLE;
class COPCGroupEvt :
public IDispatchImpl<DIOPCGroupEvent, &DIID_DIOPCGroupEvent,&LIBID_OPCAutomation>,
public CComObjectRoot
{
public:
COPCGroupEvt();
BEGIN_COM_MAP(COPCGroupEvt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(DIOPCGroupEvent)
END_COM_MAP()
// DIOPCGroupEvent
public:
STDMETHOD(OnDataChange)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnReadComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT masterquality,
HRESULT mastererror,
DWORD count,
OPCHANDLE * clienthandles,
VARIANT * values,
WORD * quality,
FILETIME * time,
HRESULT * errors
);
STDMETHOD(OnWriteComplete)(
DWORD Transid,
OPCHANDLE grphandle,
HRESULT mastererr,
DWORD count,
OPCHANDLE * clienthandles,
HRESULT * error
);
STDMETHOD(OnCancelComplete)(
DWORD transid,
OPCHANDLE grphandle
);
};
下面是用#import宏导出部分定义:
#12
struct __declspec(uuid("28e68f97-8d75-11d1-8dc3-3c302a000000"))
DIOPCGroupEvent : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT DataChange (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps );
HRESULT AsyncReadComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps,
SAFEARRAY * * Errors );
HRESULT AsyncWriteComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * Errors );
HRESULT AsyncCancelComplete (
long CancelID );
};
extern "C" const GUID __declspec(selectany) LIBID_OPCAutomation =
{0x28e68f91,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroups =
{0x28e68f9e,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroup =
{0x28e68f9b,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItem =
{0x28e68f99,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItems =
{0x28e68f98,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupEvent =
{0x28e68f97,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupsEvent =
{0x28e68f9d,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCBrowser =
{0x28e68f94,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCAutoServer =
{0x28e68f92,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroups =
{0x28e68f95,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroup =
{0x28e68f96,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCServerEvent =
{0x28e68f93,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCServer =
{0x28e68f9a,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
下面是我将事件接收器与OLE自动化封装调用代码,可以正常运行,但是无法接收到事件:
DIOPCGroupEvent : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT DataChange (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps );
HRESULT AsyncReadComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * ItemValues,
SAFEARRAY * * Qualities,
SAFEARRAY * * TimeStamps,
SAFEARRAY * * Errors );
HRESULT AsyncWriteComplete (
long TransactionID,
long NumItems,
SAFEARRAY * * ClientHandles,
SAFEARRAY * * Errors );
HRESULT AsyncCancelComplete (
long CancelID );
};
extern "C" const GUID __declspec(selectany) LIBID_OPCAutomation =
{0x28e68f91,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroups =
{0x28e68f9e,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCGroup =
{0x28e68f9b,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItem =
{0x28e68f99,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCItems =
{0x28e68f98,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupEvent =
{0x28e68f97,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCGroupsEvent =
{0x28e68f9d,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_OPCBrowser =
{0x28e68f94,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCAutoServer =
{0x28e68f92,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroups =
{0x28e68f95,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) IID_IOPCGroup =
{0x28e68f96,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) DIID_DIOPCServerEvent =
{0x28e68f93,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
extern "C" const GUID __declspec(selectany) CLSID_OPCServer =
{0x28e68f9a,0x8d75,0x11d1,{0x8d,0xc3,0x3c,0x30,0x2a,0x00,0x00,0x00}};
下面是我将事件接收器与OLE自动化封装调用代码,可以正常运行,但是无法接收到事件:
#13
IOPCGroupsPtr pOPCGroups;
OPCItemsPtr pOPCItems;
IConnectionPointContainer *pCPC = 0;
IConnectionPoint *pCallbackCP = 0;
HRESULT hres;
try
{
pOPCGroups=pOPCServer->GetOPCGroups();
pOPCGroup=pOPCGroups->Add("UpData");
pOPCGroup->IsActive=TRUE; //设置组活动状态
pOPCGroup->IsSubscribed=TRUE; //取消组非同期通知
pOPCItems=pOPCGroup->GetOPCItems();
(pOPCItems->AddItem("UpData",1))->IsActive=TRUE;
CComObject<COPCGroupEvt>* pOPCGroupEvt;
CComObject<COPCGroupEvt>::CreateInstance(&pOPCGroupEvt);
hres = pOPCGroup->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint suppuer");
return;
}
hres = pCPC->FindConnectionPoint(DIID_DIOPCGroupEvent, &pCallbackCP);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint for OPCCallback:(%lx)\n");
pCPC->Release();
return;
}
hres = pCallbackCP->Advise(pOPCGroupEvt, &m_Advise);
if (FAILED(hres))
{
MessageBox("Advise Failed:(%lx)\n");
pCallbackCP->Release();
pCPC->Release();
return;
}
/* HRESULT hRes = AtlAdvise(pOPCGroup, pOPCGroupEvt->GetUnknown(),DIID_DIOPCGroupEvent, &m_Advise);
if (FAILED(hRes))
{
AfxMessageBox("Advise failed");
}*/
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
return;
}
请各位高手帮忙看一下!
OPCItemsPtr pOPCItems;
IConnectionPointContainer *pCPC = 0;
IConnectionPoint *pCallbackCP = 0;
HRESULT hres;
try
{
pOPCGroups=pOPCServer->GetOPCGroups();
pOPCGroup=pOPCGroups->Add("UpData");
pOPCGroup->IsActive=TRUE; //设置组活动状态
pOPCGroup->IsSubscribed=TRUE; //取消组非同期通知
pOPCItems=pOPCGroup->GetOPCItems();
(pOPCItems->AddItem("UpData",1))->IsActive=TRUE;
CComObject<COPCGroupEvt>* pOPCGroupEvt;
CComObject<COPCGroupEvt>::CreateInstance(&pOPCGroupEvt);
hres = pOPCGroup->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint suppuer");
return;
}
hres = pCPC->FindConnectionPoint(DIID_DIOPCGroupEvent, &pCallbackCP);
if (FAILED(hres))
{
MessageBox("No ConnectionPoint for OPCCallback:(%lx)\n");
pCPC->Release();
return;
}
hres = pCallbackCP->Advise(pOPCGroupEvt, &m_Advise);
if (FAILED(hres))
{
MessageBox("Advise Failed:(%lx)\n");
pCallbackCP->Release();
pCPC->Release();
return;
}
/* HRESULT hRes = AtlAdvise(pOPCGroup, pOPCGroupEvt->GetUnknown(),DIID_DIOPCGroupEvent, &m_Advise);
if (FAILED(hRes))
{
AfxMessageBox("Advise failed");
}*/
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
return;
}
请各位高手帮忙看一下!