возникла проблема, нужно наладить работу с драйвером OPOS, управление ими осуществляеться через Activex, а я с Activex никогда не работал.
Кое как удалось подключить COPOSScanner_1_10, но все за стопорилось на том чтоб подключить события. Интерфейс обрабытывающий события подключаеться, у него вызываеться QueryInterface с riid = IID_OPOSScannerEvents, но события не вызываються.
//интерфейс событий взятый из исходника UnifiedOPOS CCOs 1.13
[
uuid(CCB90183-B81E-11D2-AB74-0040054C3719),
helpstring("_IOPOSScannerEvents Interface")
]
dispinterface _IOPOSScannerEvents
{
properties:
methods:
[id(1), helpstring("method DataEvent")]
void DataEvent( [in] long Status );
[id(2), helpstring("method DirectIOEvent")]
void DirectIOEvent( [in] long EventNumber, [in, out] long *pData, [in, out] BSTR *pString );
[id(3), helpstring("method ErrorEvent")]
void ErrorEvent( [in] long ResultCode, [in] long ResultCodeExtended, [in] long ErrorLocus, [in, out] long* pErrorResponse );
[id(5), helpstring("method StatusUpdateEvent")]
void StatusUpdateEvent( [in] long Data );
};
его как я понял должен реализовать клиент, и вызываться события будут через IDispatch
IDispatch я сделал так
//интерфейс событий
static CLSID const IID_IConnectionPointContainer = {0xB196B284,0xBAB4,0x101A,{0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07}};
static CLSID const CLSID_OPOSScanner = { 0xCCB90182, 0xB81E, 0x11D2, { 0xAB, 0x74, 0x0, 0x40, 0x5, 0x4C, 0x37, 0x19 } };
static CLSID const IID_OPOSScanner = { 0xCCB94181, 0xB81E, 0x11D2, { 0xAB, 0x74, 0x0, 0x40, 0x5, 0x4C, 0x37, 0x19 } };
static CLSID const IID_OPOSScannerEvents = {0xCCB90183,0xB81E, 0x11D2, { 0xAB, 0x74, 0x0, 0x40, 0x5, 0x4C, 0x37, 0x19 } };
class OPOSEvent:public IDispatch{
ULONG cref;
public:
// OPOSEvent(){cref = 0};
virtual ~OPOSEvent();
//IUnknown
STDMETHOD (QueryInterface)(REFIID riid, void **ppv);
STDMETHOD_ (ULONG, AddRef)(void);
STDMETHOD_ (ULONG, Release)(void);
//IDispatch
STDMETHOD (GetTypeInfoCount)(UINT *pctinfo);
STDMETHOD (GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo **pptinfo);
STDMETHOD (GetIDsOfNames)(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid);
STDMETHOD (Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr);
//events
void DataEvent(UINT32 status);
};
///////////////////////////////////////////
OPOSEvent::~OPOSEvent(){
}
///////////////////////////////////////////
STDMETHODIMP_ (ULONG)OPOSEvent::AddRef(){
return ++cref;
}
STDMETHODIMP_ (ULONG)OPOSEvent::Release(){
if (--cref == 0){
delete this;
return 0;
}
return cref;
}
STDMETHODIMP OPOSEvent::QueryInterface(REFIID riid, void **ppv){
if (riid == IID_IUnknown || riid == IID_IDispatch || riid == IID_OPOSScannerEvents){
*ppv = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
////////////////////////////////////////////
STDMETHODIMP OPOSEvent::GetTypeInfoCount(UINT *pctinfo){
//эта функция не вызываеться
*pctinfo = 0;
return S_OK;
}
STDMETHODIMP OPOSEvent::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo){
//эта функция не вызываеться
*pptinfo = 0;
return E_NOTIMPL;
}
STDMETHODIMP OPOSEvent::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid){
//эта функция не вызываеться
return S_OK;
}
STDMETHODIMP OPOSEvent::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr){
//эта функция не вызываеться
return S_OK;
}
//инициализвция
CoInitialize(0);
LPUNKNOWN punk = 0;
LPDISPATCH pdisp = 0;
IConnectionPointContainer* pcpc = 0;
IConnectionPoint* pcp = 0;
UINT a = CoCreateInstance(CLSID_OPOSScanner,0,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&punk);
punk->QueryInterface(IID_IDispatch,(void **)&pdisp);
COPOSScanner_1_10* scan = new COPOSScanner_1_10(pdisp);
scan->m_lpDispatch->QueryInterface(IID_IConnectionPointContainer,(void**)&pcpc);
// punk->QueryInterface(IID_IConnectionPointContainer,(void**)&pcpc);
pcpc->FindConnectionPoint(IID_OPOSScannerEvents,&pcp);
OPOSEvent* pevent = new OPOSEvent;
DWORD ConnectionID = 0;
a = pcp->Advise(pevent,&ConnectionID);
a = scan->Open(L"v1");
scan->ClaimDevice(999999);
scan->put_DeviceEnabled(true);
scan->put_DataEventEnabled(true);
scan->put_AutoDisable(true);
scan->put_DecodeData(true);
while(1){
CString str = scan->get_ScanData(); //читает последний отсканированный код нормально
Sleep(1000);
}
возможно я как-то нетак подключаю, хотелось бы узнать как надо