Форум: "Компоненты";
Текущий архив: 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.
← →
Quattro © (2005-09-24 00:12) [41]извиняюсь,если надоел глупыми вопросами....в данном примере как мне вызвать обработчик сообщениея??
TMyButton = class(TControl)
private
procedure WndProc(var Message:TMessage);override;
procedure WMLButtonClick(var Msg:TWMLButtonDown);message WM_LBUTTONDOWN;
public
end;
procedure TMyButton.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_LBUTTONDOWN then
But.WMLButtonClick()//Что здесь нужно передать в качестве параметра,имеющего тим TWMouse?;
inherited WndProc(Message);
end;
← →
umbra © (2005-09-26 13:33) [42]В метод-обработчик сообщения не надо ничего передавать. Его не надо даже вызывать самому! Этот метод вызывается автоматически каждый раз, когда контрол получает соответствующее сообщение от винды. Как параметр ей АВТОМАТИЧЕСКИ передается полученное сообщение. Приложение должно на основании информации в сообщении что-то решить. Кроме того, при клике надо обрабатывать 2 сообщения - нажатие левой кнопки мыши и отпускание. И только если для контрола произошли оба - тогда вызывать обработчик события. Честно говоря, я не специалист в этом, и то, что я написал - только мое понимание. Примеры лучше всего смотреть в модуле Controls - объявление и реализацию класса TControl и его наследников. Там есть и TWMLButtonDown.
← →
Quattro © (2005-09-27 18:06) [43]ок..спасибо за объяснения и за терпение..=)...
Страницы: 1 2 вся ветка
Форум: "Компоненты";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.045 c