unit CreateThreads; //============================================================================ // Создание потоков (основной и для форм) //============================================================================ interface uses Forms, Windows, Messages; function RunOnDemand:boolean; //запускает эмулятор и возвращает true если он запущен function WaitForTerminate(TimeOut:cardinal):boolean; //***************************************************************************** IMPLEMENTATION uses uMainForm, Hardware; function Start:boolean; forward; var VisualThreadHandle:THandle; VisualThreadID:dword; MainMutex:THandle; VisualThreadTerminated:boolean; //---------------------------------------------------------------------------- // Запускает эмулятор если не зупущен, возвращает true если запущен //---------------------------------------------------------------------------- function RunOnDemand:boolean; begin if not Assigned(MI1201AGM) then begin MI1201AGM:=tMI1201AGMEmulator.Create; if Assigned(MI1201AGM) then begin if not start then begin // MessageBox(0,'Графическая подсистема не запустилась', 'RunOnDemand', MB_OK); end; end; end; Result:=Assigned(MI1201AGM); end; //***************************************************************************** //***************************************************************************** //---------------------------------------------------------------------------- procedure CleanUp; begin CloseHandle(VisualThreadHandle); VisualThreadID:=0; CloseHandle(MainMutex); VisualThreadHandle:=0; MainMutex:=0; end; function WaitForTerminate(TimeOut:cardinal):boolean; begin Result:=VisualThreadTerminated; if not Result then begin case WaitForSingleObject(MainMutex, TimeOut) of WAIT_ABANDONED, WAIT_TIMEOUT: Result:=false; WAIT_OBJECT_0:begin Result:=true; end; end; end; end; //---------------------------------------------------------------------------- // Ждем остановки Визуальной части эмулятора заданное время //---------------------------------------------------------------------------- function TermitateTime(TimeOut:cardinal):boolean; begin Result:=VisualThreadTerminated; //Если запущена визуальная часть if not Result then begin if Assigned(MainForm) then begin PostMessage(MainForm.Handle, WM_QUIT,0,0); TerminateThread(VisualThreadHandle,0); result:=WaitForTerminate(TimeOut); end; end; end; //---------------------------------------------------------------------------- // Запускает визуальную часть эмулятора //---------------------------------------------------------------------------- function StartVCL(Parameters:pointer):dword; stdcall; var VisualAppl:TApplication; LastMainThreadID:longword; begin VisualThreadTerminated:=false; If WaitForSingleObject(MainMutex,10)=WAIT_OBJECT_0 then begin LastMainThreadID:=System.MainThreadID; System.MainThreadID:=GetCurrentThread; try VisualAppl:=TApplication.Create(nil); Forms.Application:=VisualAppl; VisualAppl.Initialize; VisualAppl.CreateForm(TMainForm, MainForm); VisualAppl.Run; forms.Application:=nil; VisualAppl.Free; except end; System.MainThreadID:=LastMainThreadID; end; ReleaseMutex(MainMutex); VisualThreadTerminated:=true; end; //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Запускает виток визуальной части эмулятора //---------------------------------------------------------------------------- function Start:boolean; begin //закрываем визуализационную часть, если что-то было открыто TermitateTime(infinite); CloseHandle(VisualThreadHandle); Result:=MainMutex<>0; if not Result then MainMutex:=CreateMutex(nil, false, nil); Result:=MainMutex<>0; ReleaseMutex(MainMutex); if Result then begin VisualThreadHandle:=CreateThread( nil, 0, @StartVCL, 0, 0, VisualThreadID ); Result:=VisualThreadHandle<>0; if not Result then begin MessageBox(0, 'Не удается содать виток','Start', MB_OK); end; end else begin MessageBox(0, 'Не удается содать mutex.','Start', MB_OK); end; if not Result then begin CleanUp; end; end; //----------------------------------------------------------------------------- initialization Application.Free; Application:=nil; VisualThreadTerminated:=true; finalization MI1201AGM.Destroy; while not TermitateTime(infinite)do begin end; TerminateThread(GetCurrentThread,0); CleanUp; end.