Текущий архив: 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.47 MB
Время: 0.04 c