Uses Core,Win2K2,CoolKey,ccontr; { Используемые модули - Core - Основной модуль курсовика, само моделирование. (C) IE 2002 Win2K2 - Графический модуль, по возможности, аналогия иделологии Win32 API (C) Microsoft. Win2k2 (C) IE CoolKey - Модуль низкоукровневой работы с клавиатурой, используется в Win2k2, в головной программе необходим для клавиатурных констант CContr - Модуль для работы с Win2k2, в нем реализованы основные элементы интерфейса (EditBox, CheckBox, Button, XYPlot)} TYPE {Состояниия системы} EStatus = (ST_WAITING, {Система ожидает старта} ST_RUNNING, {Система в сост. работы} ST_FINISHED) {Сислема завершила моделирование}; const AStatus : array [EStatus] of string[15] = ('Waiting','Running', 'Finished'); {Сообщения о состоянии системы} var TextOut : Text; {Файловый дескриптор текстового вывода результатов} RunNum : Integer; {Номер запуска системы (по нему различаются файлы вывода} RunMode : boolean; {Режим работы (рабочий/отладочный)} Parent : hWNd; {Handle основного окна программы} Stat : EStatus; {Текущее рабочее состояние} OCButtons : Array [1..2] of hWnd; {Handl'ы кнопок [1] - OK, [2] - Stop} Edits : array [1..9] of hWnd; {Handl'ы полей ввода} Checks : array [0..5] of hWnd; {Handl'ы выбираемых кновоп} Mode : hWnd; {Handle селектора режима} Limits : array [1..2] of hWnd; {Handl'ы текстовых полей границ графика} Realiz : hWnd; {Handle поля ввода числа реализаций} RealNum : UINT32; {Само число реализаций} CurReal : UINT32; {Текущий номер раелизации, использеутся ислючительно для равномерного распределения точек в режиме отладки} Plot : hWnd; {Handle графика} {Динамические объекты - элементы системы массового обслуживания} { Описание - см. заголовок модуля Core.pas} Model : ^CModel; Buffer : PBuffer; Device : PDevice; Srcs1, Srcs2,Srcs3 : PSource; BegVal, {Начальные/конечные зн-я скорости прибора} LastVal : Real; Steps : integer; {Число шагов от начального к конечному зн-ю прибора (число точек на графике)} CurStep : integer; {Текущий шаг} BufferSize : integer; {Емкость буфера модели} S1,S2,S3 : Real; {Скорости источников} Delta, DovInt : real; {Настройки вероятностей} {----------------------------------------------------------------} Function GetFloat(aH:hWND):real; {Функция считывает вещественное зн-е из поля ввода} var st : string; ret : real; i : integer; begin GetWindowText(AH,@st,255); Val(st,ret,i); GetFloat := ret; end; {----------------------------------------------------------------} Procedure GetParams; {Считывание всех зн-ний из полей ввода} var st : string[50]; i : integer; v : real; begin BegVal := GetFloat(Edits[3]); LastVal := GetFloat(Edits[4]); DovInt := GetFloat(Edits[2]); Steps := Round(GetFloat(Edits[5])); BufferSize := Round(GetFloat(Edits[6])); S1 := Getfloat(Edits[7]); S2 := Getfloat(Edits[8]); S3 := Getfloat(Edits[9]); GetWindowText(Edits[1],@st,50); if st[ord(st[0])] = '%' then begin Val(copy(st,1,ord(st[0])-1),v,i); Delta := v/100.0; end else Val(st,Delta,i); end; Procedure InitModel; {Начальная инициализация значений модели и инициализация динамических объектов} begin Delta := 0.1; DovInt := 1.64; BegVal := 1.0; LastVal := 5.0; Steps := 20; BufferSize := 5; S1 := 2.0; S2 := 1.0; S3 := 5.0; New(Buffer, Init(BufferSize)); New(Device, Init(BegVal)); New(Model, Init(3,Device,Buffer,Delta,DovInt)); New(Srcs1,Init(0,S1)); Model^.AddNewSource(Srcs1); New(Srcs2,Init(1,S2)); Model^.AddNewSource(Srcs2); New(Srcs3,Init(2,S3)); Model^.AddNewSource(Srcs3); end; Procedure StartModel; {Процедура подготовки и старта моделирования при указанных значениях} var XY : TRPoint; nm : string; i : UINT8; begin Buffer^.SetBufferSize(BufferSize); Device^.Lambda := BegVal; Model^.Delta := Delta; Model^.DovInt := DovInt; Srcs1^.Lambda := S1; Srcs2^.Lambda := S2; Srcs3^.Lambda := S3; Model^.Start; for i := 0 to 5 do SendMessage(Plot,WM_SETVISIBLE,i,SendMessage(Checks[i],CB_GETCHECK,0,0)); S1 := GetFloat(Realiz); RealNum := round(S1); Model^.RealizSteps := RealNum; if RunMode then begin Model^.CalcVer := true; XY.X:=0; XY.Y:=Steps; for i := 0 to 5 do begin SendMessage(Plot,XP_DELALLPOINTS,i,0); SendMessage(Plot,XP_SETXRANGE,i,UINT32(@XY)); end; str(Steps,nm); SetWindowText(Limits[2],@nm); str(RunNum,nm); Inc(RunNum); nm := 'result.'+nm; Assign(TextOut,nm); Rewrite(TextOut); end else begin Model^.CalcVer := false; Str(RealNum,nm); SetWindowText(Limits[2],@nm); XY.X:=1; XY.Y:=RealNum; CurReal:=0; for i := 0 to 2 do begin SendMessage(Plot,XP_DELALLPOINTS,i,0); SendMessage(Plot,XP_SETXRANGE,i,UINT32(@XY)); SendMessage(Plot,WM_SETVISIBLE,i,SendMessage(Checks[i],CB_GETCHECK,0,0)); end; for i := 3 to 5 do begin SendMessage(Plot,XP_DELALLPOINTS,i,0); SendMessage(Plot,WM_SETVISIBLE,i,0); end; end; CurStep := 0; end; {Основной обработчик сообщений (messages) от системы (графического модуля). По идеологии Win32 API (C) Microsoft - основная процедура всей программы, в ней задается вся реакция на действия пользователя, наравне с внутренней логикой программы} Function WindowProc(ahWnd:HWND;aMsg,wParam,lParam:UINT32):UINT32;far; var ps : LPPAINTSTRUCT; XY,Max : TRPoint; st : string; i : UINT8; rt : RECT; begin case aMsg of WM_CREATE: {Первое сообщение после создания окна, в нем - инициализация и создание всех дочерних окон (полей ввода, и проч.)} begin OCButtons[1] := CreateWindow('OK','BUTTON',WS_CHILD, 66,350,50,30,ahWnd,NULL); PostMessage(OCButtons[1],CB_SETID,1,0); OCButtons[2] := CreateWindow('Exit','BUTTON',WS_CHILD, 152,350,60,30,ahWnd,NULL); PostMessage(OCButtons[2],CB_SETID,2,0); CreateWindow('Veroyatn','LABEL',WS_CHILD, 10,10,140,15,ahWnd,NULL); Edits[1]:=CreateWindow('10%','EDIT',WS_CHILD, 150,10,140,15,ahWnd,NULL); CreateWindow('Dov. Int','LABEL',WS_CHILD, 10,30,140,15,ahWnd,NULL); Edits[2]:=CreateWindow('0.82','EDIT',WS_CHILD, 150,30,140,15,ahWnd,NULL); CreateWindow('Beg. Lam ist','LABEL',WS_CHILD, 10,50,140,15,ahWnd,NULL); Edits[3]:=CreateWindow('1.0','EDIT',WS_CHILD, 150,50,140,15,ahWnd,NULL); CreateWindow('End Lam ist','LABEL',WS_CHILD, 10,70,140,15,ahWnd,NULL); Edits[4]:=CreateWindow('5.0','EDIT',WS_CHILD, 150,70,140,15,ahWnd,NULL); CreateWindow('Steps','LABEL',WS_CHILD, 10,90,140,15,ahWnd,NULL); Edits[5]:=CreateWindow('20','EDIT',WS_CHILD, 150,90,140,15,ahWnd,NULL); CreateWindow('Buf size','LABEL',WS_CHILD, 10,110,140,15,ahWnd,NULL); Edits[6]:=CreateWindow('5','EDIT',WS_CHILD, 150,110,140,15,ahWnd,NULL); CreateWindow('Lambda 1','LABEL',WS_CHILD, 10,130,140,15,ahWnd,NULL); Edits[7]:=CreateWindow('2.0','EDIT',WS_CHILD, 150,130,140,15,ahWnd,NULL); CreateWindow('Lambda 2','LABEL',WS_CHILD, 10,150,140,15,ahWnd,NULL); Edits[8]:=CreateWindow('1.0','EDIT',WS_CHILD, 150,150,140,15,ahWnd,NULL); CreateWindow('Lambda 3','LABEL',WS_CHILD, 10,170,140,15,ahWnd,NULL); Edits[9]:=CreateWindow('5.0','EDIT',WS_CHILD, 150,170,140,15,ahWnd,NULL); Plot := CreateWindow('Test plot','XYPLOT',WS_CHILD,310,10,300,300,ahWnd,NULL); SendMessage(Plot,XP_SETPLOTCOUNT,6,0); SendMessage(Plot,XP_SETCOLOR,0,Red); SendMessage(Plot,XP_SETCOLOR,1,Green); SendMessage(Plot,XP_SETCOLOR,2,Blue); SendMessage(Plot,XP_SETCOLOR,3,Magenta); SendMessage(Plot,XP_SETCOLOR,4,Yellow); SendMessage(Plot,XP_SETCOLOR,5,White); XY.X:=0; XY.Y:=100; SendMessage(Plot,XP_SETYRANGE,0,UINT32(@XY)); SendMessage(Plot,XP_SETYRANGE,1,UINT32(@XY)); SendMessage(Plot,XP_SETYRANGE,2,UINT32(@XY)); Limits[1] := CreateWindow('0','LABEL',WS_CHILD,310,320,20,15,ahWnd,NULL); Limits[2] := CreateWindow('20','LABEL',WS_CHILD,560,320,50,15,ahWnd,NULL); Checks[0] := CreateWindow('Ist1 Potk (Red)','CHECKBOX',WS_CHILD, 10,200,200,15,ahWnd,NULL); SendMessage(Checks[0],CB_SETCHECK,0,0); Checks[1] := CreateWindow('Ist2 Potk (Green)','CHECKBOX',WS_CHILD, 10,220,200,15,ahWnd,NULL); SendMessage(Checks[1],CB_SETCHECK,1,0); Checks[2] := CreateWindow('Ist3 Potk (Blue)','CHECKBOX',WS_CHILD, 10,240,200,15,ahWnd,NULL); SendMessage(Checks[2],CB_SETCHECK,0,0); Checks[3] := CreateWindow('Ist1 MatO (Magenta)','CHECKBOX',WS_CHILD, 10,260,200,15,ahWnd,NULL); SendMessage(Checks[3],CB_SETCHECK,0,0); Checks[4] := CreateWindow('Ist2 MatO (Yellow)','CHECKBOX',WS_CHILD, 10,280,200,15,ahWnd,NULL); SendMessage(Checks[4],CB_SETCHECK,1,0); Checks[5] := CreateWindow('Ist3 MatO (White)','CHECKBOX',WS_CHILD, 10,300,200,15,ahWnd,NULL); SendMessage(Checks[5],CB_SETCHECK,0,0); Mode := CreateWindow('Test mode','CHECKBOX', WS_CHILD, 210,200,100,15, ahWnd, NULL); CreateWindow('KMIN','LABEL',WS_CHILD,210,220,50,15,ahWnd,NULL); Realiz := CreateWindow('1000','EDIT',WS_CHILD,210,240,70,15,ahWnd,NULL); SendMessage(Mode,CB_SETCHECK,0,0); RunMode := true; SendMessage(Mode,CB_SETID,90,0); Randomize; Stat := ST_WAITING; for i := 0 to 5 do SendMessage(Checks[i],CB_SETID,i+100,0); InitModel; RunNum := 0; PostMessage(ahWnd,WM_PAINT,0,0); AddOnFrameMessage(ahWnd); end; WM_COMMAND: {Обработчик команд от конролов (кнопок, полей ввода, кнопок выбора)} begin case wParam of 1: if (lParam = 0) and (Stat <> ST_RUNNING) then begin {OK button pressed} GetParams; StartModel; Stat := ST_RUNNING; St := 'STOP'; SetWindowText(OCButtons[2],@St); PostMessage(ahWnd,WM_PAINT,0,0); PostMessage(OCButtons[2],WM_PAINT,0,0); end; 2: if lParam = 0 then {нажата кнопка STOP} begin if Stat = ST_RUNNING then begin if RunMode then Close(TextOut); Stat := ST_WAITING; St := 'Exit'; SetWindowText(OCButtons[2],@St); PostMessage(OCButtons[2],WM_PAINT,0,0); PostMessage(ahWnd,WM_PAINT,0,0); end else PostMessage(ahWnd,WM_DESTROY,0,0); end; 90: if lParam = 0 then begin {Вкл/выкл режим отладки} RunMode := not RunMode; for i := 3 to 5 do SendMessage(Checks[i],WM_SETVISIBLE,UINT32(RunMode),0); end; end; if (wParam >= 100) and (wParam <=105) and (lParam = 0) then begin SendMessage(Plot,WM_SETVISIBLE,wParam-100,SendMessage(Checks[wParam-100],CB_GETCHECK,0,0)); end; end; WM_ONFRAME: {Основной обработчик всей программы, здесь - внутреняя логика. Вызываются методы объектов модели для осуществления моделирования. Также происходит добавление точек на график, вывод текстовой информации в файл.} begin if Stat = ST_RUNNING then begin if Not Model^.Step then begin if Runmode then begin XY.X := CurStep; XY.Y := 100*Srcs1^.RefusedReq/Srcs1^.TotalReq; SendMessage(Plot,XP_ADDPOINT,0,UINT32(@XY)); XY.Y := 100*Srcs2^.RefusedReq/Srcs2^.TotalReq; SendMessage(Plot,XP_ADDPOINT,1,UINT32(@XY)); XY.Y := 100*Srcs3^.RefusedReq/Srcs3^.TotalReq; SendMessage(Plot,XP_ADDPOINT,2,UINT32(@XY)); if (Srcs1^.DoneReq <> 0) then begin XY.Y := Srcs1^.MatWait/Srcs1^.DoneReq; SendMessage(Plot,XP_ADDPOINT,3,UINT32(@XY)); end; if (Srcs2^.DoneReq <> 0) then begin XY.Y := Srcs2^.MatWait/Srcs2^.DoneReq; SendMessage(Plot,XP_ADDPOINT,4,UINT32(@XY)); end; if (Srcs3^.DoneReq <> 0) then begin XY.Y := Srcs3^.MatWait/Srcs3^.DoneReq; SendMessage(Plot,XP_ADDPOINT,5,UINT32(@XY)); end; Max.X := 0; Max.Y := 0; for i := 3 to 5 do begin SendMessage(Plot,XP_GETYRANGE,i,UINT32(@XY)); if XY.Y > Max.Y then Max.Y := XY.Y; end; for i := 3 to 5 do SendMessage(Plot,XP_SETYRANGE,i,UINT32(@Max)); PostMessage(Plot,WM_PAINT,0,0); Model^.PrintValues(TextOut); inc(CurStep); Device^.Lambda := BegVal + (LAstVal-BegVal)/Steps*Curstep; if CurStep = Steps+1 then begin Stat := ST_FINISHED; Close(TextOut); St := 'Exit'; SetWindowText(OCButtons[2],@St); PostMessage(OCButtons[2],WM_PAINT,0,0); PostMessage(ahWnd,WM_PAINT,0,0); end else Model^.Start; end else begin Stat := ST_FINISHED; St := 'Exit'; SetWindowText(OCButtons[2],@St); PostMessage(ahWnd,WM_PAINT,0,0); end; end else if not runmode then begin if CurReal = (RealNum div 100) then begin XY.X := Model^.CurStep; XY.Y := 100*Srcs1^.RefusedReq/Srcs1^.TotalReq; SendMessage(Plot,XP_ADDPOINT,0,UINT32(@XY)); XY.Y := 100*Srcs2^.RefusedReq/Srcs2^.TotalReq; SendMessage(Plot,XP_ADDPOINT,1,UINT32(@XY)); XY.Y := 100*Srcs3^.RefusedReq/Srcs3^.TotalReq; SendMessage(Plot,XP_ADDPOINT,2,UINT32(@XY)); CurReal := -1; PostMessage(Plot,WM_PAINT,0,0); end; Inc(CurReal); end; end; end; WM_DESTROY: {Сообщение, приходящее перед завершением работы программы, здесь происходит освобождение памяти и уничтожение объектов модели} begin if Stat <> ST_WAITING then begin Dispose(Model,Done); Dispose(Buffer,Done); Dispose(Device,Done); end; DelOnFrameMessage(ahWnd); PostQuitMessage(ahwnd); end; WM_KEYDOWN: {Реакция на нажатие клавиши клавиатуры} if wParam = ord(SC_ESCAPE) then PostMessage(ahWnd,WM_DESTROY,0,0); WM_PAINT: {Обработчик прорисовки окна. Выводит только статус моделирования, вся остальная прорисовка выполняется дочерними окнами самостоятельно} begin ps := BeginPaint(ahWNd); wSetColor(ps,GlobalPalette.WindowFontColor); wSetBgColor(ps,GlobalPalette.ThreeDColor1); wSetStyle(ps,SolidFill); wSetFontJustify(ps,CenterText,BottomText); GetClientRect(ahWnd,@rt); wBar(ps,0,rt.b.y - 20, rt.b.x,rt.b.y); wTextOut(ps,rt.b.x shr 1, rt.b.y-1, @AStatus[Stat]); EndPaint(ps); end; end; end; {ГОЛОВА.} begin if InitWin2K2 = ERR_OK then {Иниц. графической подсистемы} if RegisterClass('MSMO',WindowProc) = ERR_OK then {Регистрация класса, с таким обработчиком событий} begin InitCommonControls; {Инициализация стандартных классов} Parent:=CreateWindow('Configuration','MSMO', WS_TITLE OR WS_SIZEABLE OR WS_MINMAX, 10,10,620,420, NULL,NULL); {Создание основного окна} MainRunLoop; {Основной цикл программы} end; DoneWin2K2; {Завершение работы графической подсистемы} end.