16223

Динамическое создание объектов на базе стандартных классов DELPHI

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторная работа №12 Динамическое создание объектов на базе стандартных классов DELPHI Цель работы: Изучить принципы создания COMсервера и COMприложения Постановка задачи: Разработать COMсервер реализующий три метода решения нелинейных уравнений. Разработать COMкл...

Русский

2013-06-20

128.5 KB

5 чел.

Лабораторная работа №12

Динамическое создание объектов на базе стандартных классов DELPHI

Цель работы: Изучить принципы создания COM-сервера и COM-приложения

Постановка задачи: Разработать COM-сервер, реализующий три метода решения нелинейных уравнений. Разработать COM-клиент решения нелинейных уравнений различными методами

Краткие теоретические сведения:

Модель объектных компонентов – (COM, Component Object Model) является производственным стандартом Microsoft для обмена информацией между приложениями. Основная идея – обмен информацией независимо от языка написания приложения. Обычно COM-объекты представлены в виде EXE или DLL – файлов. Если выполнять Com-объект, находящийся на одном компьютере, с помощью процессорного времени второго компьютера, а результаты отправлять на третий компьютер – это не что иное, как распределенная модель COM (Distributed COMDCOM).

Для получения ссылки на COM-объект, используйте функцию CreateComObject(GUID). Получить всю информацию о зарегистрированном в реестре объекте COM, можно в соответствующей ветви раздела реестра HKEY_CLASSES_ROOT.

Когда приложение-клиент вызывает функцию CreateComObject(GUID), то он дает команду операционной системе создать экземпляр зарегистрированного класса. ОС просматривает реестр в поисках GUID этого класса, после чего возвращает ссылку в вызывающую программу и запускает приложение-сервер. Теперь можно обращаться к методам и свойствам COM-приложения как к собственным.

Текст программы:

UMainForm:

unit UMainForm;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, StdCtrls, ExtCtrls, ComCtrls, TeeProcs, TeEngine, Chart, Series,

 Buttons, UIEquation, BubbleCh, ComObj;

type

 TForm1 = class(TForm)

   EditMin: TEdit;

   EditMax: TEdit;

   RadioGroup1: TRadioGroup;

   EditEpsilon: TEdit;

   Label1: TLabel;

   Label2: TLabel;

   Label3: TLabel;

   Panel1: TPanel;

   Label4: TLabel;

   Label5: TLabel;

   Panel2: TPanel;

   Bevel1: TBevel;

   Label6: TLabel;

   Panel3: TPanel;

   Label7: TLabel;

   EditResult: TEdit;

   CheckBox1: TCheckBox;

   UpDown1: TUpDown;

   EditRound: TEdit;

   DisplayChart: TChart;

   Series1: TLineSeries;

   Series2: TPointSeries;

   SpeedButton1: TSpeedButton;

   CheckBox2: TCheckBox;

   SpeedButton2: TSpeedButton;

   Panel4: TPanel;

   Series3: TFastLineSeries;

   EditDelay: TEdit;

   UpDown2: TUpDown;

   Label8: TLabel;

   RadioGroup2: TRadioGroup;

   procedure CheckBox1Click(Sender: TObject);

   procedure SpeedButton1Click(Sender: TObject);

   procedure Wait(x: double);

   procedure EditRoundChange(Sender: TObject);

   procedure FormCreate(Sender: TObject);

   procedure SpeedButton2Click(Sender: TObject);

   procedure EditEpsilonKeyPress(Sender: TObject; var Key: Char);

   procedure CheckBox2Click(Sender: TObject);

   procedure EditDelayChange(Sender: TObject);

   procedure RadioGroup2Click(Sender: TObject);

   procedure RadioGroup1Click(Sender: TObject);

   procedure FormClose(Sender: TObject; var Action: TCloseAction);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

type

 TCalculationThread = class(TThread)

 private

   { Private declarations }

   FMessage: string;

 protected

   procedure Execute; override;

   procedure Mess;

 end;

var

 Form1: TForm1;

 e: IEquation;

 s: TCalculationThread;

 delayTime: integer=500;

implementation

{$R *.dfm}

procedure TCalculationThread.Execute;

begin

 { Place thread code here }

 try

   try

     e.Calculate;

   except

     on e1: Exception do

             begin

               FMessage:=e1.Message;

               Synchronize(Mess);

             end;

   end;

 finally

   Form1.CheckBox1Click(Form1.CheckBox1);  //Просто запись значения в EditResult с учётом округлять/не округлять

   Self.Terminate;

   Form1.SpeedButton1.Enabled:=true;

   Form1.SpeedButton2.Enabled:=false;

   Form1.Panel4.Enabled:=true;

   Self.Free;

 end;

end;

procedure TCalculationThread.Mess;

begin

 MessageDlg(FMessage, mtWarning, [mbOK], 0);

end;

procedure TForm1.CheckBox1Click(Sender: TObject);

