2015-02-01 5 views
1

Учитывая TForm с TListBox на нем, следующие виды работ:Как передать вложенную процедуру метода в качестве параметра?

procedure TForm1.FormCreate(Sender: TObject); 
    procedure _WorkOnListBox; 
    begin 
    ListBox.Items.Append('Test'); 
    end; 
begin 
    _WorkOnListBox; 
end; 

Как делает следующее:

procedure TForm1.DoWithoutListBoxEvents(AProc: TProc); 
begin 
    ListBox.Items.BeginUpdate; 
    try 
    AProc; 
    finally 
    ListBox.Items.EndUpdate; 
    end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    DoWithoutListBoxEvents(procedure 
    begin 
    LayersListBox.Items.Append('Test'); 
    end); 
end; 

Но следующий не будет:

procedure TForm1.FormCreate(Sender: TObject); 
    procedure _WorkOnListBox; 
    begin 
    ListBox.Items.Append('Test'); 
    end; 
begin 
    DoWithoutListBoxEvents(_WorkOnListBox); 
end; 

я получаю E2555 Cannot capture symbol '_WorkOnListBox'. Зачем? Есть ли способ заставить DoWithoutListBoxEvents работать без использования анонимной процедуры? Хотя я думаю, что он выглядит элегантно, я стараюсь оставаться совместимым с FPC.

+0

@KromStern FreePascal совместимость –

+0

Спасибо за разъяснение. Добавлено тег для вас :-) – Kromster

ответ

5

DoWithoutEvents() принимает TProc в качестве входных данных:

type 
    TProc = procedure; 

только процедура автономных внеклассового и анонимной процедура может быть назначена TProc. _WorkOnForm не является ни тем, а вместо этого является локальной процедурой . Локальная процедура имеет специальную обработку компилятора, которая связывает ее с фреймом стека его родителя. Таким образом, _WorkOnForm несовместим с TProc.

+1

Есть ли какой-нибудь тип, который я могу использовать? –

+0

Не для местной процедуры, нет. Небезопасно вызывать локальную процедуру опосредованно (звонок не будет правильно настроен на сайте вызова), поэтому даже не пытайтесь это сделать. Локальные процедуры должны вызываться напрямую, каким образом компилятор видит это, чтобы он правильно настраивал вызов. Это по той же причине делает опасным использование локальной процедуры в качестве обратного вызова API (настройка плохого вызова). Только не делай этого. –