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

Вниз

Наследник от TShape со встроенным таймером   Найти похожие ветки 

 
ssk ©   (2004-07-06 14:38) [0]

Всем привет! Посмотрите, пожалуйста, код и поправьте меня, где я ошибся. Проблема в том, что после установки компонента в среду, код, прописанный в обработчике OnShapeTimer, не отрабатывает, хотя при компиляции видно, что строки в обработчике отмечаются как "прокомпилированные" синими метками. Почему? Что не так? Спасибо.


unit ShapeTimer;

interface

uses
 Classes, ExtCtrls;

type
 TShapeTimer = class(TShape)
 private
   FTimer: TTimer;
   FOnShapeTimer: TNotifyEvent;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property OnShapeTimer: TNotifyEvent read FOnShapeTimer write FOnShapeTimer;
   property Timer: TTimer read FTimer write FTimer;
 end;

procedure Register;

implementation

constructor TShapeTimer.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 FTimer:=TTimer.Create(Self);
 FTimer.Enabled:=False;
 FTimer.Interval:=1000;
 FTimer.OnTimer:=OnShapeTimer;
end;

destructor TShapeTimer.Destroy;
begin
 inherited Destroy;
end;

procedure Register;
begin
 RegisterComponents("Samples", [TShapeTimer]);
end;

end.


 
MBo ©   (2004-07-06 14:45) [1]

> FTimer.Enabled:=False;
а где запуск?


 
ssk ©   (2004-07-06 14:51) [2]

>а где запуск?

запуск делается потом в приложении в нужном месте:
ShapeTimer1.Timer.Enabled:=True;

а при создании (вернее, при "кидании" компонента на форму) по умолчанию таймер выключен. или я что-то не так понимаю?


 
MBo ©   (2004-07-06 15:05) [3]

Тьфу ты, проглядел ;(
таймер же не связывается с обработчиком
...
 procedure SetShapeTimer(const Value: TNotifyEvent);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property OnShapeTimer: TNotifyEvent read FShapeTimer write SetShapeTimer;

procedure TShapeTimer.SetShapeTimer(const Value: TNotifyEvent);
begin
 FTimer.OnTimer:=Value;
 FShapeTimer:=Value;
end;

А вообще, нужно переработать интерфейс компонента - не светить наружу FTimer, только методы доступа к нему.


 
Юрий Зотов ©   (2004-07-06 15:15) [4]

> ssk

1. В момент выполнения конструктора компонент еще не загружен из DFM и поэтому FOnShapeTimer равно nil. Таким образом, реально никакой обработчик не назначается и, соответственно, событие не отрабатывает.

2. При объявлении
property Timer: TTimer read FTimer write FTimer;
есть опасность утечки памяти.

3. Деструктор здесь не нужен.

4. Чтобы свойство Timer появлялось в Object Inspector с плюсиком и списком подсвойств, для него нужно назначить другй редактор.

В итоге получим вот что.

type
 TShapeTimer = class(TShape)
 private
   FTimer: TTimer;
   procedure SetTimer(const Value: TTimer);
   function GetOnShapeTimer: TNotifyEvent;
   procedure SetOnShapeTimer(const Value: TNotifyEvent);
 public
   constructor Create(AOwner: TComponent); override;
 published
   property Timer: TTimer read FTimer write SetTimer;
   property OnShapeTimer: TNotifyEvent
     read GetOnShapeTimer write SetOnShapeTimer;
 end;

constructor TShapeTimer.Create(AOwner: TComponent);
begin
 inherited;
 FTimer := TTimer.Create(Self);
 FTimer.Enabled := False
end;

procedure TShapeTimer.SetTimer(const Value: TTimer);
begin
 FTimer.Assign(Value) // Или оставить пустое тело метода
end;

function TShapeTimer.GetOnShapeTimer: TNotifyEvent;
begin
 Result := FTimer.OnTimer
end;

procedure TShapeTimer.SetOnShapeTimer(const Value: TNotifyEvent);
begin
 FTimer.OnTimer := Value
end;

procedure Register;
begin
 RegisterComponents("Samples", [TShapeTimer]);
 RegisterPropertyEditor
   (TTimer.ClassInfo, TShapeTimer, "Timer", TClassProperty)
end;


 
ssk ©   (2004-07-06 16:06) [5]

>MBo
>Юрий Зотов

спасибо за помощь.

переделал, попробовал. работает. в принципе разобрался и идею понял, но остался один момент: после изменения в design-time значения интервала для таймера, в самой программе оно не меняется: как было 1000, так и осталось. меняется тогда, когда в run-time изменить принудительно. попробую теперь это сам исправить...


 
Юрий Зотов ©   (2004-07-06 16:36) [6]

> ssk ©   (06.07.04 16:06) [5]

Тут три варианта решения:
1. Для D6 и выше - посмотрите csSubComponent.
2. Объявить свойство Timer со stored False и писать его в DFM ручками (см. DefineProperties, и TReader/TWriter - Read/WriteComponent).
3. Убрать свойство FTimer в public и сделать его read-only, а Enabled и Interval вытащить наружу по аналогии с OnTimer.

Рекомендую вариант 3. Об этом же говорил и MBo в [3].


 
ssk ©   (2004-07-06 16:51) [7]

>3. Убрать свойство FTimer в public и сделать его read-only, а Enabled и Interval вытащить наружу по аналогии с OnTimer.

именно так я и сделал, только FTimer поместил в private.


 
Юрий Зотов ©   (2004-07-06 17:04) [8]

> ssk ©   (06.07.04 16:51) [7]

Это и имелось в виду. Поле - private, а соответствующее ему свойство - public (либо protected) и read-оnly. Никаких ресурсов не жрет, но очень полезно в плане возможных наследников.



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

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

Наверх




Память: 0.49 MB
Время: 0.032 c
14-1118159003
Андрей Жук
2005-06-07 19:43
2005.07.11
Сравнение ogty-сорсных СУБД


1-1119345488
alexa
2005-06-21 13:18
2005.07.11
Иконка на понели задач


3-1116927000
msguns
2005-05-24 13:30
2005.07.11
Что нужно на клиенте для работы ADO+Access


3-1117083340
Dmitry_VP
2005-05-26 08:55
2005.07.11
Firebird


14-1118161199
Maks_
2005-06-07 20:19
2005.07.11
Кто может решить задания на экзамен по матеше(начало аназила)