begin

 EditRound.Enabled:=(Sender as TCheckBox).Checked;

 UpDown1.Enabled:=(Sender as TCheckBox).Checked;

 try

   if (Sender as TCheckBox).Checked then

     EditResult.Text:=FloatToStrF(e.Res, ffFixed, 15, StrToInt(EditRound.Text))

   else

     EditResult.Text:=FloatToStrF(e.Res, ffFixed, 15, 15);

 finally

 end;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);

begin

 try

   e.Min:=StrToFloat(EditMin.Text);

   e.Max:=StrToFloat(EditMax.Text);

   e.Epsilon:=StrToFloat(EditEpsilon.Text);

   e.Method:=RadioGroup1.ItemIndex;

 except

   on e1: ECantBeZero do

             begin

               MessageDlg(e1.Message, mtWarning, [mbOK], 0);

               exit;

             end;

   else

             begin

               MessageDlg('Неверное число!'#13#10'Проверьте, возможно в одно из полей введено не число!', mtError, [mbOK], 0);

               exit;

             end;

 end;

 SpeedButton1.Enabled:=false;

 SpeedButton2.Enabled:=true;

 Panel4.Enabled:=false;

 s:=TCalculationThread.Create(false);

end;

procedure TForm1.Wait(x: double);

begin

 if CheckBox2.Checked then

   sleep(delayTime);

end;

procedure TForm1.EditRoundChange(Sender: TObject);

begin

 CheckBox1Click(CheckBox1);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

try

 e:=(CreateComObject(Class_Equation) as IEquation);

 e.Chart:=DisplayChart;

 e.SetNewEquation(0, 0.5, 2, 0.001, RadioGroup1.ItemIndex);

 e.Calculate;

 e.OnNextStep:=Wait;

 CheckBox1Click(CheckBox1); //Просто запись значения в EditResult с учётом округлять/не округлять

 Panel4.Enabled:=true;

 SpeedButton1.Enabled:=true;

 CheckBox1.Enabled:=true;

except

end;

end;

procedure TForm1.SpeedButton2Click(Sender: TObject);

begin

 if s.Suspended then

   s.Resume

 else

   s.Suspend;

end;

procedure TForm1.EditEpsilonKeyPress(Sender: TObject; var Key: Char);

begin

 if not (Key in ['0'..'9', ',', '-', #8]) then

   Key:=chr(0);

end;

procedure TForm1.CheckBox2Click(Sender: TObject);

begin

 EditDelay.Enabled:=(Sender as TCheckBox).Checked;

 UpDown2.Enabled:=(Sender as TCheckBox).Checked;

end;

procedure TForm1.EditDelayChange(Sender: TObject);

begin

 delayTime:=StrToInt((Sender as TEdit).Text);

end;

procedure TForm1.RadioGroup2Click(Sender: TObject);

begin

 case (Sender as TRadioGroup).ItemIndex of

 0:  begin

       //e.Free;

       e.SetNewEquation(0, 0.5, 2, 0.001, RadioGroup1.ItemIndex);

       e.OnNextStep:=nil;

       EditMin.Text:='0,5';

       EditMax.Text:='2';

       EditEpsilon.Text:='0,001';

       e.Calculate;

       CheckBox1Click(CheckBox1);

       e.OnNextStep:=Wait;

     end;

 1:  begin

       //e.Free;

       e.SetNewEquation(1, 2, 3, 0.001, RadioGroup1.ItemIndex);

       e.OnNextStep:=nil;

       EditMin.Text:='2';

       EditMax.Text:='3';

       EditEpsilon.Text:='0,001';

       e.Calculate;

       CheckBox1Click(CheckBox1);

       e.OnNextStep:=Wait;

     end;

 2:  begin

       //e.Free;

       e.SetNewEquation(2, 2, 3, 0.001, RadioGroup1.ItemIndex);

       e.OnNextStep:=nil;

       EditMin.Text:='2';

       EditMax.Text:='3';

       EditEpsilon.Text:='0,001';

       e.Calculate;

       CheckBox1Click(CheckBox1);

       e.OnNextStep:=Wait;

     end;

 end;

end;

procedure TForm1.RadioGroup1Click(Sender: TObject);

begin

{  e.OnNextStep:=nil;

 e.Method:=RadioGroup1.ItemIndex;

 e.Calculate;

 CheckBox1Click(CheckBox1);

 e.OnNextStep:=Wait;

 }

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

 //e.FreeSelf;

 //Action:=caNone;

end;

end.

UIEquation:

unit UIEquation;

interface

uses SysUtils, Chart;

const

 Class_Equation: TGUID = '{C38FF40B-9B73-45AC-808C-D2633A4D25F0}';

 IID_IEquation: TGUID = '{8F0B1F0B-6D2D-4AE9-95DA-B571A5F8BA9D}';

const drawFSteps=50;

     drawFSpace=0.05;

     FMaxIterations=100;

type

 EMinNotLessThenMax=class(Exception);

 ETooMuchIterations=class(Exception);

 EDontMatchCondition=class(Exception);

 EZeroDenominator=class(Exception);

 EZeroDerivatite=class(Exception);

 ECantBeZero=class(Exception);

type

 TNextStepEvent=procedure(x: double) of object;

type

 IEquation=interface (IUnknown)

 ['{8F0B1F0B-6D2D-4AE9-95DA-B571A5F8BA9D}']

   function GetMin: Double;

   procedure SetMin(const Value: Double);

   function GetChart: TChart;

   function GetEpsilon: Double;

   function GetMax: Double;

   function GetMethod: integer;

   function GetOnNextStep: TNextStepEvent;

   function GetResult: Double;

   procedure SetChart(const Value: TChart);

   procedure SetMax(const Value: Double);

   procedure SetMethod(const Value: integer);

   procedure SetOnNextStep(const Value: TNextStepEvent);

   procedure SetEpsilon(AEpsilon: double);

   procedure SetNewEquation(AEquation: integer; AMin, AMax, AEpsilon: double; AMethod: integer);

   property Min: Double read GetMin write SetMin;

   property Max: Double read GetMax write SetMax;

   property Epsilon: Double read GetEpsilon write SetEpsilon;

   property Res: Double read GetResult;

   property Method: integer read GetMethod write SetMethod;

   property Chart: TChart read GetChart write SetChart;

   property OnNextStep: TNextStepEvent read GetOnNextStep write SetOnNextStep;

   procedure Calculate;

 end;

implementation

end.

UEquation:

unit UEquation;

interface

uses SysUtils, Chart, Math, UIEquation;

type

 TEquation=class (TInterfacedObject, IEquation)

 private

   FMin: Double;

   FMax: Double;

   FEpsilon: Double;

   FResult: Double;

   FMethod: Integer;

   FOnNextStep: TNextStepEvent;

   FChart: TChart;

   FEquation: Integer;

   function GetMin: Double;

   procedure SetMin(const Value: Double);

   function GetChart: TChart;

   function GetEpsilon: Double;

   function GetMax: Double;

   function GetMethod: integer;

   function GetOnNextStep: TNextStepEvent;

   function GetResult: Double;

   procedure SetChart(const Value: TChart);

   procedure SetMax(const Value: Double);

   procedure SetMethod(const Value: integer);

   procedure SetOnNextStep(const Value: TNextStepEvent);

 public

   constructor Create; overload;

   constructor Create(AMin, AMax, AEpsilon: double; AMethod: integer; AChart: TChart); overload;

   function F(x: Double): Double; virtual;

   function Phi(x: Double): Double; virtual;

   function FirstDerivative(x: Double): Double; virtual;

   function SecondDerivative(x: Double): Double; virtual;

   function F1(x: Double): Double; virtual;

   function Phi1(x: Double): Double; virtual;

   function FirstDerivative1(x: Double): Double; virtual;

   function SecondDerivative1(x: Double): Double; virtual;

   function F2(x: Double): Double; virtual;

   function Phi2(x: Double): Double; virtual;

   function FirstDerivative2(x: Double): Double; virtual;

   function SecondDerivative2(x: Double): Double; virtual;

   function F3(x: Double): Double; virtual;

   function Phi3(x: Double): Double; virtual;

   function FirstDerivative3(x: Double): Double; virtual;

   function SecondDerivative3(x: Double): Double; virtual;

   procedure SetEpsilon(AEpsilon: double); virtual;

   property Min: Double read GetMin write SetMin;

   property Max: Double read GetMax write SetMax;

   property Epsilon: Double read GetEpsilon write SetEpsilon;

   property Res: Double read GetResult;

   property Method: integer read GetMethod write SetMethod;

   property Chart: TChart read GetChart write SetChart;

   property OnNextStep: TNextStepEvent read GetOnNextStep write SetOnNextStep;

   procedure Calculate; virtual;

   function Calculate_HalfDividing: Double; virtual;

   function Calculate_Iterations: Double; virtual;

   function Calculate_Newton: Double; virtual;

   procedure DrawF; virtual;

   procedure DrawStep(x: double); virtual;

   procedure DrawStep2(x: double); virtual;

   procedure SetNewEquation(AEquation: integer; AMin, AMax, AEpsilon: double; AMethod: integer);

 end;

implementation

//TEquation1

 function TEquation.F2(x: Double): Double;

 begin

   Result:=3*sin(sqrt(x))+0.35*x-3.8;

   //Self.Free;

 end;

 function TEquation.Phi2(x: Double): Double;

 begin

   Result:=-8.571*sin(sqrt(x))+10.8571;

 end;

 function TEquation.FirstDerivative2(x: Double): Double;

 begin

   Result:=1.5*cos(sqrt(x))/sqrt(x)+0.35;

 end;

 function TEquation.SecondDerivative2(x: Double): Double;

 begin

   Result:=-0.75*(sin(sqrt(x))+cos(sqrt(x)))/(x*sqrt(x));

 end;

//TEquation1

 function TEquation.F3(x: Double): Double;

 begin

   Result:=ln(x)-x+1.8;

 end;

 function TEquation.Phi3(x: Double): Double;

 begin

   Result:=ln(x)+1.8;

 end;

 function TEquation.FirstDerivative3(x: Double): Double;

 begin

   Result:=1/x-1;

 end;

 function TEquation.SecondDerivative3(x: Double): Double;

 begin

   Result:=-1/sqr(x);

 end;

//TEquation

 constructor TEquation.Create;

 begin

   inherited Create;

   FMin:=0;

   FMax:=2;

   FEpsilon:=0.001;

 end;

 constructor TEquation.Create(AMin, AMax, AEpsilon: double; AMethod: integer; AChart: TChart);

 begin

   inherited Create;

   FMin:=AMin;

   FMax:=AMax;

   FEpsilon:=AEpsilon;

   FMethod:=AMethod;

   FChart:=AChart;

   DrawF;

 end;

 procedure TEquation.SetEpsilon(AEpsilon: double);

 begin

   if (AEpsilon=0) then

     raise ECantBeZero.Create('Точность не может равняться 0!');

     FEpsilon:=abs(AEpsilon);

 end;

 procedure TEquation.Calculate;

 begin

   if not (FMin<FMax) then

     raise EMinNotLessThenMax.Create('Нижняя граница должна быть меньше верхней!');

   if assigned(FChart) then

   begin

     FChart.Series[1].Clear;

     FChart.Series[2].Clear;

   end;

   case FMethod of

   1: FResult:=Calculate_Iterations;

   2: FResult:=Calculate_Newton;

   else

      FResult:=Calculate_HalfDividing;

   end;

 end;

 procedure TEquation.DrawF;

 var

   leftBorder, rightBorder, h, x: double;

   i: integer;

 begin

   if assigned(FChart) then

   begin

     FChart.Series[0].Clear;

     leftBorder:=FMin-(FMax-Fmin)*drawFSpace;

     rightBorder:=FMax+(FMax-Fmin)*drawFSpace;

     h:=(rightBorder-leftBorder)/drawFSteps;

     x:=leftBorder;

     for i:=0 to drawFSteps do

     begin

       FChart.Series[0].AddXY(x, f(x));

       x:=x+h;

     end;

   end;

 end;

 function TEquation.F1(x: Double): Double;

 begin

   Result:=0.25*power(x, 3)+x-1.2502;

 end;

 function TEquation.Phi1(x: Double): Double;

 begin

   Result:=-0.25*power(x, 3)+1.2502;

 end;

 function TEquation.FirstDerivative1(x: Double): Double;

 begin

   Result:=0.75*power(x, 2)+1;

 end;

 function TEquation.SecondDerivative1(x: Double): Double;

 begin

   Result:=1.5*x+1;

 end;

 function TEquation.Calculate_HalfDividing: Double;

 var B, A, x0: double;

     N: integer;

 begin

   if not (F(FMin)*F(FMax)<0) then

     raise EDontMatchCondition.Create('Для метода половинного деления необходимо, чтобы функция на концах промежутка иммела разные знаки!');

   N:=0;

   B:=FMax;

   A:=FMin;

   if F(A)=0 then

   begin

     Result:=A;

     DrawStep(A);

     exit;

   end;

   if F(B)=0 then

   begin

     Result:=B;

     DrawStep(B);

     exit;

   end;

   while ((B-A)>(FEpsilon*2)) do

   begin

     if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     x0:=(B+A)/2;

     if F(x0)=0 then

       break;

     DrawStep(x0);

     if (F(A)*F(x0)<0) then

       B:=x0

     else

       A:=x0;

     inc(N);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x0);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x0);

   end;

   Result:=(B+A)/2;

   if Assigned(FChart) then

   begin

       FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

       FChart.Series[1].Title:='X='+FloatToStr(Result);

   end;

 end;

 function TEquation.Calculate_Iterations: Double;

 var N: integer;

     x0, x1{, x2, y0, y1, y2, d1, d2}: double;

 begin

    N:=1;

    x1:=(FMax+FMin)/2;

    DrawStep(x1);

    repeat

     x0:=x1;

      if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     inc(N);

     x1:=Phi(x0);

     DrawStep(x1);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x1);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x1);

    until ((x1-x0)<FEpsilon);

    Result:=x1;

 end;

 function TEquation.Calculate_Newton: Double;

 var N: integer;

     x0, x1, d: double;

 begin

   N:=1;

   x1:=FMin;

   if F(FMax)*SecondDerivative(FMax)>0 then

     x1:=FMax;

   DrawStep2(x1);

   if Assigned(FOnNextStep) then

       FOnNextStep(x1);

   repeat

     if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     x0:=x1;

     if FirstDerivative(X0)=0 then

       raise EZeroDerivatite.Create('На шаге '+inttostr(N)+' производная стала равна нулю!');

     x1:=x0-(F(x0)/FirstDerivative(X0));

     DrawStep2(x1);

     inc(N);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x1);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x1);

     if abs(x1)>1 then

       d:=(x1-x0)/x1

     else

       d:=x1-x0;

   until ((d<=FEpsilon) and (abs(F(x1))<=100*Fepsilon));

   Result:=x1;

   if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(Result);

     end;

 end;

 procedure TEquation.DrawStep(x: Double);

 begin

   if Assigned(FChart) then

     FChart.Series[1].AddXY(x, F(x));

 end;

 procedure TEquation.DrawStep2(x: Double);

 begin

   if Assigned(FChart) then

   begin

     if ((F(x)<0) and (FirstDerivative(x)>0)) then

     begin

       FChart.Series[1].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, 0);

       FChart.Series[2].AddXY(x, F(x));

     end

     else

     begin

       FChart.Series[1].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, 0);

     end

   end;

 end;

function TEquation.F(x: Double): Double;

begin

 case FEquation of

   1: Result:=F2(x);

   2: Result:=F3(x);

   else Result:=F1(x);

 end;

end;

function TEquation.FirstDerivative(x: Double): Double;

begin

 case FEquation of

   1: Result:=FirstDerivative2(x);

   2: Result:=FirstDerivative3(x);

   else Result:=FirstDerivative1(x);

 end;

end;

function TEquation.Phi(x: Double): Double;

begin

 case FEquation of

   1: Result:=Phi2(x);

   2: Result:=Phi3(x);

   else Result:=Phi1(x);

 end;

end;

function TEquation.SecondDerivative(x: Double): Double;

begin

 case FEquation of

   1: Result:=SecondDerivative2(x);

   2: Result:=SecondDerivative3(x);

   else Result:=SecondDerivative1(x);

 end;

end;

procedure TEquation.SetNewEquation(AEquation: integer; AMin, AMax,

 AEpsilon: double; AMethod: integer);

begin

   FEquation:=AEquation;

   FMin:=AMin;

   FMax:=AMax;

   FEpsilon:=AEpsilon;

   FMethod:=AMethod;

   DrawF;

end;

function TEquation.GetMin: Double;

begin

 Result:=FMin;

end;

procedure TEquation.SetMin(const Value: Double);

