Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Win API   Найти похожие ветки 

 
Тонго   (2006-07-24 01:50) [0]

Добрый день. Помогите с такой ситуацией. Есть 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;


 
KilkennyCat ©   (2006-07-24 03:30) [1]

я б для начала REV.EXecute и RevRes.Execute нормально бы переписал, вспомнив про finally.


 
Тонго   (2006-07-24 06:23) [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;


 
Сергей М. ©   (2006-07-24 09:54) [3]


> сигналят сразу все Event-ы


Приведи дословно фрагмент лога, подтверждающего это ..



Страницы: 1 вся ветка

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.054 c
2-1163634950
Wadim
2006-11-16 02:55
2006.12.03
Тут был вопрос по поводу как словить клавиши в винде. А если..


5-1144509756
SaFy
2006-04-08 19:22
2006.12.03
Прозрачный Edit


2-1163510234
mfender
2006-11-14 16:17
2006.12.03
IHTMLElement и интерфейсы элементов


1-1161371943
SkySpeed
2006-10-20 23:19
2006.12.03
Как правильно организовать контроль за запускаемыми файлами?


15-1163178255
Ne-Ld
2006-11-10 20:04
2006.12.03
Назовите, пожалуйста, главные признаки проектов, в которых не сто