Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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.


Наверх

Титульная страница Поиск, карта сайта Написать письмо