begin

 FMin:=Value;

end;

function TEquation.GetChart: TChart;

begin

 Result:=FChart;

end;

function TEquation.GetEpsilon: Double;

begin

 Result:=FEpsilon;

end;

function TEquation.GetMax: Double;

begin

 Result:=FMax;

end;

function TEquation.GetMethod: integer;

begin

 Result:=FMethod;

end;

function TEquation.GetOnNextStep: TNextStepEvent;

begin

 Result:=FOnNextStep;

end;

function TEquation.GetResult: Double;

begin

 Result:=FResult;

end;

procedure TEquation.SetChart(const Value: TChart);

begin

 FChart:=Value;

end;

procedure TEquation.SetMax(const Value: Double);

begin

 FMax:=Value;

end;

procedure TEquation.SetMethod(const Value: integer);

begin

 FMethod:=Value;

end;

procedure TEquation.SetOnNextStep(const Value: TNextStepEvent);

begin

 FOnNextStep:=Value;

end;

end.

UEquation_COM:

unit UEquation_COM;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses

 Windows, ActiveX, Classes, ComObj, UIEquation, Chart, Math, SysUtils;

type

 TEquation=class (TComObject, IEquation)

 private

   FMin: Double;

   FMax: Double;

   FEpsilon: Double;

   FResult: Double;

   FMethod: Integer;

   FOnNextStep: TNextStepEvent;

   FChart: TChart;

   FEquation: Integer;

 public

   constructor Create; overload;

   constructor Create(AMin, AMax, AEpsilon: double; AMethod: integer; AChart: TChart); overload;

   function F(x: Double): Double; virtual;

   function Phi(x: Double): Double; virtual;

   function FirstDerivative(x: Double): Double; virtual;

   function SecondDerivative(x: Double): Double; virtual;

   function F1(x: Double): Double; virtual;

   function Phi1(x: Double): Double; virtual;

   function FirstDerivative1(x: Double): Double; virtual;

   function SecondDerivative1(x: Double): Double; virtual;

   function F2(x: Double): Double; virtual;

   function Phi2(x: Double): Double; virtual;

   function FirstDerivative2(x: Double): Double; virtual;

   function SecondDerivative2(x: Double): Double; virtual;

   function F3(x: Double): Double; virtual;

   function Phi3(x: Double): Double; virtual;

   function FirstDerivative3(x: Double): Double; virtual;

   function SecondDerivative3(x: Double): Double; virtual;

   function GetMin: Double;

   procedure SetMin(const Value: Double);

   function GetChart: TChart;

   function GetEpsilon: Double;

   function GetMax: Double;

   function GetMethod: integer;

   function GetOnNextStep: TNextStepEvent;

   function GetResult: Double;

   procedure SetChart(const Value: TChart);

   procedure SetMax(const Value: Double);

   procedure SetMethod(const Value: integer);

   procedure SetOnNextStep(const Value: TNextStepEvent);

   

   procedure SetEpsilon(AEpsilon: double); virtual;

   property Min: Double read GetMin write SetMin;

   property Max: Double read GetMax write SetMax;

   property Epsilon: Double read GetEpsilon write SetEpsilon;

   property Res: Double read GetResult;

   property Method: integer read GetMethod write SetMethod;

   property Chart: TChart read GetChart write SetChart;

   property OnNextStep: TNextStepEvent read GetOnNextStep write SetOnNextStep;

   procedure Calculate; virtual;

   function Calculate_HalfDividing: Double; virtual;

   function Calculate_Iterations: Double; virtual;

   function Calculate_Newton: Double; virtual;

   procedure DrawF; virtual;

   procedure DrawStep(x: double); virtual;

   procedure DrawStep2(x: double); virtual;

   procedure SetNewEquation(AEquation: integer; AMin, AMax, AEpsilon: double; AMethod: integer);

 end;

