KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

Валентин Озеров - Советы по Delphi. Версия 1.4.3 от 1.1.2001

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Валентин Озеров, "Советы по Delphi. Версия 1.4.3 от 1.1.2001" бесплатно, без регистрации.
Перейти на страницу:

end.

Вы можете сделать две вещи. Во-первых, если вы хотите использовать для передачи longint, напишите следующий код:

i := longint(@foo)

Другая вещь, которую вы можете сделать — исключить работу с longint и вызывать функцию dll следующим образом:

DLLfunction(@foo);

Имейте в виду, что если вы собираетесь вызывать foo из DLL, то необходимо предусмотреть вопросы совместимости, для получения дополнительной информации почитайте описание функции MakeProcInstance.

Проблема передачи записи

Delphi 1

Может это не то, что вы ищете, но идея такая:

Определите базовый класс с именем, скажем, allrecs:

tAllrecs = class

 function getVal(field: integer): string; virtual;

end;

Затем создаем классы для каждой записи:

recA = class(tAllrecs)

 this: Integer;

 that: String;

 the_other: Integer;

 function getVal(field: integer): string; virtual;

end;

Затем для каждой функции класса определите возвращаемый результат:

function recA.getVal(field: integer); string;

begin

 case field of

 1: getVal := intToStr(this);

 2: getVal := that;

 3: getVal := intToStr(the_other);

 end;

end;

Затем вы можете определить

function myFunc(rec: tAllrecs; field: integer);

begin

label2.caption := allrecs.getVal(field);

end;

затем вы можете вызвать myFunc с любым классом, производным от tAllrecs, например:

myFunc(recA, 2);

myFunc(recB, 29);

(getVal предпочтительно должна быть процедурой (а не функцией) с тремя var-параметрами, возвращающими имя, тип и значение.)

Все это работает, т.к. данный пример я взял из моего рабочего проекта.

[Sid Gudes, [email protected]]

Если вы хотите за один раз передавать целую запись, установите на входе ваших функций/процедур тип 'array of const' (убедитесь в правильном приведенни типов). Это идентично 'array of TVarRec'. Для получения дополнительной информации о системных константах, определяемых для TVarRec, смотри электронную справку по Delphi.

Указатели

Указатель на функцию I

Delphi 1

Это то, что я нашел при создании простой машины состояний:

Ниже приведен простой пример для Borland Delphi, использующий указатели функций для управления программным потоком. Просто создайте простую форму с единственной кнопкой и скопируйте код из Unit1 во вновь созданный модуль. Добавьте к проекту Unit2 и скомпилируйте проект. Дайте мне знать, если у вас возникнут какие-либо проблемы.

interface


uses

 SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,Forms, Dialogs, StdCtrls;

type

 TForm1 = class(TForm)

  Button1: TButton;

  procedure Button1Click(Sender: TObject);

 private { Private declarations }

 public { Public declarations }

 end;


var

 Form1: TForm1;

 CurrProc : LongInt;

 MyVal : LongInt;


implementation


uses Unit2;


{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);

var

 NewProc : LongInt;

 MyString : string;

begin

 CurrProc := 2; { начальная точка в таблице методов }

 MyVal := 0; { вспомогательная переменная }

 NewProc := 0; { возвращаемое значение для следующего индекса в таблице методов }

 while CurrProc < 6 do begin

{ выполняем текущий индекс в таблице методов и получаем следующую процедуру }

  NewProc := ProcTable[CurrProc](MyVal);

  { просто показываем значения NewProc и CurrProc }

  FmtStr(MyString, 'NewProc [%d] CurrProc [%d]', [NewProc, CurrProc]);

  MessageDlg(MyString, mtInformation, [mbOK], 0);

  { присваиваем текущую процедуру возвращаемой процедуре }

  CurrProc := NewProc;

 end;

end;


end.


{ Это простой пример, определяющий массив указателей на функции }


interface


type

 { определяем Procs как функцию }

 Procs = function(var ProcNum : LongInt): LongInt;


var

 { объявляем массив указателей на функции }

 ProcTable : Array [1..5] of Procs;

 { определения интерфейсов функций }


function Proc1(var MyVal : LongInt) : LongInt; far;

function Proc2(var MyVal : LongInt) : LongInt; far;

function Proc3(var MyVal : LongInt) : LongInt; far;

function Proc4(var MyVal : LongInt) : LongInt; far;

function Proc5(var MyVal : LongInt) : LongInt; far;


implementation


uses Dialogs;


function Proc1(var MyVal : LongInt) : LongInt;

begin

 MessageDlg('Процедура 1', mtInformation, [mbOK], 0);

 Proc1 := 6;

end;


function Proc2(var MyVal : LongInt) : LongInt;

begin

 MessageDlg('Процедура 2', mtInformation, [mbOK], 0);

 Proc2 := 3;

end;


function Proc3(var MyVal : LongInt) : LongInt;

begin

 MessageDlg('Процедура 3', mtInformation, [mbOK], 0);

 Proc3 := 4;

end;


function Proc4(var MyVal : LongInt) : LongInt;

begin

 MessageDlg('Процедура 4', mtInformation, [mbOK], 0);

 Proc4 := 5;

end;


function Proc5(var MyVal : LongInt) : LongInt;

begin

 MessageDlg('Процедура 5', mtInformation, [mbOK], 0);

 Proc5 := 1;

end;


initialization

 { инициализируем содержание массива указателей на функции }

 @ProcTable[1] := @Proc1;

 @ProcTable[2] := @Proc2;

 @ProcTable[3] := @Proc3;

 @ProcTable[4] := @Proc4;

 @ProcTable[5] := @Proc5;

end.

Я думаю это можно сделать приблизительно так: объявите в каждой форме процедуры, обрабатывающие нажатие кнопки, типа процедуры CutButtonPressed(Sender:TObject) of Object; затем просто назначьте события кнопок OnClick этим процедурам при наступлении событий форм OnActivate. Этот способ соответствует концепции ОО-программирования, но если вам не нравится это, то вы все еще можете воспользоваться указателями функций, которая предоставляет Delphi.

Объявите базовый класс формы с объявлениями абстрактных функций для каждой функции, которую вы хотите вызывать из вашего toolbar. Затем наследуйте каждую вашу форму от базового класса формы и создайте определения этих функций.

Пример: (Здесь может встретиться пара синтаксических ошибок — я не компилил это)

type

 TBaseForm = class(TForm)

 public

  procedure Method1; virtual; abstract;

 end;


type

 TDerivedForm1= class(TBaseForm)

 public

  procedure Method1; override;

 end;


 TDerivedForm2= class(TBaseForm)

 public

  procedure Method1; override;

 end;


procedure TDerivedForm1.Method1;

begin

 …

end;


procedure TDerivedForm2.Method1;

begin

 …

end;


{Для вызова функции из вашего toolbar, получите активную в настоящий момент форму и вызовите Method1}

procedure OnButtonClick;

var

 AForm: TBaseForm;

begin

 AForm := ActiveForm as TBaseForm;

 AForm.Method1;

end

Указатель на функцию II

Delphi 1

Что лично я использую, чтобы вызвать какую-то функцию из DLL:

1. Объявите тип:

type TYourDLLFunc = function(Parm1: TParm1; Parm2: TParm2): TParm3;

2. Объявите переменную этого типа:

var YourDllFunc: TYourDLLFunc;

3. Получаем дескриптор DLL:

DLLHandle := LoadLibrary('YourDLL.DLL');

Получаем адрес функции:

@YourDLLFunc := GetProcAddress(DLLHandle, 'YourDLLFuncName');

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*