Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.04;
Скачать: CL | DM;

Вниз

методы объектов   Найти похожие ветки 

 
_Guest_   (2004-03-12 14:33) [0]

unit Unit1;

implementation

var
 FTimer: TTimer;

initialization
 FTimer := TTimer.Create(nil);
 FTimer.OnTimer := ?

finalization
 FTimer.Free;  
end.


как мне описать процедуру, которая будет вызываться по событию OnTimer?


 
alless ©   (2004-03-12 14:39) [1]

po moemu tak:
FTimer.OnTimer:=MyProcedure;

procedure MyProcedure(Sender:TObject)
begin
Showmessage("OnTimer")
end;


 
Amoeba ©   (2004-03-12 14:40) [2]

Читаем:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342


 
MU   (2004-03-12 14:41) [3]

unit Unit2;
interface

implementation

uses ExtCtrls;

type
TMyTimer = class(TTimer)
  procedure OnMyTimer(Sender : TObject);
end;

var
FTimer: TMyTimer;

{ TMyTimer }

procedure TMyTimer.OnMyTimer(Sender: TObject);
begin
//...
end;

initialization
FTimer := TMyTimer.Create(nil);
FTimer.OnTimer :=  FTimer.OnMyTimer;

finalization
FTimer.Free;
end.


 
_Guest_   (2004-03-12 14:56) [4]

2alless: это работать не будет.
2amoeba: ссылка клёвая да беспонтовая. Если нужную мне процедуру объвить внутри класса, то никаких проблем нету, так как она будет являться методом класса. А как это сделать, если нету класса?

2MU: а без объявления наследника?


 
MU   (2004-03-12 15:01) [5]

unit Unit2;
interface
implementation

uses ExtCtrls, Dialogs;

type
TMyObject = class(TObject)
  class procedure OnMyTimer(Sender : TObject);
end;

var
FTimer: TTimer;

{ TMyTimer }

class procedure TMyObject.OnMyTimer(Sender: TObject);
begin
FTimer.Enabled := false;
ShowMessage("Timer");
FTimer.Enabled := true;
end;

initialization
FTimer := TTimer.Create(nil);
FTimer.Interval := 1000;
FTimer.OnTimer :=  TMyObject.OnMyTimer;
FTimer.Enabled := true;
finalization
FTimer.Free;
end.

:))


 
PVOzerski ©   (2004-03-12 15:01) [6]

А метод без класса не бывает. Во-первых, процедурная переменная для метода - не один указатель, а связка из двух, во-вторых, вызов метода сопровождается неявной передачей как параметра указателя на экземпляр. "Хакерский" вариант решения состоит в том, чтобы вручную сварганить через какой-нибудь move "метод" из процедуры, нормальное же решение - написать метод как метод.


 
Amoeba ©   (2004-03-12 15:05) [7]

А как это сделать, если нету класса?
Никак. Процедура обязательно должна быть методом какого-нибудь класса. Надо учить матчасть.

В частности можно использовать совет
MU   (12.03.04 14:41) [3]

Как вариант можно создать наследника TObject c необходимым методом. Экземпляр этого класса создавать в initialization до создания таймера.


 
_Guest_   (2004-03-12 15:06) [8]

спасибо, понял - вопросов больше не имею :)


 
PVOzerski ©   (2004-03-12 15:10) [9]

2Amoeba:
а надо ли создавать экземпляр? Описать как class procedure и прямо так и передавать: tMyClass.MyProc?


 
MU   (2004-03-12 15:12) [10]

PVOzerski ©   (12.03.04 15:10) [9]
[5] ;)


 
evvcom   (2004-03-12 15:37) [11]

procedure OnMyTimer(TimerObject, Sender: TObject);
begin
 // Здесь TimerObject - формальный параметр.
 // OnMyTimer вызывается как procedure of object,
 // поэтому в нее неявно передается еще указатель на
 // экземпляр класса, в котором должно
 // обрабатываться это событие, поэтому,
 // чтобы обмануть компилятор введем в параметры явную
 // передачу ссылки на экземпляр!
end;

TMethod(FTimer.OnTimer).Code  := @OnMyTimer;


 
evvcom   (2004-03-12 15:39) [12]

TimerObject - поспешил, просто указатель на экземпляр какого-то класса, который не имеет здесь никакого смысла, но обозвать этот параметр как-то надо! А анализировать его нельзя.
А вот Sender и будет TTimer


 
evvcom   (2004-03-12 15:41) [13]

TimerObject лучше обозвать каким-нибудь Nothing


 
WebErr ©   (2004-03-12 15:42) [14]


> evvcom   (12.03.04 15:37) [11]

Вот это уже дорогого стоит! А работать будет ли? :))))


 
KSergey ©   (2004-03-12 15:45) [15]

>  [3] MU   (12.03.04 14:41)

Если уж беретесь писать наследников - так хоть пишите грамотно, ага?

> type
> TMyTimer = class(TTimer)
 private
   procedure Timer; override;
> end;
>
> var
> FTimer: TMyTimer;
>
> { TMyTimer }
>
> procedure TMyTimer.Timer;
> begin
> //...
> end;
>
> initialization
> FTimer := TMyTimer.Create(nil);
> FTimer.OnTimer :=  FTimer.OnMyTimer;
>
> finalization
> FTimer.Free;
> end.


 
KSergey ©   (2004-03-12 15:50) [16]