implementation

uses ComServ;

//TEquation1

 function TEquation.F2(x: Double): Double;

 begin

   Result:=3*sin(sqrt(x))+0.35*x-3.8;

   //Self.Free;

 end;

 function TEquation.Phi2(x: Double): Double;

 begin

   Result:=-8.571*sin(sqrt(x))+10.8571;

 end;

 function TEquation.FirstDerivative2(x: Double): Double;

 begin

   Result:=1.5*cos(sqrt(x))/sqrt(x)+0.35;

 end;

 function TEquation.SecondDerivative2(x: Double): Double;

 begin

   Result:=-0.75*(sin(sqrt(x))+cos(sqrt(x)))/(x*sqrt(x));

 end;

//TEquation1

 function TEquation.F3(x: Double): Double;

 begin

   Result:=ln(x)-x+1.8;

 end;

 function TEquation.Phi3(x: Double): Double;

 begin

   Result:=ln(x)+1.8;

 end;

 function TEquation.FirstDerivative3(x: Double): Double;

 begin

   Result:=1/x-1;

 end;

 function TEquation.SecondDerivative3(x: Double): Double;

 begin

   Result:=-1/sqr(x);

 end;

//TEquation

 constructor TEquation.Create;

 begin

   inherited Create;

   FMin:=0;

   FMax:=2;

   FEpsilon:=0.001;

 end;

 constructor TEquation.Create(AMin, AMax, AEpsilon: double; AMethod: integer; AChart: TChart);

 begin

   inherited Create;

   FMin:=AMin;

   FMax:=AMax;

   FEpsilon:=AEpsilon;

   FMethod:=AMethod;

   FChart:=AChart;

   DrawF;

 end;

 procedure TEquation.SetEpsilon(AEpsilon: double);

 begin

   if (AEpsilon=0) then

     raise ECantBeZero.Create('Точность не может равняться 0!');

     FEpsilon:=abs(AEpsilon);

 end;

 procedure TEquation.Calculate;

 begin

   if not (FMin<FMax) then

     raise EMinNotLessThenMax.Create('Нижняя граница должна быть меньше верхней!');

   if assigned(FChart) then

   begin

     FChart.Series[1].Clear;

     FChart.Series[2].Clear;

   end;

   case FMethod of

   1: FResult:=Calculate_Iterations;

   2: FResult:=Calculate_Newton;

   else

      FResult:=Calculate_HalfDividing;

   end;

 end;

 procedure TEquation.DrawF;

 var

   leftBorder, rightBorder, h, x: double;

   i: integer;

 begin

   if assigned(FChart) then

   begin

     FChart.Series[0].Clear;

     leftBorder:=FMin-(FMax-Fmin)*drawFSpace;

     rightBorder:=FMax+(FMax-Fmin)*drawFSpace;

     h:=(rightBorder-leftBorder)/drawFSteps;

     x:=leftBorder;

     for i:=0 to drawFSteps do

     begin

       FChart.Series[0].AddXY(x, f(x));

       x:=x+h;

     end;

   end;

 end;

 function TEquation.F1(x: Double): Double;

 begin

   Result:=0.25*power(x, 3)+x-1.2502;

 end;

 function TEquation.Phi1(x: Double): Double;

 begin

   Result:=-0.25*power(x, 3)+1.2502;

 end;

 function TEquation.FirstDerivative1(x: Double): Double;

 begin

   Result:=0.75*power(x, 2)+1;

 end;

 function TEquation.SecondDerivative1(x: Double): Double;

 begin

   Result:=1.5*x+1;

 end;

 function TEquation.Calculate_HalfDividing: Double;

 var B, A, x0: double;

     N: integer;

 begin

   if not (F(FMin)*F(FMax)<0) then

     raise EDontMatchCondition.Create('Для метода половинного деления необходимо, чтобы функция на концах промежутка иммела разные знаки!');

   N:=0;

   B:=FMax;

   A:=FMin;

   if F(A)=0 then

   begin

     Result:=A;

     DrawStep(A);

     exit;

   end;

   if F(B)=0 then

   begin

     Result:=B;

     DrawStep(B);

     exit;

   end;

   while ((B-A)>(FEpsilon*2)) do

   begin

     if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     x0:=(B+A)/2;

     if F(x0)=0 then

       break;

     DrawStep(x0);

     if (F(A)*F(x0)<0) then

       B:=x0

     else

       A:=x0;

     inc(N);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x0);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x0);

   end;

   Result:=(B+A)/2;

   if Assigned(FChart) then

   begin

       FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

       FChart.Series[1].Title:='X='+FloatToStr(Result);

   end;

 end;

 function TEquation.Calculate_Iterations: Double;

 var N: integer;

     x0, x1{, x2, y0, y1, y2, d1, d2}: double;

 begin

    N:=1;

    x1:=(FMax+FMin)/2;

    DrawStep(x1);

    repeat

     x0:=x1;

      if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     inc(N);

     x1:=Phi(x0);

     DrawStep(x1);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x1);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x1);

    until ((x1-x0)<FEpsilon);

    Result:=x1;

 end;

 function TEquation.Calculate_Newton: Double;

 var N: integer;

     x0, x1, d: double;

 begin

   N:=1;

   x1:=FMin;

   if F(FMax)*SecondDerivative(FMax)>0 then

     x1:=FMax;

   DrawStep2(x1);

   if Assigned(FOnNextStep) then

       FOnNextStep(x1);

   repeat

     if N>FMaxIterations then

       raise ETooMuchIterations.Create('Превышено максимальное количество итераций ('+inttostr(FMaxIterations)+')!');

     x0:=x1;

     if FirstDerivative(X0)=0 then

       raise EZeroDerivatite.Create('На шаге '+inttostr(N)+' производная стала равна нулю!');

     x1:=x0-(F(x0)/FirstDerivative(X0));

     DrawStep2(x1);

     inc(N);

     if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(x1);

     end;

     if Assigned(FOnNextStep) then

       FOnNextStep(x1);

     if abs(x1)>1 then

       d:=(x1-x0)/x1

     else

       d:=x1-x0;

   until ((d<=FEpsilon) and (abs(F(x1))<=100*Fepsilon));

   Result:=x1;

   if Assigned(FChart) then

     begin

         FChart.Series[0].Title:='Функция ('+inttostr(N)+' итераций).';

         FChart.Series[1].Title:='X='+FloatToStr(Result);

     end;

 end;

 procedure TEquation.DrawStep(x: Double);

 begin

   if Assigned(FChart) then

     FChart.Series[1].AddXY(x, F(x));

 end;

 procedure TEquation.DrawStep2(x: Double);

 begin

   if Assigned(FChart) then

   begin

     if ((F(x)<0) and (FirstDerivative(x)>0)) then

     begin

       FChart.Series[1].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, 0);

       FChart.Series[2].AddXY(x, F(x));

     end

     else

     begin

       FChart.Series[1].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, F(x));

       FChart.Series[2].AddXY(x, 0);

     end

   end;

 end;

