//создаем собитие
HANDLE event=CreateEvent(NULL,TRUE,FALSE,"EVENT");
//устанавливаем событие
SetEvent(event);
//уничтожаем событие и закрываем недл
ResetEvent(event);
CloseHandle(event);
Как создатать событие в DLL что бы потом можно его отловить в программе?
Код:
Но проблема в том что это надо написать в DLL, по моему ни чем код создания не будет отличаться, а вот как потом подключив DLL можно отловить это событие?
Насколько я помню, таким образом ты создаешь именованный системный объект, который будет доступен глобально в системе посредством повторного вызова CreateEvent. Если конечно права доступа позволят. В пределах одного процесса вообще никаких проблемм не должно возникать.
Потому что DLL пишу под 1С, и попросили чтобы она посылала событие, после окончания опроса устройства.
Это уже все в Visual С++ работает.(Спасибо DaemonDZK).
Может есть какие нибуть правила создания событий, так как DLL ето универсальная библиотека которую можно подключать к многим программам.
передай в длл адресс функции которую нужно вызывать после окончания опроса либо посылай виндовое сообщение или можно ипользовать объекты ядра: в длл создай тотже евент (именованный или передавай через промежуточные вызовы функций описатель евента) сбрось его в сотояние занято, далее создай поток в вызывающей проге жди пока освободиться тотже евент(как только опрос окончиться освободи евент в длл) и это будет сигнализировать об окончании опроса.
Код:
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
hEvent=CreateEvent(NULL,TRUE,FALSE,SysAllocString(L"EVENTCARD"));
}
else if (dwReason == DLL_PROCESS_DETACH)
{
if(hEvent!=NULL) CloseHandle(hEvent);
}
return TRUE; // ok
}
//в процессе
STDMETHODIMP CCARD::Answer()
{
for(int i=0; i<20;i++)
{
//............
}
SetEvent(hEvent);
Sleep(20);
ResetEvent(hEvent);
return S_OK;
}
{
if (dwReason == DLL_PROCESS_ATTACH)
{
hEvent=CreateEvent(NULL,TRUE,FALSE,SysAllocString(L"EVENTCARD"));
}
else if (dwReason == DLL_PROCESS_DETACH)
{
if(hEvent!=NULL) CloseHandle(hEvent);
}
return TRUE; // ok
}
//в процессе
STDMETHODIMP CCARD::Answer()
{
for(int i=0; i<20;i++)
{
//............
}
SetEvent(hEvent);
Sleep(20);
ResetEvent(hEvent);
return S_OK;
}
и тогда в программе по имени "EVENTCARD" можно отловить это событие?
static HANDLE hEvent=NULL;
Код:
//header
enum TYPEMESS {TM_ONEEVENT, TM_TWOEVENT};
struct ISomeInterface
{
virtual void __stdcall Notify(TYPEMESS tm, LPVOID lpAditionalParam) = 0;
};
//process
class CProcessClass: public ISomeInterface
{
CThreadClass* m_pThreadProc;
public:
CProcessClass()
{
m_pThreadProc = new CThreadClass((ISomeInterface*)this);
}
protected:
void __stdcall Notify(TYPEMESS, LPVOID lpAditionalParam)
{
/*
.....
*/
}
};
//dll
class __declspec(dllexport) CThreadClass
{
ISomeInterface* m_pNotifyObject;
HANDLE m_hThread;
HANDLE m_hTerminateThread;
public:
CThreadClass(ISomeInterface*pNotifyObject):
m_pNotifyObject(pNotifyObject)
{
m_hTerminateThread = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hThread = CreateThread(NULL, 0, Process, this, 0, NULL);
}
~CThreadClass()
{
SetEvent(m_hTerminateThread);
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hTerminateThread);
CloseHandle(m_hThread);
}
protected:
static DWORD __stdcall Process(LPVOID lpParam)
{
CThreadClass* pThis = (CThreadClass*)lpParam;
while (WaitForSingleObject(pThis -> m_hTerminateThread, 0) != WAIT_OBJECT_0)
{
/*.....*/
pThis -> m_pNotifyObject -> Notify(TM_ONEEVENT, 0);
/*.....*/
pThis -> m_pNotifyObject -> Notify(TM_TWOEVENT, 0);
/*.....*/
}
return 0;
}
};
enum TYPEMESS {TM_ONEEVENT, TM_TWOEVENT};
struct ISomeInterface
{
virtual void __stdcall Notify(TYPEMESS tm, LPVOID lpAditionalParam) = 0;
};
//process
class CProcessClass: public ISomeInterface
{
CThreadClass* m_pThreadProc;
public:
CProcessClass()
{
m_pThreadProc = new CThreadClass((ISomeInterface*)this);
}
protected:
void __stdcall Notify(TYPEMESS, LPVOID lpAditionalParam)
{
/*
.....
*/
}
};
//dll
class __declspec(dllexport) CThreadClass
{
ISomeInterface* m_pNotifyObject;
HANDLE m_hThread;
HANDLE m_hTerminateThread;
public:
CThreadClass(ISomeInterface*pNotifyObject):
m_pNotifyObject(pNotifyObject)
{
m_hTerminateThread = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hThread = CreateThread(NULL, 0, Process, this, 0, NULL);
}
~CThreadClass()
{
SetEvent(m_hTerminateThread);
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hTerminateThread);
CloseHandle(m_hThread);
}
protected:
static DWORD __stdcall Process(LPVOID lpParam)
{
CThreadClass* pThis = (CThreadClass*)lpParam;
while (WaitForSingleObject(pThis -> m_hTerminateThread, 0) != WAIT_OBJECT_0)
{
/*.....*/
pThis -> m_pNotifyObject -> Notify(TM_ONEEVENT, 0);
/*.....*/
pThis -> m_pNotifyObject -> Notify(TM_TWOEVENT, 0);
/*.....*/
}
return 0;
}
};
Если не сложно, подскажите как сделать такое, или где поискать.
А то не могу пойти в отпуск. :(
ты не знаешь как ком объект написать? Я могу тебе на ATL шаблонный проект сделать, если нужно конечно, но в остальном предыдущий пример отражает суть как постороить callback
Методы и свойства уже описаны. А вот 1С не отлавливает событие, написанное так как я описал выше, и не могу придумать как правильно это сделать?!
Event в windows api это объект ядра служаший для синхронизации данных между потоками процесса либо различных процессов и ни чего он ни куда не посылает. раскажи или напиши как ты узаешь в 1с свой ком
Процедура ПриНачалеРаботыСистемы()
// Вставить содержимое обработчика.
глОбъект = Новый COMОбъект("PCARD.CARD.1");
глОбъект.InitMetod();
КонецПроцедуры
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
// Вставить содержимое обработчика.
Предупреждение("Событие");
КонецПроцедуры
Ну что никто не знает как можно организовать событие в COM-объекте, чтобы его можно было отловить с любого другого програмного продукта?
А может ктото знает как создать асинхронное событие в С++?
Ну если Event никуда ничего не передает, то значит должно быть то что передает и делает это глобально.
В MSDN его нет, а нете нарыл примеры с его использованием.
Может ктото разберется, у меня не получается огласить переменную интерфейса IAsyncEvent *pAsyncEvent; Куда должен указывать этот указатель, не пойму?
И почему ошибка error C2501: 'auto_ptr' : missing storage-class or type specifiers при:
Код:
class ATL_NO_VTABLE CTEST :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTEST, &CLSID_TEST>,
public IDispatchImpl<ITEST, &IID_ITEST, &LIBID_TESTCOMEVENTLib>,
public CProxy_ITESTEvents< CTEST >,
public IConnectionPointContainerImpl<CTEST>
{
virtual ~CTEST(void) throw();
CTEST(void);
DECLARE_REGISTRY_RESOURCEID(IDR_TEST)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CTEST)
COM_INTERFACE_ENTRY(ITEST)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CTEST)
CONNECTION_POINT_ENTRY(DIID__ITESTEvents)
END_CONNECTION_POINT_MAP()
public: class class1c
{
public:
~class1c();
class1c();
public:
IAsyncEvent *pAsyncEvent;
};
auto_ptr< class1c>class1c_;//ошибки:
//error C2143: syntax error : missing ';' before '<'
//error C2501: 'auto_ptr' : missing storage-class or type specifiers
//error C2059: syntax error : '<'
//error C2238: unexpected token(s) preceding ';'
};
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTEST, &CLSID_TEST>,
public IDispatchImpl<ITEST, &IID_ITEST, &LIBID_TESTCOMEVENTLib>,
public CProxy_ITESTEvents< CTEST >,
public IConnectionPointContainerImpl<CTEST>
{
virtual ~CTEST(void) throw();
CTEST(void);
DECLARE_REGISTRY_RESOURCEID(IDR_TEST)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CTEST)
COM_INTERFACE_ENTRY(ITEST)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CTEST)
CONNECTION_POINT_ENTRY(DIID__ITESTEvents)
END_CONNECTION_POINT_MAP()
public: class class1c
{
public:
~class1c();
class1c();
public:
IAsyncEvent *pAsyncEvent;
};
auto_ptr< class1c>class1c_;//ошибки:
//error C2143: syntax error : missing ';' before '<'
//error C2501: 'auto_ptr' : missing storage-class or type specifiers
//error C2059: syntax error : '<'
//error C2238: unexpected token(s) preceding ';'
};