>  [15] KSergey ©   (12.03.04 15:45)

Промашечка вышла! Главное убрать забыл:

> FTimer.OnTimer :=  FTimer.OnMyTimer; - убрать!


 
MU   (2004-03-12 15:54) [17]

>>KSergey ©   (12.03.04 15:45) [15]
 И что же было неправильно, я не понял?


 
MU   (2004-03-12 15:57) [18]

>>KSergey ©   (12.03.04 15:50) [16]
>>Промашечка вышла! Главное убрать забыл
 Так не работает... Надо убирать все...


 
evvcom   (2004-03-12 15:59) [19]


> WebErr ©   (12.03.04 15:42) [14]
>
> > evvcom   (12.03.04 15:37) [11]
>
> Вот это уже дорогого стоит! А работать будет ли? :))))


У меня работает. В свое время про TMethod я у Юрия Зотова вычитал. Так что апплодисменты ему адресуйте.


 
KSergey ©   (2004-03-12 16:08) [20]

>  [17] MU   (12.03.04 15:54)
> >>KSergey ©   (12.03.04 15:45) [15]
>  И что же было неправильно, я не понял?

В потомках принято перекрывать предназначенные для этого методы, а не вешать свои обработчики на события компонента.
Да, в данном случае формально результат будет одинаков, т.к. не создание компонента обсуждаем, но все же считаю, что такой стиль привьет неверные привычки.

А по поводу [11] evvcom   (12.03.04 15:37) или > [6] PVOzerski ©   (12.03.04 15:01) (в части "хакерских" методов) - в данном случае не вижу разницы: описать простейшего потомка, в котором перекрыть метод Timer или написать TMethod(...) - по-моему, здесь - одинаково.
Однако в данном случае решение через потомка в перекрытым методом Timer видится мне наиболее красивым и правильным.


 
MU   (2004-03-12 16:17) [21]

>>KSergey ©   (12.03.04 16:08) [20]
 Вы извините, я не придираюсь, но у меня
это код не работает.
 в proc TMyTimer.Timer не попадает.

unit Unit2;
interface
implementation
uses ExtCtrls, Dialogs;
type
TMyTimer = class(TTimer)
private
  procedure Timer; override;
end;

var
FTimer: TMyTimer;
{ TMyTimer }

procedure TMyTimer.Timer;
begin
FTimer.Enabled := false;
ShowMessage("Timer");
FTimer.Enabled := true;
end;

initialization
FTimer := TMyTimer.Create(nil);
FTimer.Interval := 10;
FTimer.Enabled := true;
finalization
FTimer.Free;
end.


 
MU   (2004-03-12 16:21) [22]

Не работает...

unit Unit2;
interface
implementation
uses ExtCtrls, Dialogs;
type
TMyTimer = class(TTimer)
private
  procedure Timer; override;
end;

var
FTimer: TMyTimer;
{ TMyTimer }

procedure TMyTimer.Timer;
begin
Enabled := false;
ShowMessage("Timer");
Enabled := true;
end;

initialization
FTimer := TMyTimer.Create(nil);
FTimer.Interval := 10;
FTimer.Enabled := true;
finalization
FTimer.Free;
end.


 
_Guest_   (2004-03-12 16:29) [23]

2evvcom:
не работает TMethod(FTimer.OnTimer).Code  := @OnMyTimer;
говорит, Left side cannot be assigned to


 
evvcom   (2004-03-12 16:40) [24]

Прошу прощения. Немного не туда глянул в свои исходники. Поправь так:

var
 pMethod: ^TMethod;
begin
 pMethod := @@FTimer.OnTimer;
 pMethod.Code := @OnMyTimer;
end;


 
_Guest_   (2004-03-12 16:48) [25]

другое дело - так работает


 
evvcom   (2004-03-12 22:56) [26]

Или более оптимально:

type
 PMethod = ^TMethod;

begin
 PMethod(@@FTimer.OnTimer)^.Code := @OnMyTimer;
end;


 
KSergey ©   (2004-03-15 09:25) [27]

> MU   (12.03.04 16:21) [22]

Мда.. Маненько я погорячился.
Оказывается, есть определенная проблема с таймером: собственно запуск таймера осуществляется в методе TTimer.UpdateTimer, где проеврятеся обязательное задание метода обработчика в FOnTimer. Иначе таймер не устанавливается.
Вот в этом вся и беда, потому этот код не работат. В общем-то был не прав, недодумал, что так может быть. Хотя это, конечно, частный случай...



Страницы: 1 вся ветка

Текущий архив: 2004.04.04;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.074 c
3-1078565230
Trap
2004-03-06 12:27
2004.04.04
Создание таблицы в путом файле *.mdb через ADO


1-1078907554
трактор
2004-03-10 11:32
2004.04.04
Как узнать время работы ПК? Бросьте идею


1-1079431499
Alex Shulg
2004-03-16 13:04
2004.04.04
MessageBox & mb_Help ???


1-1079416363
olegy
2004-03-16 08:52
2004.04.04
frame


3-1078931930
ser k
2004-03-10 18:18
2004.04.04
как программно поменять поля местами