function TEquation.F(x: Double): Double;

begin

 case FEquation of

   1: Result:=F2(x);

   2: Result:=F3(x);

   else Result:=F1(x);

 end;

end;

function TEquation.FirstDerivative(x: Double): Double;

begin

 case FEquation of

   1: Result:=FirstDerivative2(x);

   2: Result:=FirstDerivative3(x);

   else Result:=FirstDerivative1(x);

 end;

end;

function TEquation.Phi(x: Double): Double;

begin

 case FEquation of

   1: Result:=Phi2(x);

   2: Result:=Phi3(x);

   else Result:=Phi1(x);

 end;

end;

function TEquation.SecondDerivative(x: Double): Double;

begin

 case FEquation of

   1: Result:=SecondDerivative2(x);

   2: Result:=SecondDerivative3(x);

   else Result:=SecondDerivative1(x);

 end;

end;

procedure TEquation.SetNewEquation(AEquation: integer; AMin, AMax,

 AEpsilon: double; AMethod: integer);

begin

   FEquation:=AEquation;

   FMin:=AMin;

   FMax:=AMax;

   FEpsilon:=AEpsilon;

   FMethod:=AMethod;

   DrawF;

end;

function TEquation.GetMin: Double;

begin

 Result:=FMin;

end;

procedure TEquation.SetMin(const Value: Double);

