Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];

Вниз

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

 
_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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.038 c
4-1074689155
Petrovich
2004-01-21 15:45
2004.04.04
Как запустить программу (Отказано в доступе)


1-1079112475
European
2004-03-12 20:27
2004.04.04
Программное передвижение курсора мыши


4-1075401649
myst
2004-01-29 21:40
2004.04.04
память выделенная процессу


14-1078933866
menart
2004-03-10 18:51
2004.04.04
Рыбалка :)


3-1078404598
stone
2004-03-04 15:49
2004.04.04
Проблема с TBatchMove





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский