скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

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



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

Ниже приведен простой пример для 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;






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook