Форум: "Компоненты";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
ВнизКак вызвать событие Найти похожие ветки
← →
rds © (2005-09-20 21:07) [0]В своем компоненте Определяю событие, как
type TEvent=procedure(Sender:TObject)
....
private
fOnEvent: TEvent;
....
published
property OnEvent: TEvent read fOnEvent write fOnEvent
В процессе работы методов компонента возникает ситуация, когда должно возникнуть это событие. Каким образом это осуществляется. Т.е. я понимаю, что должен стоять соответствующий вызов, но может кто-то приведет краткий пример?
← →
Sphinx © (2005-09-20 21:30) [1]Может ошибусь, но кажется так
if Assigned(fOnEvent) then fOnEvent;
← →
RDS © (2005-09-20 21:59) [2]спасибо, сечас попробую
← →
jack128 © (2005-09-20 22:02) [3]rds © (20.09.05 21:07)
TEvent=procedure(Sender:TObject)
обычно события компонентов отпереляют как методы, а не процедуры: TEvent = procedure (Sender: Tobject) of object;
правда уже существует такой стандартный тип - TNotifyEvent;
вызов обычно делается так:type
TEsComponent = class(TComponent)
private
fEvent: TNotifyEvent; // обычно в название поля не в ключают приставку On
protected
procedure DoEvent; virtual; // обычно в название метода диспетчеризации включают приставку Do и этот метод делают виртуальным или динамическим
published
property OnEvent: TNotifyEvent read fOnEvent write fOnEvent;
end;
{ TEsComponent }
procedure TEsComponent.DoEvent;
begin
if Assigned(fEvent) tehn
fEvent(Self);
end;
← →
Юрий Зотов © (2005-09-20 22:37) [4]> jack128 © (20.09.05 22:02) [3]
> этот метод делают виртуальным или динамическим
Обычно динамическим, т.к. методы диспетчеризации перекрываются нечасто, а в таком случае динамический метод дает тот же расход памяти, что и виртуальный, но работу ускоряет.
← →
RDS © (2005-09-20 23:37) [5]jack128 © (20.09.05 22:02) [3]
Конечно же TEvent = procedure (Sender: Tobject) of object; - моя вина, не правильно написал.
← →
Leonid Troyanovsky © (2005-09-21 11:53) [6]
> Юрий Зотов © (20.09.05 22:37) [4]
> Обычно динамическим, т.к. методы диспетчеризации перекрываются
> нечасто, а в таком случае динамический метод дает тот же
> расход памяти, что и виртуальный, но работу ускоряет.
Virtual methods optimize for speed, while dynamic methods optimize for code size.
..
Dynamic methods are useful when a base class declares many overridable
methods which are inherited by many descendant classes in an application,
but only occasionally overridden.
Т.е., не ускоряет, а уменьшает размер (вкупе с наследниками).
--
Regards, LVT.
← →
Quattro © (2005-09-21 17:04) [7]Прошу меня извинить за то что влезаю в разговор,но не могли бы вы подсказать как назначить обработчик данному событию Event:TNotifyEvent ???
← →
Reindeer Moss Eater © (2005-09-21 17:27) [8]Оператором присваивания.
:=
Слышал про такой?
← →
Quattro © (2005-09-21 17:38) [9]
> Оператором присваивания.
> :=
>
> Слышал про такой?
угу...что такое когда то слышал=)......
TMyButton = class(TControl)
private
FOnClick:TNotifyEvent;
procedure DoMouseDown;
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
protected
procedure qwe(Sender: TObject);
public
Constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
property OnClick:TNotifyEvent read FOnClick write FOnClick;
end;
затем пытаюсь назначить обработчик
procedure TForm1.FormCreate(Sender: TObject);
var
But:TMyButton;
begin
But:=TMyButton.Create(nil);
But.Parent:=Self;
But.Show;
But.Top:=10;
But.Left:=10;
But.OnClick:=qwe;
end;
да вот пишет что qwe-ндекларед идентифир ......не подскажите,в чём проблема?
← →
Reindeer Moss Eater © (2005-09-21 17:39) [10]Проблема в том, что идентификатор qwe не объявлен.
← →
Reindeer Moss Eater © (2005-09-21 17:42) [11]Точнее объявлен не там где его ищет компилятор.
But.OnClick:=But.qwe;
← →
Quattro © (2005-09-22 03:05) [12]ёлки зелёные..почему же не србатывает ShowMessage?
type
TMyButton = class(TControl)
private
FOnClick:TNotifyEvent;
procedure DoMouseDown;
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
protected
public
procedure DoShowMes(Sender: TObject);
Constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
property OnClick:TNotifyEvent read FOnClick write FOnClick;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyButton }
constructor TMyButton.Create(AOwner: TComponent);
begin
inherited;
CreateWindow("BUTTON","QWERTY",WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON
,123,115,100,28,Form1.Handle,0,hInstance,nil);
end;
destructor TMyButton.Destroy;
begin
inherited;
end;
procedure TMyButton.DoMouseDown;
begin
if Assigned(FOnClick) then FOnClick(Self);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
But:TMyButton;
begin
But:=TMyButton.Create(nil);
But.Parent:=Self;
But.Show;
But.Top:=10;
But.Left:=10;
But.OnClick:=But.DoShowMes;
end;
procedure TMyButton.WMLButtonClick(var Msg: TWMLButtonDown);
begin
DoMouseDown;
end;
procedure TMyButton.DoShowMes;
begin
ShowMessage("qweqwe");
end;
← →
Reindeer Moss Eater © (2005-09-22 09:13) [13]Что бы оно срабатывало, надо как минимум обрабатывать нужные сообщения посылаемые твоему окну.
Где твоя оконная процедура?
← →
Quattro © (2005-09-22 12:25) [14]хм...обработки сообщения WMLBUTTONDOWN классом TMyButton не достаточно??
← →
Reindeer Moss Eater © (2005-09-22 12:42) [15]И как зовут того дядю, который вызовет твой WMLButtonClick?
← →
icWasya © (2005-09-22 12:46) [16]IMHO - что бы работали вот такие процедуры
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
компонент должен быть наследником TWinControl
← →
Quattro © (2005-09-22 12:57) [17]Reindeer Moss Eater ©
Прошу меня извинить,если я задаю глупые вопросы.....но что значит как зовут дядю??...я нажму на контрол и обработчик сообщени нажатия должен ,собственно,обработать сообщение....нет?
← →
Quattro © (2005-09-22 12:58) [18]icWasya ©
??..а какая разница??..
← →
Reindeer Moss Eater © (2005-09-22 13:03) [19]я нажму на контрол и обработчик сообщени нажатия должен ,собственно,обработать сообщение....нет?
Канечно нет. Иначе бы ты не спрашивал почему не генерируется событие.
← →
Quattro © (2005-09-22 14:01) [20]Reindeer Moss Eater ©
Логично=)..не поспоришь=)...хм есть предположение что нужен обработчик сообщения WMLBUTTONDOWN для формы....
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
{ Private declarations }
public
{ Public declarations }
end;
procedure TMyButton.WMLButtonClick(var Msg: TWMLButtonDown);
begin
DoMouseDown;
end;
← →
umbra © (2005-09-22 14:03) [21]
> Quattro ©
> ёлки зелёные..почему же не србатывает ShowMessage?
Потому, что у тебя на форме не ТMyButton - наследник TControl, а TButton - наследнк TWinControl. А ТMyButton на форме вообще не видно. Отсюда -
> TMyButton.DoShowMes
НИКОГДА не вызывается
← →
Quattro © (2005-09-22 15:28) [22]umbra ©
вообще тогда ничего не понимаю......я же в конструктора TMyButton сам создаю кнопку функцией CreateWindow!!....
← →
Reindeer Moss Eater © (2005-09-22 15:32) [23]И думаешь что ты после этого молодец?
А где обработка сообщений этому окну?
← →
Reindeer Moss Eater © (2005-09-22 15:37) [24]Откуда по твоему созданное окно должно узнать, что оно - твоя новая супер-кнопка и что у этой кнопки есть какое-то событие которое должно срабатывать при получении окном WM_LBUTTONDOWN?
← →
Quattro © (2005-09-22 17:56) [25]Reindeer Moss Eater ©
так..давай по порядку....
1) Извини,если я чего то не понимаю и раздражаю тебя ,на твой взгляд , глупыми вопросами
2)Я сам в конструкторе класса TMyButton создаю окно функцие CreateWindow
3)Вновь созданную мной кнопку на форме видно(она нажимается и всё такое)
> Откуда по твоему созданное окно должно узнать, что оно -
> твоя новая супер-кнопка и что у этой кнопки есть какое-
> то событие которое должно срабатывать при получении окном
> WM_LBUTTONDOWN?
как это откуда?я же указал обработчик сообщения WMLBUTTONCLICK!!TMyButton = class(TControl)
private
FOnClick:TNotifyEvent;
procedure DoMouseDown;
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
protected
public
procedure DoShowMes(Sender: TObject);
Constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
property OnClick:TNotifyEvent read FOnClick write FOnClick;
end;
← →
umbra © (2005-09-22 18:48) [26]
> созданную мной кнопку на форме видно
Если код из [12] остается в силе, то там на форме есть TButton и вот его-то и видно на форме. Если была бы и TMyButton, то на форме было-бы две кнопки.
← →
Quattro © (2005-09-22 18:56) [27]umbra ©
так я создаю кнопку только когда программа запущена....TButton случайно там оказалась...считай что её нет...просто я смотрел как она устроена и забыл вычеркнуть из кода......конечный вариант кода вот такойtype
TMyButton = class(TControl)
private
FOnClick:TNotifyEvent;
procedure DoMouseDown;
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
public
procedure DoShowMes(Sender: TObject);
Constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
property OnClick:TNotifyEvent read FOnClick write FOnClick;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TMyButton }
constructor TMyButton.Create(AOwner: TComponent);
begin
inherited;
CreateWindow("BUTTON","QWERTY",WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON
,123,115,100,28,Form1.Handle,0,hInstance,nil);
end;
destructor TMyButton.Destroy;
begin
inherited;
end;
procedure TMyButton.DoMouseDown;
begin
if Assigned(FOnClick) then FOnClick(Self);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
But:TMyButton;
begin
But:=TMyButton.Create(nil);
But.Parent:=Self;
But.Show;
But.Top:=10;
But.Left:=10;
But.OnClick:=But.DoShowMes;
end;
procedure TMyButton.WMLButtonClick(var Msg: TWMLButtonDown);
begin
DoMouseDown;
end;
procedure TMyButton.DoShowMes;
begin
ShowMessage("qweqwe");
end;
← →
umbra © (2005-09-22 19:33) [28]вот я скопировал твой код, вставил в новый проект, запустил - и не вижу на форме ни одной кнопки.
← →
Quattro © (2005-09-22 20:52) [29]umbra ©
??????? как это так??...тогда почему этот же скопированный код прекрасно отображает кнопку???...
З.Ы. Начинаю чувствовать себя идиотом...
← →
Reindeer Moss Eater © (2005-09-22 20:53) [30]2)Я сам в конструкторе класса TMyButton создаю окно функцие CreateWindow
А я щас отнаследуюсь от TObject, создам такое же окно, а про себя подумаю, что мой новый компонент - это супер пупер навороченный тулбар из аутлука и еще круче в 10 раз.
И напишу кучу процедур реагирующих на все возможные сообщения windows.
И чё?
По твоей логике должен таки получиться супер-пупер навороченный тулбар из аутлука и еще круче в 10 раз.
← →
Quattro © (2005-09-22 22:18) [31]
> А я щас отнаследуюсь от TObject, создам такое же окно, а
> про себя подумаю, что мой новый компонент - это супер пупер
> навороченный тулбар из аутлука и еще круче в 10 раз.
так ведь я написал для этого окна обработчик сообщения!!..или что я сделал??
Почему тогда этот код для формы прекрасно работает ?TForm1 = class(TForm)
private
{ Private declarations }
procedure WMLButtonDown(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
public
{ Public declarations }
end;
procedure TForm1.WMLButtonDown(var Msg: TWMLButtonDown);
begin
ShowMessage("qwqwe");
end;
← →
Reindeer Moss Eater © (2005-09-22 22:39) [32]И я написал 1000 обработчиков.
И что?
Кто их вызывает (должен вызывать) по твоему?
Зеленые человечки?
← →
Quattro © (2005-09-22 22:41) [33]Reindeer Moss Eater ©
Форма?
← →
Reindeer Moss Eater © (2005-09-22 22:44) [34]А с какого щасться форма должна заботиться о сообщениях твоему баттону?
Тем более, что у него есть окно.
Ты его (окно) зачем вообще создавал?
Что бы смотреть сквозь него на унылый осенний пейзаж?
← →
Quattro © (2005-09-22 22:54) [35]эээ..так кто же должен вызывать эти сообщения то???
← →
Reindeer Moss Eater © (2005-09-22 23:00) [36]Сообщения посылаются созданному тобой окну.
Для этого ты и создал его.
А дальше их надо обрабатывать.
В оконной процедуре.
← →
Quattro © (2005-09-22 23:04) [37]
> Сообщения посылаются созданному тобой окну
это вот это!так?
CreateWindow("BUTTON","QWERTY",WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON
,123,115,100,28,Form1.Handle,0,hInstance,nil);
> А дальше их надо обрабатывать.
> В оконной процедуре.
оконная процедура это вот это??
TMyButton = class(TControl)
private
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
protected
public
end;
← →
Reindeer Moss Eater © (2005-09-22 23:09) [38]Это не оконная процедура.
Это метод класса.
← →
Quattro © (2005-09-23 00:48) [39]Reindeer Moss Eater ©
аа!!!понял!..WndProc!!!TMyButton = class(TControl)
private
FOnClick:TNotifyEvent;
procedure DoMouseDown;
procedure WndProc(var Message:TMessage);override;
public
procedure DoShowMes(Sender: TObject);
Constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
property OnClick:TNotifyEvent read FOnClick write FOnClick;
end;
Только как указать что если сообщение WM_LBUTTONDOWN ,то вызывать обработчик этого сообщения??
procedure TMyButton.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_LBUTTONDOWN then
????? But.WMLButtonClick?????
inherited WndProc(Message);
end;
← →
umbra © (2005-09-23 10:44) [40]Ты создал окно. Оно получает от винды ВСЕ сообщения от мыши или клавиатуры. Если ты клацнешь мышой где угодно на экране, твое окно получит сообщение WM_LBUTTONDOWN, в котором указано где имеено на экране клацнули мышой. И тебе надо, как минимум, филтровать эти сообщения и обрабатывать только клики на твоем окне. Дальше. Тебе надо твое окно рисовать! Ты ведь наследуешь от TControl, а отрисовка окон реализована только в TCustomControl (наследнике TWinControl). Посему в твоей оконной процедуре должны обрабатываться сообщения об отрисовке окна и рисовать его. Иначе его никто не увидит. И т.д. Писать окно снуля - нелегкий труд. Чтобы его избежать и создана VCL.
В общем, наследуй не от TControl, а от TButton, или, в общем, от ближайшего класса, в котором есть похожая функциональность.
Насколько я помню, первоначально вопрос был о том, как присвоить обработчик событию. Ниже - рабочий пример. При запуске проги у Button2 нет обработчика OnClick. После нажатия на Button1 обработчик присваивается, после повторного опять убирается.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure Clicker(sender: TObject);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.Clicker(sender: TObject);
begin
Randomize;
Color := TColor(Random($FFFFFF));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(Button2.OnClick) then
Button2.OnClick := Clicker
else
Button2.OnClick := nil;
end;
end.
Страницы: 1 2 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.073 c