Так как проект самой библиотеки 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б)