Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2008年10月10日] [更新 2012年04月28日] Delphi サンプルプログラム集
003_簡易ストップウォッチ
動作確認等 Windows 7 U64(SP1) + Delphi XE Pro
003_StopWatch.zip [1,083 KB] 2012年04月12日版 (EXE 同梱)



  • 2012年04月10日
  • Delphi XE での動作確認とコード整備
  • TStopWatch のサンプルを追加




ストップウォッチとタイマー


ストップウォッチのサンプルです。ストップウォッチもタイマーも基本的に同じです。
一定時間が経過したら動作を止めるのがタイマー、途中で止めて、経過時間を知るのがストップウォッチということになります。

タイマーやストップウォッチの機能は、コンポーネントパレットの [System] タブにある TTimer コンポーネントを使用すると簡単に実現できます。
TTimer コンポーネントは確度、精度共に少し低いので、確度、精度を高めるために、本ページのサンプルでは、TTimer コンポーネント以外を使用しています。

経過時間の表示はしていません。またスレッドも使用していませんが、[004_タイマー] のサンプルプログラムで、[ストップ] ボタンがあるものは、全てストップウォッチとしての機能があるということになります。ただし、[04_タイマー] のサンプルプログラムでは、残り時間を秒単位で表示するようになっています。これを経過時間を表示するようにして、計測したい最小時間単位で表示するようにすれば、ストップウォッチになります。



TTimer コンポーネントや、本ページのサンプルで使用しているコンポーネント類を使用しなくても、タイマーの機能は、以下のようなコードで実装できます。
グローバルな変数を用意します。このコードでは StopFlag という論理型の変数です。この値が変わった時を「ストップ」の合図として、ループ内の処理を終了します。このような目的で使用する変数のことをフラグと言っています。フラグは「旗」のことです。つまり、旗で合図するという意味です。
タイマー専用のコンポーネント類を使用すると、フラグを使用する必要がありません。



リスト1
MMSystem のルーチンを使用した簡単なストップウォッチ
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    StopFlag : Boolean;
  public
    { Public 宣言 }
  end;

var
  Form1 : TForm1;

implementation

uses MMSystem;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  TimeStart : Cardinal;
begin
  //ストップしていない
  StopFlag := False;
  //現在の時刻を取得しておく
  TimeStart := timeGetTime;

  //StopFlagの値がTrueになったら終了
  while True do begin
    if StopFlag then break;
    Application.ProcessMessages;
    Sleep(1);
  end;
  //[秒.ミリセコンド]で表示
  ShowMessage(Format('%5.3f ', [(timeGetTime - TimeStart) / 1000.0]));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  StopFlag := True;
end;

end.




01_簡易ストップウォッチ


[002_アプリの起動時間を測定] で使用したマイクロ秒測定用のストップウォッチを使用したストップウォッチのサンプルです。そのサンプルコードからストップウォッチの部分だけを取出したものです。

このサンプルでは、[スタート] と [ストップ] ボタンが別々になっていますが、1 つのボタンで [スタート] と [ストップ] を兼用したトグルボタンにすることもできます。トグル操作の実装は、グローバル変数を使用することもできますが、const 修飾子と型付き定数を使用する方法もあります。



図1
設計時画面
図2
実行画面
  • 6.744 秒でストップしたところ

リスト2
簡易ストップウォッチ
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, plJStopWatch;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    AStopWatch : TplJStopWatch;
   procedure DisplayTime(msTime: Extended);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  ストップウォッチを機動
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if not Assigned(AStopWatch) then AStopWatch := TplJStopWatch.Create(Self);

  AStopWatch.Start;
  DisplayTime(0);
end;

//=============================================================================
//  ストップウォッチを停止
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  ATime : Extended;
begin
  if AStopWatch <> nil then begin
    ATime := AStopWatch.Stop;
    DisplayTime(ATime);
    Windows.Beep(200, 800);
  end;
end;

//=============================================================================
//  時間を小数点以下3桁の秒単位で表示。つまり1/1000秒(ミリセコンド)まで表示
//  TplStopWatchの返値はミリセコンド
//=============================================================================
procedure TForm1.DisplayTime(msTime: Extended);
begin
  Panel1.Caption := Format('%5.3f ', [msTime / 1000.0]);
  Panel1.Update;
end;

end.




02_TStopWatch を使用したストップウォッチ  ( Delphi 2010 以降 )


Delphi 2010 の Diagnostics ユニットに追加された、TStopWatch を使用したストップウォッチのサンプルです。
時刻取得のプロパティは、TTimeSpan 型のレコード型となっていて、いろいろな形式での時刻形式での取得ができます。TTimeSpan クラス (レコード型)は、TimeSpan というユニットにあります。
TStopWatch は QueryPerformanceCounter 関数を使用しています。


図3
設計時画面
図4
実行画面
  • 145.081 秒でストップしたところ

リスト3
TStopWatch を使用したストップウォッチ
uses に Diagnostics を追加して使用
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Diagnostics;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    AStopWatch : TStopWatch;
   procedure DisplayTime(msTime: Int64);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  ストップウォッチを機動
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  AStopWatch := TStopwatch.StartNew;
  DisplayTime(AStopWatch.ElapsedMilliseconds);
end;

//=============================================================================
//  ストップウォッチを停止
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  AStopWatch.Stop;
  DisplayTime(AStopWatch.ElapsedMilliseconds);
  Windows.Beep(200, 800);
end;

//=============================================================================
//  時間を小数点以下3桁の秒単位で表示。つまり1/1000秒(ミリセコンド)まで表示
//  TStopWatchのElapsedMillisecondsプロパティの値はミリセコンド
//=============================================================================
procedure TForm1.DisplayTime(msTime: Int64);
begin
  Panel1.Caption := Format('%5.3f ', [msTime / 1000.0]);
  Panel1.Update;
end;

end.