![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Win API [D7, WinXP]
Тонго © (2006-07-24 01:50:00)Добрый день. Помогите с такой ситуацией. Есть DLL-ка ActiveX, в которой два метода WaitEvent – проверяет есть ли Event с именем EvName, если есть то ожидает его, если нет, создает и также ожидает. Второй метод ResEvent- проверяет есть ли Event с именем EvName, если есть то сигналит и закрывает хендл Event-а.
Из другого приложения, в отдельном потоке создается объект DLL-ки и запускается метод WaitEvent. Также в отдельном потоке создается объект DLL-ки и запускается метод ResEvent.
Объясняю в чем проблема. Из программы создается несколько Event-ов с разными именами, и ожидается сигнального состояния конкретного Event-а, но после запуска ResEvent сигналят сразу все Event-ы которые ожидались, хотя должен сигналить один, чье имя было передано.
Подскажите что я не так сделал. Заранее благодарен за ответы.
Код процедур ниже.
Initialization // DLL-ки
TAutoObjectFactory.Create(ComServer, TRunEvent, Class_RunEvent,
ciSingleInstance, tmFree);
---------------------------- в DLL --------------------------------
procedure TRunEvent.ResEvent(const EvName: WideString);
var
hEvent: Cardinal;
LastError: Integer;
begin
hEvent := OpenEvent(EVENT_ALL_ACCESS, True, PChar(EvName));
if hEvent = 0 then
begin
LastError := GetLastError;
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' +
SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
Exit;
end;
if not PulseEvent(hEvent) then
begin
LastError := GetLastError;
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' + SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
end;
if not CloseHandle(hEvent) then
begin
LastError := GetLastError;
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' + SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
end;
end;
procedure TRunEvent.WaitEvent(const EvName: WideString; var OutStr: WideString);
var
hEvent: Cardinal;
LastError: Integer;
SA: TSecurityAttributes;
SD: TSecurityDescriptor;
begin
InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION);
SA.nLength := SizeOf(SA);
SA.lpSecurityDescriptor := @SD;
SA.bInheritHandle := True;
hEvent := OpenEvent(SYNCHRONIZE, True, PChar(EvName));
if hEvent = 0 then
begin
LastError := GetLastError;
if LastError <> 2 then // 2 = нет такого Eventa
begin
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' +
SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
Exit;
end;
hEvent := CreateEvent(@SA, True, False, PChar(EvName));
if hEvent = 0 then
begin
LastError := GetLastError;
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' +
SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
Exit;
end;
end;
if WaitForSingleObject(hEvent, INFINITE) = WAIT_OBJECT_0 then
OutStr := 'SetEvent "' + EvName + '".'
else
begin
LastError := GetLastError;
if LastError <> 0 then
MessageBox(0, Pchar('#' + IntToStr(LastError) + '. ' +
SysErrorMessage(LastError)), 'AddIn.RunEvent', MB_ICONERROR);
OutStr := 'Not SetEvent "' + EvName + '".';
end;
end;
---------------------------- в приложении --------------------------------
// один поток
procedure REv.Execute;
var
CC: Variant;
begin
try
CoInitializeEx(nil, COINIT_MULTITHREADED);
CC := CreateOleObject('AddIn.RunEvent');
except
MessageBox(0, Pchar(SysErrorMessage(GetLastError)), '', MB_ICONERROR);
CC := Unassigned;
Exit;
end;
CC.WaitEvent(EventName, OutStr);
Synchronize(UpdateMemo);
CC := Unassigned;
CoUninitialize;
end;
// второй поток
procedure RevRes.Execute;
var
CC: Variant;
begin
try
CoInitializeEx(nil, COINIT_MULTITHREADED);
CC := CreateOleObject('AddIn.RunEvent');
except
MessageBox(0, Pchar(SysErrorMessage(GetLastError)), '', MB_ICONERROR);
CC := Unassigned;
Exit;
end;
CC.ResEvent(EventName);
CC := Unassigned;
CoUninitialize
end;
Сергей М. (2006-07-24 09:54:00) [1]
> сигналят сразу все Event-ы
Приведи дословно фрагмент лога, подтверждающего это ..
Тонго (2006-07-24 06:23:00) [2]Переписал, но проблемму это не решет.
// один поток
procedure REv.Execute;
var
CC: Variant;
begin
try
CoInitializeEx(nil, COINIT_MULTITHREADED);
CC := CreateOleObject('AddIn.RunEvent');
CC.WaitEvent(EventName, OutStr);
Synchronize(UpdateMemo);
finally
//MessageBox(0, Pchar(SysErrorMessage(GetLastError)), '', MB_ICONERROR);
CC := Unassigned;
CoUninitialize;
end;
end;
// второй поток
procedure RevRes.Execute;
var
CC: Variant;
begin
try
CoInitializeEx(nil, COINIT_MULTITHREADED);
CC := CreateOleObject('AddIn.RunEvent');
CC.ResEvent(EventName);
finally
//MessageBox(0, Pchar(SysErrorMessage(GetLastError)), '', MB_ICONERROR);
CC := Unassigned;
CoUninitialize;
end;
end;
KilkennyCat (2006-07-24 03:30:00) [3]я б для начала REV.EXecute и RevRes.Execute нормально бы переписал, вспомнив про finally.