Timerイベントメゾットについて

解決


初心者  2005-03-30 17:31:36  No: 14019

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上で何かを宣言などしているのでしょうかが、現状の自分ではわかりませんでした。

ですので、もしよろしければ原因と解決方法についてご教授のほどお願いいたします。(解決方法はコンポーネント内のみでの方法です)

日本語不十分の箇所もたくさんあるでしょうが、その場合はご質問ください。


ふぐちゃん  2005-03-30 17:51:35  No: 14020

> これをFOrm1にはりつけても、何も動作しませんでした。
if Assigned(FOnTimer) then は「イベントハンドラが設定されていれば」という意味ですから、
イベントハンドラが無いとBeepは実行されないです。
if文の外に記述してみてください。


  2005-03-30 21:29:13  No: 14021

type
TBeepTimer = class(TTimer)
  public
    { Public 宣言 }
    procedure Timer; override;
  end;

procedure TBeepTimer.Timer;
begin
  Beep;
  inherited;
end;

これでいいのでは?
  inherited;  を先にするか後にするかは自分できめてください


初心者  2005-03-30 23:33:03  No: 14022

ふぐちゃん様、@様アドバイスありがとうございます。
>if Assigned(FOnTimer) then は「イベントハンドラが設定されていれば」という意味

そんな初歩的なところを間違えていましたか^^;わかりやすい解説ありがとうございます。

@様のをやってみたのですが、やはりうまくいきませんでした。
また、ふぐちゃん様のも参考にし、色々やってみたのですが、やはり前と同じ症状になってしまいます。

一応。@様のは前もやっていたのですが、そのときもうまくいきませんでした。
何か他のところで変なミスをおかしているのでしょうか。。。


ふぐちゃん  2005-03-31 00:10:58  No: 14023

試してみましたが私の環境ではうまく働きました。
参考までに試したソースを書いておきます。

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.


初心者  2005-03-31 07:36:20  No: 14024

ふぐちゃん様、ソースまで提示していただき、ありがとうございました。
しかし、結果はやはり前回と同じでした。

自分の確認した環境は、
WinXPで
Delphi6 Personalと、
Delphi7 Proの二つです。

両者とも、OnTimerに何か書き込むと動作する模様です。
もしかすると、TTimer自体の内容がおかしいのかと思い、出来る限りの点検はしましたが、おかしな点はありませんでした。(もしかするとあるかもしれませんが・・・

ここまで親切にしていただいたのに、申し訳ありません;;
ふくちゃん様はBeepTimerをFormに貼り付け、他何もいじらずに実行していたのでしょうか?


ふぐちゃん  2005-03-31 08:45:15  No: 14025

> BeepTimerをFormに貼り付け、他何もいじらずに実行していたのでしょうか?
実はいじっていました。
申し訳ありません。
TTimerのソースコードをちゃんと読んでみたところ、TTimerのTimerメソッドは
OnTimerが設定されていないと実行されないんです。<(_ _)>
イベントハンドラが設定されていないのにタイマーを動作させるのは無駄だからでしょう。

TTimerを継承してTBeepTimerを作成するのは難しいと思います。


初心者  2005-03-31 11:34:18  No: 14026

いえいえ、こちらは質問させていただいている立場なので、そのようなことはまったく気にしていませんので、お気になさらず^^

なんだか、自分の質問のせいで無駄な労力を使わせてしまい申し訳ありません><

>TTimerのTimerメソッドはOnTimerが設定されていないと実行されないんです。<(_ _)>
そうなのですか。。。色々アドバイスしていただいたのに、悪いです><
他の方法を考えて見ますね。ありがとうございました^^
(OnTimerをTBeepTimer上で設定したりすることは無理ですよね...??)

ではこれにて一応解決といたします。ほんとうにふぐちゃん様、@様、ありがとうございました。


初心者  2005-03-31 11:35:04  No: 14027

解決策が見つかれば一応連絡しますね。
もしかすると、自分みたいな方がいらっしゃるかもしれませんので。(めったになさそうですが^^;


りおりお  2005-03-31 11:55:17  No: 14028

> (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.


ふぐちゃん  2005-03-31 18:05:20  No: 14029

↑できていますね。
初心者さん、混乱させてすみませんでした。<(_ _)>


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加