TTImerを上位クラスとしたTBeepTimerを作ろうとしています。
Timerが呼ばれるごとに、Beepを鳴らすだけのものです。
なので、Timerイベントメゾットをoverrideして、Beepを付け足せばよいものと思い、
procedure TBeepTimer.Timer;
begin
if Assigned(FOnTimer) then
begin
FOnTimer(Self);
Beep;
end;
end;
としたのですが、これをFOrm1にはりつけても、何も動作しませんでした。
ですが、そのコンポーネントのOntimerイベントに何か動作を加える
procedure TForm1.BeepTimer1Timer(Sender: TObject);
begin
//
end;
のようにしておくと、ちゃんと動作してくれます。
多分、Ontimerに何か書き込むことで、Form上で何かを宣言などしているのでしょうかが、現状の自分ではわかりませんでした。
ですので、もしよろしければ原因と解決方法についてご教授のほどお願いいたします。(解決方法はコンポーネント内のみでの方法です)
日本語不十分の箇所もたくさんあるでしょうが、その場合はご質問ください。
> これをFOrm1にはりつけても、何も動作しませんでした。
if Assigned(FOnTimer) then は「イベントハンドラが設定されていれば」という意味ですから、
イベントハンドラが無いとBeepは実行されないです。
if文の外に記述してみてください。
type
TBeepTimer = class(TTimer)
public
{ Public 宣言 }
procedure Timer; override;
end;
procedure TBeepTimer.Timer;
begin
Beep;
inherited;
end;
これでいいのでは?
inherited; を先にするか後にするかは自分できめてください
ふぐちゃん様、@様アドバイスありがとうございます。
>if Assigned(FOnTimer) then は「イベントハンドラが設定されていれば」という意味
そんな初歩的なところを間違えていましたか^^;わかりやすい解説ありがとうございます。
@様のをやってみたのですが、やはりうまくいきませんでした。
また、ふぐちゃん様のも参考にし、色々やってみたのですが、やはり前と同じ症状になってしまいます。
一応。@様のは前もやっていたのですが、そのときもうまくいきませんでした。
何か他のところで変なミスをおかしているのでしょうか。。。
試してみましたが私の環境ではうまく働きました。
参考までに試したソースを書いておきます。
unit BeepTimer;
interface
uses
ExtCtrls;
type
TBeepTimer = class(TTimer)
protected
procedure Timer; override;
end;
procedure Register;
implementation
uses
Classes, SysUtils;
procedure Register;
begin
RegisterComponents('Samples', [TBeepTimer]);
end;
procedure TBeepTimer.Timer;
begin
inherited;
Beep;
end;
end.
ふぐちゃん様、ソースまで提示していただき、ありがとうございました。
しかし、結果はやはり前回と同じでした。
自分の確認した環境は、
WinXPで
Delphi6 Personalと、
Delphi7 Proの二つです。
両者とも、OnTimerに何か書き込むと動作する模様です。
もしかすると、TTimer自体の内容がおかしいのかと思い、出来る限りの点検はしましたが、おかしな点はありませんでした。(もしかするとあるかもしれませんが・・・
ここまで親切にしていただいたのに、申し訳ありません;;
ふくちゃん様はBeepTimerをFormに貼り付け、他何もいじらずに実行していたのでしょうか?
> BeepTimerをFormに貼り付け、他何もいじらずに実行していたのでしょうか?
実はいじっていました。
申し訳ありません。
TTimerのソースコードをちゃんと読んでみたところ、TTimerのTimerメソッドは
OnTimerが設定されていないと実行されないんです。<(_ _)>
イベントハンドラが設定されていないのにタイマーを動作させるのは無駄だからでしょう。
TTimerを継承してTBeepTimerを作成するのは難しいと思います。
いえいえ、こちらは質問させていただいている立場なので、そのようなことはまったく気にしていませんので、お気になさらず^^
なんだか、自分の質問のせいで無駄な労力を使わせてしまい申し訳ありません><
>TTimerのTimerメソッドはOnTimerが設定されていないと実行されないんです。<(_ _)>
そうなのですか。。。色々アドバイスしていただいたのに、悪いです><
他の方法を考えて見ますね。ありがとうございました^^
(OnTimerをTBeepTimer上で設定したりすることは無理ですよね...??)
ではこれにて一応解決といたします。ほんとうにふぐちゃん様、@様、ありがとうございました。
解決策が見つかれば一応連絡しますね。
もしかすると、自分みたいな方がいらっしゃるかもしれませんので。(めったになさそうですが^^;
> (OnTimerをTBeepTimer上で設定したりすることは無理ですよね...??)
できますよ。以下ではコンストラクタで設定しています。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TBeepTimer = class(TTimer)
protected
procedure Timer; override;
procedure Dummy(Sender: TObject);
public
constructor Create(AOwner:TComponent);override;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
public
bt:TBeepTimer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TBeepTimer.Create(AOwner:TComponent);
begin
inherited;
if not (csDesigning in ComponentState) then
OnTimer := Dummy;
end;
procedure TBeepTimer.Timer;
begin
inherited;
Beep;
end;
procedure TBeepTimer.Dummy(Sender: TObject);
begin
// なにもしない
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
bt := TBeepTimer.Create(self);
end;
end.
↑できていますね。
初心者さん、混乱させてすみませんでした。<(_ _)>
ツイート | ![]() |