![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
не работает динамически созданный обработчик
vasek © (2005-11-23 23:48:00)для динамически созданной кнопки данный обработчик работает:
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure myClick(Sender: TObject);
end;
var
Form1: TForm1;
const
i : integer = 0;
implementation
{$R *.DFM}
procedure TForm1.myClick(Sender: TObject);
begin
with Sender as TButton do
Self.Caption := ClassName + ' ' + Name;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TButton.Create(self) do begin
Left := 20;
Top := 30 + i;
Width := 120;
Height := 40;
Name := 'ThisButton' + IntToStr(i);
Caption := 'There' + IntToStr(i);
OnClick := MyClick; { процедура, определенная где-то еще }
Parent := Form1;
end; {end with}
inc(i, 40);
end; {end button1.click}
end.
а так не хочет... :( :
program Project1;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,
Unit1 in 'Unit1.pas';
{$R *.res}
type
TButtonArray = array[1..4,1..4] of TButton;
var
MainForm: TForm;
Hnd, Hnd1: THandle;
Buttons : TButtonArray;
Panel1: TPanel;
procedure ButtonPressed(Sender: TObject);
var
B : TButton;
i1,j1: Integer;
begin
B := Sender as TButton;
begin
{code}
end;
end;
begin
MainForm:= TForm.CreateParented(Hnd);
Application.Initialize;
Application.CreateForm(TForm, MainForm);
Buttons[1,1]:= TButton.CreateParented(MainForm.Handle);
Buttons[1,1].Parent:= MainForm;
Buttons[1,1].OnClick:= ButtonPressed;
end;
почему ?
пишет следующее: incompatible types: 'method pointer and regular procedure'.
sniknik (2005-11-25 10:52:00) [41]Leonid Troyanovsky © (25.11.05 10:38) [19]
на первый взгляд решил что передается указатель на структуру.
был не прав. исправлюсь.
Leonid Troyanovsky (2005-11-25 10:38:00) [42]
> sniknik © (24.11.05 20:10) [13]
> Zeqfreed © (24.11.05 14:14) [9]
> а вот это хреновый пример, Method локальная переменная,
> тоже не проверял но думаю могут быть проблемы.
Никаких проблем, в поле копируется 8 байт.
--
Regards, LVT.
Leonid Troyanovsky (2005-11-25 10:32:00) [43]
> Плохиш © (25.11.05 02:20) [16]
> Потому что Click не является классовой функцией.
Если уж точней, то процедурой.
Однако, является методом класса (но не классовым методом ;)
Но, причина неудачи не этом, а в том, что список параметров разный.
Хотя, собс-но, такое назначение, в рассматриваемом случае,
категорически противопоказано.
--
Regards, LVT.
Leonid Troyanovsky (2005-11-25 10:27:00) [44]
> vasek © (25.11.05 00:32) [14]
> зарубку сделал... но а в случае когда массив кнопок:
> Buttons[i,j].OnClick:= TMyButton.Click;;
Это совсем не нужно.
А вот кнопки надо создавать уже нового класса: TMyButton.
--
Regards, LVT.
Плохиш (2005-11-25 02:20:00) [45]
> ... не срабатывает :(
>
> incompatible types 'parametr lists differ'
Потому что Click не является классовой функцией.
Германн (2005-11-25 01:57:00) [46]2 vasek ©
Может объяснишь простым языком - зачем нужен такой садомазохизм:
Объявление процедур, реализация процедур, создание компонет и т.п. в файле проекта, исходно для этого не предназначенного?
vasek (2005-11-25 00:32:00) [47]зарубку сделал... но а в случае когда массив кнопок:
type
TButtonArray = array[1..n,1..n] of TButton;
TMyButton = class(TButton)
public
procedure Click; override;
end;
procedure ButtonPressed;
var
B : TButton;
begin
B := Sender as TButton;
begin
end;
end;
procedure TMyButton.Click;
begin
inherited;
ButtonPressed;
end;
begin
MainForm:= TForm.CreateParented(Hnd);
Application.Initialize;
Application.CreateForm(TForm, MainForm);
for i:= 1 to n do
for j:= 1 to n do
begin
Buttons[i,j]:= TButton.CreateParented(MainForm.Handle);
Buttons[i,j].Parent:= MainForm;
Buttons[i,j].OnClick:= TMyButton.Click;;
end;
end;
Application.Run;
end.
... не срабатывает :(
incompatible types 'parametr lists differ'
sniknik (2005-11-24 20:10:00) [48]Zeqfreed © (24.11.05 14:14) [9]
а вот это хреновый пример, Method локальная переменная, тоже не проверял но думаю могут быть проблемы.
Leonid Troyanovsky (2005-11-24 15:30:00) [49]
> vasek © (23.11.05 23:48)
> для динамически созданной кнопки данный обработчик работает:
..
> а так не хочет... :( :
..
> почему ?
Потому, что для динамически создаваемых контрола нужно
не назначать обработчик OnClick, а перекрывать метод Click, т.е.
TMyButton = class(TButton);
public
procedure Click; override;
..
end;
procedure TMyButton.Click;
begin
inherited;
MyClick; { процедура, определенная где-то еще }
end;
Подобным же образом перекрываются и конструкторы и др., дабы
меньше писать кода для настроек по умолчанию и т.д.
Советую сделать памятную зарубку на носу.
--
Regards, LVT.
Zeqfreed (2005-11-24 14:25:00) [50]Zeqfreed © (24.11.05 14:14) [9]
> const ButtonLeft, ButtonTop : TPoint);
Читать какconst ButtonLeft, ButtonTop : Integer);
Плохиш (2005-11-24 14:18:00) [51]
> vasek © (23.11.05 23:48)
> procedure ButtonPressed(Sender: TObject) of object;
Zeqfreed (2005-11-24 14:14:00) [52]vasek © (24.11.05 13:31) [8]
procedure ClickEventHandler(Sender : TObject);
begin
if (Sender is TButton) then
ShowMessage(Format('Button with caption %s has just been clicked', [(Sender as TButton).Caption]));
end;
procedure AddButton(ParentForm : TForm; Handler : Pointer; const ButtonCaption : String; const ButtonLeft, ButtonTop : TPoint);
var
Method : TMethod;
begin
Method.Code := Handler;
Method.Data := nil;
with TButton.Create(nil) do begin
Caption := ButtonCaption;
Parent := ParentForm;
Left := ButtonLeft;
Top := ButtonTop;
OnClick := TNotifyEvent(Method);
end;
end;
procedure TMainForm.Button1Click(Sender : TObject);
begin
AddButton(Self, @ClickEventHandler, 'Button 1', 8, 8);
AddButton(Self, @ClickEventHandler, 'Button 2', 8, 32);
end;
Код не проверял, но вроде все должно работать.
> на тему полностью рабочего примера
Пример в [2] очень даже рабочий, если не считать опечатки в слове Method.
vasek (2005-11-24 13:31:00) [53]а куда переместить (onCreate MainForm), если не затруднит поподробнее..?
@YourEventHandler - это про кого?(это на тему полностью рабочего примера).
sniknik (2005-11-24 07:33:00) [54]и кстати,
> begin
> MainForm:= TForm.CreateParented(Hnd);
> Application.Initialize;
> Application.CreateForm(TForm, MainForm);
> Buttons[1,1]:= TButton.CreateParented(MainForm.Handle);
>
> Buttons[1,1].Parent:= MainForm;
> Buttons[1,1].OnClick:= ButtonPressed;
> end;
если перенести создание в правильное место (onCreate MainForm) "проблема" исчезнет так и не родившись...
sniknik (2005-11-24 07:29:00) [55]> и если уж совсем не затруднит рабочий(полурабочий :)) кусочек...
кусочек в Zeqfreed © (24.11.05 00:15) [2] полностью рабочий... (так, для справки)
ЮЮ (2005-11-24 04:28:00) [56]Сорри, не обратил внимание, что ButtonPressed описан в dpr. А не лучше его описать, как в [4], только в public секции, тогда
Buttons[1,1].OnClick:= MainForm.ButtonPressed;
ЮЮ (2005-11-24 04:20:00) [57]TForm1 = class(TForm)
...
private
ButtonPressed(Sender: TObject);
...
end;
procedure Form1.ButtonPressed(Sender: TObject);
vasek (2005-11-24 01:19:00) [58]Apllication.Run есть дальше...
....
Application.Run;
end.
...
все работает но не получается сделать динамически обработчик, без него все ок. если можно по подробнее, и если уж совсем не затруднит рабочий(полурабочий :)) кусочек...
Zeqfreed (2005-11-24 00:15:00) [59]vasek © (23.11.05 23:48)
А, увидел :)
Форматирование кода используй в следующий раз.
> пишет следующее: incompatible types: 'method pointer
> and regular procedure'.
Ну тут тебе же говорят, что требуется указать метод (процедуру-член класса), как и сделано у тебя в коде, что выше.
В общем-то можно использовать и регулярную процедуру, создав метод и назначив его в качестве обработчика, примерно так:
var
Method : TMethod;
begin
Method.Code := @YourEventHandler;
Mathod.Data := nil;
ButtonInstance.OnClick := TNotifyEvent(Method);
end;
Zeqfreed (2005-11-24 00:09:00) [60]vasek © (23.11.05 23:48)
Код компилируется?
ГдеApllication.Runв project.dpr?