![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как вызвать событие [D7]
rds © (2005-09-20 21:07:00)В своем компоненте Определяю событие, как
type TEvent=procedure(Sender:TObject)
....
private
fOnEvent: TEvent;
....
published
property OnEvent: TEvent read fOnEvent write fOnEvent
В процессе работы методов компонента возникает ситуация, когда должно возникнуть это событие. Каким образом это осуществляется. Т.е. я понимаю, что должен стоять соответствующий вызов, но может кто-то приведет краткий пример?
Quattro (2005-09-27 18:06:00) [1]ок..спасибо за объяснения и за терпение..=)...
umbra (2005-09-26 13:33:00) [2]В метод-обработчик сообщения не надо ничего передавать. Его не надо даже вызывать самому! Этот метод вызывается автоматически каждый раз, когда контрол получает соответствующее сообщение от винды. Как параметр ей АВТОМАТИЧЕСКИ передается полученное сообщение. Приложение должно на основании информации в сообщении что-то решить. Кроме того, при клике надо обрабатывать 2 сообщения - нажатие левой кнопки мыши и отпускание. И только если для контрола произошли оба - тогда вызывать обработчик события. Честно говоря, я не специалист в этом, и то, что я написал - только мое понимание. Примеры лучше всего смотреть в модуле Controls - объявление и реализацию класса TControl и его наследников. Там есть и TWMLButtonDown.
Quattro (2005-09-24 00:12:00) [3]извиняюсь,если надоел глупыми вопросами....в данном примере как мне вызвать обработчик сообщениея??
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-23 10:44:00) [4]Ты создал окно. Оно получает от винды ВСЕ сообщения от мыши или клавиатуры. Если ты клацнешь мышой где угодно на экране, твое окно получит сообщение 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-23 00:48:00) [5]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;
Reindeer Moss Eater (2005-09-22 23:09:00) [6]Это не оконная процедура.
Это метод класса.
Quattro (2005-09-22 23:04:00) [7]
> Сообщения посылаются созданному тобой окну
это вот это!так?
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:00:00) [8]Сообщения посылаются созданному тобой окну.
Для этого ты и создал его.
А дальше их надо обрабатывать.
В оконной процедуре.
Quattro (2005-09-22 22:54:00) [9]эээ..так кто же должен вызывать эти сообщения то???
Reindeer Moss Eater (2005-09-22 22:44:00) [10]А с какого щасться форма должна заботиться о сообщениях твоему баттону?
Тем более, что у него есть окно.
Ты его (окно) зачем вообще создавал?
Что бы смотреть сквозь него на унылый осенний пейзаж?
Quattro (2005-09-22 22:41:00) [11]Reindeer Moss Eater ©
Форма?
Reindeer Moss Eater (2005-09-22 22:39:00) [12]И я написал 1000 обработчиков.
И что?
Кто их вызывает (должен вызывать) по твоему?
Зеленые человечки?
Quattro (2005-09-22 22:18:00) [13]
> А я щас отнаследуюсь от 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 20:53:00) [14]2)Я сам в конструкторе класса TMyButton создаю окно функцие CreateWindow
А я щас отнаследуюсь от TObject, создам такое же окно, а про себя подумаю, что мой новый компонент - это супер пупер навороченный тулбар из аутлука и еще круче в 10 раз.
И напишу кучу процедур реагирующих на все возможные сообщения windows.
И чё?
По твоей логике должен таки получиться супер-пупер навороченный тулбар из аутлука и еще круче в 10 раз.
Quattro (2005-09-22 20:52:00) [15]umbra ©
??????? как это так??...тогда почему этот же скопированный код прекрасно отображает кнопку???...
З.Ы. Начинаю чувствовать себя идиотом...
umbra (2005-09-22 19:33:00) [16]вот я скопировал твой код, вставил в новый проект, запустил - и не вижу на форме ни одной кнопки.
Quattro (2005-09-22 18:56:00) [17]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 18:48:00) [18]
> созданную мной кнопку на форме видно
Если код из [12]остается в силе, то там на форме есть TButton и вот его-то и видно на форме. Если была бы и TMyButton, то на форме было-бы две кнопки.
Quattro (2005-09-22 17:56:00) [19]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;
Reindeer Moss Eater (2005-09-22 15:37:00) [20]Откуда по твоему созданное окно должно узнать, что оно - твоя новая супер-кнопка и что у этой кнопки есть какое-то событие которое должно срабатывать при получении окном WM_LBUTTONDOWN?