begin

 FMin:=Value;

end;

function TEquation.GetChart: TChart;

begin

 Result:=FChart;

end;

function TEquation.GetEpsilon: Double;

begin

 Result:=FEpsilon;

end;

function TEquation.GetMax: Double;

begin

 Result:=FMax;

end;

function TEquation.GetMethod: integer;

begin

 Result:=FMethod;

end;

function TEquation.GetOnNextStep: TNextStepEvent;

begin

 Result:=FOnNextStep;

end;

function TEquation.GetResult: Double;

begin

 Result:=FResult;

end;

procedure TEquation.SetChart(const Value: TChart);

begin

 FChart:=Value;

end;

procedure TEquation.SetMax(const Value: Double);

begin

 FMax:=Value;

end;

procedure TEquation.SetMethod(const Value: integer);

begin

 FMethod:=Value;

end;

procedure TEquation.SetOnNextStep(const Value: TNextStepEvent);

begin

 FOnNextStep:=Value;

end;

initialization

 TComObjectFactory.Create(ComServer, TEquation, Class_Equation,

   'TEquation', '', ciMultiInstance, tmApartment);

end.

Результаты работы программы:

 

 

 

Выводы: таким образом, мы изучили способы работы с компонентами COM. Мы научились создавать COM-сервер и COM-клиент.


 

