-
делаю компонент
TGTimer = class(TTimer)
private
{ Private declarations }
protected
{ Protected declarations }
procedure Ontimer1(S:TObject);
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
end;
// ---------------------------------- TGTimer
Constructor TGTimer.Create(AOwner: TComponent);
begin
Inherited Create(AOwner);
Enabled:=False;
Ontimer:=Ontimer1;
end;
procedure TGTimer.Ontimer1(S:TObject);
begin
showmessage('1');
Inherited Ontimer(s);
end;
Destructor TGTimer.Destroy;
begin
Inherited;
end;
===
регистрируется, кладу на форму включаю в свойствах, далее в онтаймер пишу
procedure TForm1.GTimer1Timer(Sender: TObject);
begin
showmessage('2');
end;
но при запуске никаких сообщений не выдает. что не так?
Что надо: создать потомка от таймера с промежуточной обработкой события онтаймер (чтобы сначало отрабатывало то что в компоненте, а потом то что на форме в онтаймер)
-
если при создании заремить enabled:=false то показывает только "2". тогда непонятно как создать потомка с измененным (переопределенным) свойством и почему не показывает "1".
-
вася, не трогай онтаймер. оно не для тебя, оно для пользователя твоего таймера.
-
Надо так переопределять:
TGTimer = class (TTimer)
protected
procedure Timer; override;
end;
...
procedure TGTimer.Timer;
begin
ShowMessage('2');
inherited;
end;
Метод Timer не сработает, если не назначен обработчик OnTimer, т.к. - смотри исходники TTimer.
Советую почитать что-нибудь по созданию компонентов, например Тейксейр и Пачеко. Ну а лучший учебник - сами исходники VCL.
-
*Тейксейру
-
пасибо попробую
-
еще такой вопрос: при работе стандартного ontimer работа ведется в отдельном потоке или используется что-то типа app..processmessage?
я вот смотрю у jedy исходник там вот на потоках реализовано. а как лучше - стандартный или ихний?
-
Нет никакого отдельного потока
-
> vasa777 (10.07.12 10:13) [6]
Всё в основном потоке - ловится сообщение WM_TIMER из общей очереди.
> я вот смотрю у jedy исходник там вот на потоках реализовано. а как лучше - стандартный или ихний?
Что именно в jedi реализовано на потоках? Задачи-то разные бывают.
Какая у тебя задача?
-
задача в онтаймер обновлять статистику вычислений на форме (лабелы и мемо). вычисления довольно весомые и форма сильно притормаживает и зависает на 3-5 сек, вычисления длятся несколько минут. а вносить processmessages в процесс вычислений не хочется, так дольше работает.
-
+ потренироваться в создании компонент своих
-
Вот если я на вашем примере сделаю
TGTimer = class (TTimer)
protected
procedure Timer; override;
end;
...
procedure TGTimer.Timer;
begin
application.processmessages;
inherited;
end;
нормально будет? а в онтаймер рефреш лаблов.
-
> vasa777 (10.07.12 10:41) [9]
Какой смысл свой компонент писать? Да еще и на основе таймера?
Выноси вычисления в отдельный поток. А из потока отправляй сообщения форме (через PostMessage или, на крайний случай, через Synchronize) для визуализации прогресса.
Чтобы не тормозило, обновлять визуализацию надо не на каждой итерации цикла вычислений, а когда, к примеру, прогресс изменяется на 1%, чтобы лишний раз сообщения не слать. Можно вообще в стиле висты сделать - пока идут вычисления прогрессбар рисуется анимированно в виде бегающей змейки.
Таймер тут ни к чему. Про ProcessMessages лучше вообще забыть.
> vasa777 (10.07.12 10:52) [11]
Это не сработает, если вычисления в основном потоке.
-
а вносить processmessages в процесс вычислений не хочется, так дольше работает.
логика конечно инопланетная.
считается что-то тяжелое.
попутно меняются капшены лейблов (тут же при самих вычислениях)
автор жмется на процессмессадж внутри вычислений.
но придумывает вставить их не просто в онтаймер, он придумывает написать свой таймер.
блестяще. тебе в правительстве работать или в думе. примут без экзаменов.
-
ну подумаю. мне не сколько прога интересна, сколько вопрос создания компонента.
а подскажите, почему при Enabled:=False; (в начале) делает при "кладении" на форму таймер выключеным, дает его включить в свойствах, но при работе программы он все равно не включается?
-
тут
Constructor TGTimer.Create(AOwner: TComponent);
begin
Inherited Create(AOwner);
Enabled:=False;
end;
-
видимо потому что у предка актив = true и при этом default.
как следствие твое значение true не попадает в дфм и на рантайме таймер в состоянии после конструктора.
-
кроме этого
Constructor TGTimer.Create(AOwner: TComponent);
begin
Inherited Create(AOwner);
Enabled:=False;
end;
нужно добавить
published
property Enabled; default False;
end
и для
default property всегда делать одинаковые настройки и в конструкторе, и в описании типа.
Поскольку если у свойства стоит
default <Константа>;, то при сохранении в DFM, если значение свойства совпадает с этой константой, то в DFM начего не пишется.
-
спасибо