Так как проект самой библиотеки POISKLIB остается без изменений, обсудим только приложение Poisk, импортирующее подпрограмы RandomData и CalcMax, экспортируемые этой библиотекой.
В связи с тем, что способ подключения изменился, модуль UnPoiskIntface стал почти не нужен (используется только описание типов TPointFloat и TCoord). Описания TPointFloat и TCoord перенес в интерфейсную часть модуля unPokaz, а модуль UnPoiskIntface удаляю из проекта (меню Делфи | Project | Remove from Project). Затем файл можно удалить из папки. Явное подключение библиотеки производится с использованием функций WinAPI LoadLibrary (загрузить библиотеку), GetProcAddress (получить адрес процедуры) и FreeLibrary (отключить библиотеку). Описан и используется класс исключений ELoadDLL - для реагирование на ошибку (библиотека не подключается - например, не найден файл POISKLIB.DLL)
Запуск каждой подпрограммы состоит из таких элементов:
unit unMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Menus, unPokaz;
type
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
Vvod: TMenuItem;
Random: TMenuItem;
Solve: TMenuItem;
Quit: TMenuItem;
Pokaz: TMenuItem;
Label1: TLabel;
edCount: TEdit;
Label2: TLabel;
edminX: TEdit;
Label3: TLabel;
edmaxX: TEdit;
Label4: TLabel;
edminY: TEdit;
Label5: TLabel;
edmaxY: TEdit;
btnNew: TMenuItem;
procedure RandomClick(Sender: TObject);
procedure QuitClick(Sender: TObject);
procedure PokazClick(Sender: TObject);
procedure SolveClick(Sender: TObject);
procedure btnNewClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TRandomData = procedure(NumPoints: integer; MinX,MaxX,MinY,MaxY: double;
var Coord: TCoord); StdCall; //Создаем тип процедуры
TCalcMax = function (NumPoints: integer; MinX,MaxX,MinY,MaxY: double;
var Coord: TCoord; var N1,N2: integer {номера заданных точек}):word; StdCall;
ELoadDLL = class (Exception);
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
var
NPoints, NN1, NN2: integer;
MinX1,MaxX1,MinY1,MaxY1: double;
Coord1: TCoord;
Buf: word;
procedure TfrmMain.RandomClick(Sender: TObject);
var LibHnd: THandle;
RandomData: TRandomData;
begin
NPoints:= StrToInt(edCount.Text);
MinX1:= StrToFloat(edminX.Text);
MaxX1:= StrToFloat(edmaxX.Text);
MinY1:= StrToFloat(edminY.Text);
MaxY1:= StrToFloat(edmaxY.Text);
if MaxX1 <= MinX1 then
begin
showmessage('MaxX > MinX !');
exit;
end;
if MaxY1 <= MinY1 then
begin
showmessage('MaxY > MinY !');
exit;
end;
SetLength(Coord1, NPoints);
Randomize;
{ *********** подключение процедуры RandomData из POISKLIB.DLL ************ }
LibHnd:= LoadLibrary('POISKLIB.DLL');
try
if LibHnd = 0 then
raise ELoadDLL.Create('Не удалось загрузить POISKLIB.DLL');
@RandomData:= GetProcAddress(LibHnd,'RandomData');
if not (@RandomData = nil) then
begin
RandomData(NPoints,MinX1,MaxX1,MinY1,MaxY1,Coord1);
Solve.Enabled:= true;
edCount.Enabled:= false;
edminX.Enabled:= false;
edmaxX.Enabled:= false;
edminY.Enabled:= false;
edmaxY.Enabled:= false;
end
else RaiseLastWin32Error;
finally
FreeLibrary(LibHnd);
end;
{ ************ ************************* }
end;
procedure TfrmMain.QuitClick(Sender: TObject);
begin
Application.Terminate;
end;
procedure TfrmMain.PokazClick(Sender: TObject);
begin
ShowGraphPoints(NPoints,MinX1,MaxX1,MinY1,MaxY1,Coord1,0,0);
end;
procedure TfrmMain.SolveClick(Sender: TObject);
var LibHnd: THandle;
CalcMax: TCalcMax;
begin
{ *********** подключение функции CalcMax из POISKLIB.DLL ************ }
LibHnd:= LoadLibrary('POISKLIB.DLL');
try
if LibHnd = 0 then
raise ELoadDLL.Create('Не удалось загрузить POISKLIB.DLL');
@CalcMax:= GetProcAddress(LibHnd,'CalcMax');
if not (@CalcMax = nil) then
begin Buf:= CalcMax(NPoints,MinX1,MaxX1,MinY1,MaxY1,Coord1,NN1,NN2);
ShowGraphPoints(NPoints,MinX1,MaxX1,MinY1,MaxY1,Coord1,NN1,NN2);
end
else RaiseLastWin32Error;
finally
FreeLibrary(LibHnd);
end;
end;
procedure TfrmMain.btnNewClick(Sender: TObject);
begin
edCount.Enabled:= true;
edminX.Enabled:= true;
edmaxX.Enabled:= true;
edminY.Enabled:= true;
edmaxY.Enabled:= true;
Coord1:= nil;
end;
end.
-----------------------
unit unPokaz;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmPokaz = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
TPointFloat = record
X,Y: single;
end;
TCoord = array of TPointFloat;
var
frmPokaz: TfrmPokaz;
procedure ShowGraphPoints(NumPoints: integer; MinX,MaxX,MinY,MaxY: double;
var Coord: TCoord; N1,N2: integer);
implementation
{$R *.dfm}
procedure ShowGraphPoints(NumPoints: integer; MinX,MaxX,MinY,MaxY: double;
var Coord: TCoord; N1,N2: integer);
var ii,XX,YY: integer;
ax,bx,ay,by: double;
{ коэффициенты линейного преобразования реальных координат
в экранные: Хэкр := ax*Хреал + bx; такие, что
Хэкр(Xmin) = 0; Хэкр(Xmax) = ширина формы.
Yэкр := ay*Yреал + by;
Yэкр(Ymin) = высота формы; Yэкр(Ymax) = 0.
a,b - определяются из решения СЛАУ, записанных выше
}
begin
// showmessage('Показ точек - график');
ax:= frmPokaz.ClientWidth/(MaxX-MinX);
bx:= ax*MinX;
ay:= frmPokaz.ClientHeight/(MinY - MaxY);
by:= -ay*MaxY;
with frmPOkaz do
begin
Canvas.Pen.Width:=2;
Canvas.Pen.Color:= clGreen;
Color:= clBlack;
Canvas.FillRect(ClientRect);
Show;
for ii:= 0 to NumPoints - 1 do
begin
XX:= Round(ax*Coord[ii].X + bx);
YY:= Round(ay*Coord[ii].Y + by);
Canvas.Pixels[XX,YY ]:= RGB(200,200,200);
Canvas.Pixels[XX+1,YY ]:= RGB(200,200,0);
Canvas.Pixels[XX+1,YY+1 ]:= RGB(0,200,200);
Canvas.Pixels[XX,YY+1 ]:= RGB(200,0,200);
end;
if N1<>N2 then
begin
XX:= Round(ax*Coord[N1].X + bx);
YY:= Round(ay*Coord[N1].Y + by);
Canvas.Ellipse(XX-5,YY-5,XX+5,YY+5);
XX:= Round(ax*Coord[N2].X + bx);
YY:= Round(ay*Coord[N2].Y + by);
Canvas.Ellipse(XX-5,YY-5,XX+5,YY+5);
end;
end;
end;
end.
Скачать RAR-архив исходника + .exe(0.23 Mб)