Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

не работает динамически созданный обработчик


Страницы:   1 2 3

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?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо