{ Виток для главной формы управления масс-спектрометром При создании и запуске витка главная форма создается и показывается на мониторе. Виток создан для обеспечения следующих действий: 1) Правильной работы клавиатурного ввода в форму при работе в DLL, запущенная в главном витке DLL форма не получает клавиатурного ввода. 2) Независимое от главной программы функционирование системы управления. } {--------------------------------------------------------------------------- The control program for mass-spectrometer MI1201-AGM (c) Copyright Aleksandrov O.E., 2001 Molecular Physics department, USTU, Ekaterinsburg, K-2, 620002, RUSSIA phone 75-47-15 E-mail: aleks@dpt.ustu.ru Программа управления масс-спектрометром МИ1201-АГМ (c) Собственность Александрова О.Е., 2001 620002, Екатеринбург, К-2, УГТУ, Кафедра молекулярной физики тел. 75-47-15 E-mail: aleks@dpt.ustu.ru ----------------------------------------------------------------------------} unit MCAD_MI1201_FormThread; interface uses Classes, Forms, SyncObjs, Windows, MCAD_MI1201_Thread, MCAD_MI1201_Form; type TMainFormThread = class(TThread) private { Private declarations } prFinished:boolean; // Признак завершения витка prIsTerminated:TEvent; // Событие для ожидания завершения витка prIsRunning:TEvent; // Событие для ожидания запуска витка prMassSpectrometer:tMsThread; // Переменная для временного хранения ссылки на виток масс-спектрометра prTerminateTimeOut:cardinal; // Время ожидания выхода из витка, если не дождались, то виток аварийно завершается prApplication:tApplication; // Приложение витка; protected procedure Execute; override; procedure DoTerminate; override; public constructor Create(MassSpectrometer:tMsThread); destructor Destroy; override; function WaitForTerminate(TimeOut:cardinal):tWaitResult; // Завершение витка с ожиданием function WaitForStart(TimeOut:cardinal):tWaitResult; // Ожидание запуска витка procedure Terminate; // Завершение витка function TerminateAndWait:tWaitResult; // Завершение витка с ожиданием TerminateTimeOut function Terminated:boolean; // Признак завершения витка property Finished:boolean read prFinished; property TerminateTimeOut:cardinal read prTerminateTimeOut write prTerminateTimeOut; // Время ожидания выхода из витка, если не дождались, то виток аварийно завершается property Application:tApplication read prApplication; end; implementation USES MiscFunc, Controls, SysUtils, Messages; procedure TMainFormThread.DoTerminate; begin prIsRunning.ResetEvent; prIsTerminated.SetEvent; prFinished:=TRUE; end; procedure TMainFormThread.Execute; var LastMainThreadID:longword; OldApplication:tApplication; begin prFinished:=FALSE; prIsTerminated.ResetEvent; LastMainThreadID:=System.MainThreadID; System.MainThreadID:=GetCurrentThread; try prApplication:=tApplication.Create(NIL); OldApplication:=Forms.Application; Forms.Application:=prApplication; prApplication.HintHidePause:=4000; prApplication.CreateForm(TFormMain,FormMain); if Assigned(FormMain) then begin // prApplication.OnMessage:=FormMain.MessageEventBUG; prApplication.OnMinimize:=FormMain.DoMinimize; FormMain.MassSpectrometer:=prMassSpectrometer; prApplication.ShowHint:=OldApplication.ShowHint; prIsRunning.SetEvent; prApplication.Run; prIsRunning.ResetEvent; Priority:=tpHigher; end; except end; Forms.Application:=OldApplication; prApplication.Free; prApplication:=NIL; System.MainThreadID:=LastMainThreadID; end; constructor TMainFormThread.Create(MassSpectrometer:tMsThread); begin prFinished:=TRUE; prIsTerminated:=TEvent.Create(nil,TRUE,TRUE,''); prIsRunning:=TEvent.Create(nil,TRUE,FALSE,''); prMassSpectrometer:=MassSpectrometer; TerminateTimeOut:={$IfDef DEBUG}INFINITE{$Else}50000{$EndIf}; Inherited Create(not Assigned(prMassSpectrometer)); end; destructor TMainFormThread.Destroy; begin if TerminateAndWait<>wrSignaled then // Если завершения потока не дождались, то необходимо остановить его, иначе ЗАВИСАНИЕ Suspend; prIsTerminated.Free; prIsRunning.Free; Inherited; end; procedure TMainFormThread.Terminate; begin if Not Finished then begin Inherited Terminate; Priority:=tpHigher{est}; if Assigned(prApplication.MainForm) then begin PostMessage(prApplication.MainForm.Handle,WM_QUIT,0,0); end else begin prApplication.Terminate; end; end; end; // Завершение витка с ожиданием TerminateTimeOut function TMainFormThread.TerminateAndWait:tWaitResult; begin Terminate; Result:=WaitForTerminate(TerminateTimeOut); end; function TMainFormThread.Terminated:boolean; begin Result:=Inherited Terminated or prApplication.Terminated; end; function TMainFormThread.WaitForTerminate(TimeOut:cardinal):tWaitResult; begin if (GetCurrentThreadID=ThreadID) then begin Result:=wrAbandoned; end else begin if Finished then begin Result:=wrSignaled; end else begin Result:=prIsTerminated.WaitFor(TimeOut); if Result=wrSignaled then while (not Suspended) and (not Finished) do Sleep(1); end; end; end; function TMainFormThread.WaitForStart(TimeOut:cardinal):tWaitResult; begin if (GetCurrentThreadID=ThreadID) then begin Result:=wrAbandoned; end else begin Result:=prIsRunning.WaitFor(TimeOut); end; end; END.