А также другие работы, которые могут Вас заинтересовать

78513. Назначение и функции операционных систем, их архитектурные типы, классификация и основные семейства 27.5 KB
  ОС – это комплекс управляющих и обрабатывающих программ, который, с одной стороны, выступает как интерфейс между пользователем и аппаратными компонентами вычислительных машин и вычислительных систем, а с другой стороны предназначен для эффективного управления вычислительными процессами
78514. Операционные системы: концепции и механизмы управления процессами и ресурсами 38 KB
  Функциями ОС по управлению памятью являются: отслеживание свободной и занятой памяти выделение памяти процессам и освобождение памяти при завершении процессов вытеснение процессов из оперативной памяти на диск когда размеры основной памяти не достаточны для размещения в ней всех процессов и возвращение их в оперативную память когда в ней освобождается место а также настройка адресов программы на конкретную область физической памяти. Так как во время трансляции в общем случае не известно в какое место оперативной памяти будет загружена...
78515. Операционные системы: управление файлами и файловые системы 28.5 KB
  Файловая система NTFS. Файл в системе NTFS – это не просто линейная последовательность байтов как в системе FT. Отличительными свойствами ФС NTFS являются: Поддержка больших файлов и больших дисков объемом до 264 байт. Структура тома раздела NTFS: Все пространство тома NTFS представляет собой либо файл либо часть файла.
78516. Основные характеристики и особенности организации современных операционных систем 26.5 KB
  Типы ОС: общие специальные и специализированные бортовой автокомпьютер CISCO – управление коммутаторами и маршрутизаторами Общая характеристика Windows XP. Windows XP объединяет в себе лучшие качества предыдущих версий Windows: надежность стабильность и управляемость – от Windows 2000 простой и понятный интерфейс а также технологию Plug Ply – от Windows 98. В Windows XP появился новый более эффективный интерфейс пользователя включающий новые возможности группировки и поиска документов новый внешний вид возможность быстрого...
78517. Основные задачи системного администрирования и их практическая реализация 33 KB
  Важнейшей сферой профессиональной деятельности специалистов в области информационных технологий является управление администрирование функционированием ОС как отдельных компьютеров так и их групп объединенных в вычислительные сети. Системное администрирование в общем случае сводится к решению следующих основных задач: управление и обслуживание пользователей вычислительной системы – создание и поддержка учетных записей пользователей управление доступом пользователей к ресурсам; управление и обслуживание ресурсов вычислительной системы –...
78518. Понятие, назначение и основные принципы организации распределенной обработки информации. Архитектура, свойства и характеристики распределенных систем 29.5 KB
  Понятие назначение и основные принципы организации распределенной обработки информации. Под распределенной обработкой информации понимается комплекс операций с информацией проводимый на независимых но связанных между собой ВМ предназначенных для выполнения общих задач. Возможность взаимодействия вычислительных систем при реализации распределенной обработки информации определяют как их способность к совместному использованию данных или к совместной работе с использованием стандартных интерфейсов. Целью распределенной обработки информации...
78519. Концепции и механизмы практической реализации распределенной обработки информации 27 KB
  Концепции и механизмы практической реализации распределенной обработки информации. Одним из исторически первых механизмов реализации распределенной обработки информации является механизм удаленного вызова процедур RPC который поддерживает синхронный режим коммуникаций между двумя прикладными модулями клиентом и сервером. RPC реализует в распределенной среде принципы традиционного структурного программирования. Применение объектно-ориентированного подхода способствует значительному усовершенствованию механизмов организации распределенной...
78520. Эволюция технических средств в обработке информации. Классификация, структурное построение и основные параметры вычислительных машин 28 KB
  Классификация структурное построение и основные параметры вычислительных машин. Предшественниками вычислительных машин были механические и электромеханические счетные устройства. Эта машина во многом была прообразом современных универсальных вычислительных машин. Лебедевым независимо от фон Неймана были сформулированы более детальные и полные принципы построения электронных цифровых вычислительных машин которые были применены при создании первых отечественных разработок ВМ Первый период 19451955.
78521. Основные аппаратные составляющие и перифирийные устройства компьютеров, их назначение, типы, принципы функционирования и характеристики 33 KB
  Процессор является основным вычислительным устройством ВМ в задачу которого входит исполнение находящейся в памяти машины программы. Процессор является основным вычислительным узлом ПК в задачу которого входят исполнение находящейся в памяти программы. сам по себе процессор и остальные элементы контроллеры памяти интерфейсы шины КЭШ память...