Каким образом добавить собственное событие(Event) вызываемое объектом(формой).
Вроде оно описывается как property, но компилятор выдает ошибку:
INDEX, READ or WRITE clause expected, but ';' found
Делаю чтото вроде этого (по хелпу):
type
TMyEvent = procedure (Sender: TObject) of object; (можно исполз.
TNotifyEvent?)
TForm = class (TForm)
property OnSomething: TMyEvent;
end;
PS: А вообще это можно зделать?
С наилучшими пожеланиями All!
> Каким образом добавить собственное событие(Event) вызываемое
> объектом(формой).
> Вроде оно описывается как property, но компилятор выдает ошибку:
> INDEX, READ or WRITE clause expected, but ';' found
Есть очень хорошая книга: Рей Конопка. "Создание оригинальных компонент в
среде Delphi". Hо, к сожалению, она на русском не переиздавалась с 96 года.
(хотя, на английском, IMHO, в 2002 году).
Т.е., найти ее можно, наверное, только в библиотеке.
> PS: А вообще это можно зделать?
Вот слегка измененный пример Рея:
Предположим, что мы хотим научить наш компонент
реагировать на изменение состояния NumLock.
type
TNumLockEvent = procedure (Sender:TObject; AStatus: OnLock: Boolean) of
object;
TMyComponent = class(TComponent)
private
FNumLock: Boolean; {поле хранит статус NumLock}
..
FOnNumLock: TNumLockEvent;
protected
..
procedure NumLock; dynamic; {метод диспетчеризации}
published
..
property OnNumLock: TNumLockEvent read FOnNumLock
write FOnNumLock;
public
end;
..
procedure TMyComponent.NumLock;
begin
if Assigned( FOnNumLock) then
FOnNumLock(Self, FNumLock);
end;
Теперь осталось придумать, как обнаруживать измененение состояния.
Можно, например, сделать таймер и в его OnTimer написать:
procedure TMyComponent.Timer1Timer(Sender: TObject);
var
NewNumLock : Boolean;
begin
Timer.Enabled := False;
NewNumLock := GetKeyState(vk_NumLock) = 1;
if ( NewNumLock <> FNumLock ) then
begin
FNumLock := NewNumLock;
NumLock; {вот, собс-но}
end;
Timer.Enabled := True;
end;
--
С уважением, LVT.
AP> Каким образом добавить собственное событие(Event) вызываемое
AP> объектом(формой). Вроде оно описывается как property, но компилятор
AP> выдает ошибку: INDEX, READ or WRITE clause expected, but ';' found
AP> Делаю чтото вроде этого (по хелпу):
AP> type
AP> TMyEvent = procedure (Sender: TObject) of object; (можно исполз.
AP> TNotifyEvent?)
AP> TForm = class (TForm)
AP> property OnSomething: TMyEvent;
AP> end;
AP> PS: А вообще это можно зделать?
А как же сделаны события в TForm? Погляди исходники.
Hабиралось в деде, так что не пинать особо. ;)
type
TOnPadaet = TNotifyEvent; // можно и конкретную процедуру описать, если нужны
какие-нить параметры
TMyForm = class (TForm)
FOnPadaet = TPadaet;
property OnPadaet: TNotifyEvent read FOnPadaet write FOnPadaet
end;
procedure TMyForm.Close;
begin
if Assigned(FOnPadaet) then FOnPadaet(Self);
end;
Удачи!
>> Каким образом добавить собственное событие(Event) вызываемое
>> объектом(формой). Вроде оно описывается как property, но компилятор
>> выдает ошибку: INDEX, READ or WRITE clause expected, but ';' found
LT> Есть очень хорошая книга: Рей Конопка. "Создание оригинальных компонент
LT> в среде Delphi". Hо, к сожалению, она на русском не переиздавалась с 96
LT> года. (хотя, на английском, IMHO, в 2002 году).
LT> Т.е., найти ее можно, наверное, только в библиотеке.
В ближайшее время постораюсь найти
LT> Предположим, что мы хотим научить наш компонент
LT> реагировать на изменение состояния NumLock.
[-=Cut=-]
LT> Теперь осталось придумать, как обнаруживать измененение состояния.
LT> Можно, например, сделать таймер и в его OnTimer написать:
Втом то и дело, что по таймеру я просто могу опрашивать состояние NumLoсk'а и
вызавать локальную процедурку без всяких Event'ов.
LT> procedure TMyComponent.Timer1Timer(Sender: TObject);
LT> var
LT> NewNumLock : Boolean;
LT> begin
LT> Timer.Enabled := False;
LT> NewNumLock := GetKeyState(vk_NumLock) = 1;
LT> if ( NewNumLock <> FNumLock ) then
LT> begin
LT> FNumLock := NewNumLock;
LT> NumLock; {вот, собс-но}
LT> end;
LT> Timer.Enabled := True;
LT> end;
А вот как они (Event'ы) у объектов (форм) вызываются, ведь не по таймеру же?
По сути на свой вопрос я ответ получил.
Теперь хотелось бы понять каким образом они обрабатываются (например OnActivate
у формы).
С наилучшими пожеланиями Alexander!
LT> Можно, например, сделать таймер и в его OnTimer написать:
> Втом то и дело, что по таймеру я просто могу опрашивать состояние NumLoсk'а и
> вызавать локальную процедурку без всяких Event'ов.
Во многих случаях, опрос по таймеру - самый простой способ узнать о изменении
состояния. В конкретном случае, возможно, и не требуется оформление в виде
компонента - это лишь пример.
> А вот как они (Event'ы) у объектов (форм) вызываются, ведь не по таймеру же?
Формы, как и другие TControl, получают компонентные сообщения, например,
cm_activate. Эти сообщения, в большинстве, дублируют сообщения Windows,
скажем, WM_ACTIVATE, но, т.к. не все TControl имеют окно (не TWinControl),
они могут пересылаться и не через Post/SendMessage.
> Теперь хотелось бы понять каким образом они обрабатываются (например
> OnActivate
> у формы).
Обработчик сообщения, например, message cm_activate
type
TXControl = class(TControl)
..
private
{ Private declarations }
procedure CMActivate(var Message: TCMActivate); message cm_activate;
..
end;
вызывает метод диспетчеризации (Activate; dynamic) который проверяет наличие
обработчика OnActivate и вызывает его с требуемыми параметрами (Self).
--
С уважением, LVT.