Процедуры на Free Pascal

Я относительно новичок в Pascal, и, хотя у меня есть хорошее понимание языка, все еще есть некоторые вещи, которые я не могу понять, как реализовать. Я столкнулся с этой проблемой, и после нескольких часов самостоятельных попыток поиска подобных случаев в Интернете я ничего не нашел. Я надеюсь, что этот вопрос справедлив, потому что, честно говоря, я не знаю, как это понять.

Вот в чем дело.

У меня есть приложение, которое динамически создает текстовые поля (в данном случае TextEdits) и добавляет их на панель для отображения. Дело в том, что мне нужно выполнить некоторые процедуры для вновь созданных элементов. Я добавил новую процедуру в свое приложение (это только для пояснения):

procedure Demo_Procedure(i: integer, a: String);

Затем я приступил к «разработке» своей процедуры под частью «реализации» формы.

procedure Demo_Procedure(i: integer, a: String);
begin
      ShowMessage(a, '  ' ,i);
end;

Теперь для моих динамически созданных элементов я пытаюсь установить событие «OnKeyDow» для запуска моей новой процедуры (это то, чего я не знаю, а- возможно ли это сделать, или б- как это сделать)

NewlyButton.OnClick:= Demo_Procedure(5, 'Hi');

Я получаю разные ошибки в зависимости от того, как я вызываю свою процедуру. Например:

Если я сделаю это так: Demo_Procedures(5, 'Привет'), он скажет:

Ошибка: несовместимые типы: получен "нетипизированный" ожидаемый "процедурный тип переменной процедуры (TObject, var Word, TShiftState) объекта; Регистрация>"

Теперь, исследуя вокруг, я обнаружил, что некоторые люди, которые помещают «@» перед вызовом метода, единственная разница в том, что на этот раз вместо того, чтобы сказать «нетипизированный», он говорит, что он получил «тип процедуры переменной процедуры (AnsiString ,LongInt) объекта" и что он ожидал того же, что и раньше (procedure(TObject,var> Word,Tshift...etc)

Может кто-нибудь помочь мне здесь? Я действительно потерян, поэтому любая помощь будет принята с благодарностью. Заранее спасибо :)


person Oscar Valdez Esquea    schedule 03.09.2014    source источник
comment
Вы можете назначить только «метод», процедуру «объекта». См. методы.   -  person Sertac Akyuz    schedule 04.09.2014
comment
В Object Pascal нет встроенной языковой конструкции, которая позволяла бы просто создавать lambda функции, которые, в свою очередь, могли бы использоваться как граждане 1-го класса вместе с другими ... of object функциями. Вероятно, вы пытаетесь понять шаблон команды GoF.   -  person xmojmr    schedule 04.09.2014


Ответы (1)


В вашем коде есть ошибки:

procedure Demo_Procedure(i: integer, a: String); // Wrong
procedure Demo_Procedure(i: integer; a: String); // Right, use semicolon as parameters delimiter

ShowMessage(a, '  ' ,i); // Wrong, ShowMessage takes only one string parameter
ShowMessage(Format('%s  %d', [a, i])); // Right, %s means string value and %d means decimal value, see help about Format function

События — это процедурные переменные, поэтому они имеют свои типы. Например, событие OnKeyDown имеет тип

TKeyEvent = procedure(Sender: TObject; var Key: Word; Shift: TShiftState) of Object;

где of Object означает, что ваш обработчик событий должен быть методом класса. Таким образом, вы не можете присвоить событию какую-либо процедуру, а только метод класса с параметрами, указанными в объявлении типа.

Вот простой код:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, Forms, Controls, Dialogs, StdCtrls;

type

    { TForm1 }

    TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    private
    public
        { public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
    e: TEdit;
begin
    e := TEdit.Create(Self); // Create new TEdit control
    e.Parent := Self; // Place control onto the form 
    e.Left := 10; // Set control coordinates
    e.Top := 10;
    e.OnKeyDown := @EditKeyDown; // Assign event handler
end;

procedure TForm1.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
    ShowMessage(Format('Key code is %d', [Key]));
end;

end.
person Abelisto    schedule 03.09.2014
comment
Спасибо за помощь! Итак, нет способа выполнить процедуру с моими собственными параметрами для событий элемента управления, таких как OnKeyDown или OnClick? Извините, если я кажусь глупым, просто новичок в Паскале:/ - person Oscar Valdez Esquea; 04.09.2014
comment
@OscarValdezEsquea Просто замените ShowMessage(Format('Key code is %d', [Key])); вызовом процедуры. Demo_Procedure(5, 'Hi'); в вашем примере - person Abelisto; 04.09.2014