|
| Mere stopur... Fra : Nils Thøger Møller |
Dato : 03-03-03 23:42 |
|
Mit stopur tælle nu op af som planlagt, men der er stadig et problem med
tiden.
Bliver tiden 9ms, er udlæsningen sat til "00:00:00:9" og ikke "00:00:00:009"
..
Findes der en kommando, der altid sætter decimal cifre på 3 når man laver en
integer om til en string ?
Hvorfor kan jeg ikke få DecodeTime til at virke med MSec udlæsning ?
var
Form1: TForm1;
Start, Diff : TDateTime;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
Start := Now();
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
MSec, NotUsed : word;
begin
Diff := Now() - Start;
DecodeTime(Diff, NotUsed, NotUsed, NotUsed, MSec);
Label1.Caption := TimeToStr(Diff) + ':' + IntToStr(MSec);
end;
P.S: Findes der en mere "smart" måde at lave et simpelt stopur på ?
Med venlig hilsen, og tak for gode råd
Nils
| |
Aezay (04-03-2003)
| Kommentar Fra : Aezay |
Dato : 04-03-03 03:45 |
|
FormatDateTime('HH:NN:SS. ',Now)
| |
Klaus Petersen (10-03-2003)
| Kommentar Fra : Klaus Petersen |
Dato : 10-03-03 14:49 |
|
> P.S: Findes der en mere "smart" måde at lave et simpelt stopur på ?
Ja det gør der da. TTimer i delphi er ret upræcis så den er ikke så velegnet
i sammenhænge, hvor præcision er i højsædet (som f.eks. i et stopur).
Derimod findes der i Windows API et par funktioner, som giver dig adgang til
en højfrekvent tæller.
QueryPerformanceCounter ( resultat ); - Den henter tællerværdien ud
QueryPerformanceFrequency ( resultat ); - Den henter frekvensen ud - antal
tællinger pr. sekundt
resultat er af type int64.
Når du starter stopuret henter du en tællerværdi ud, og når du vil opdatere
gui, henter du en ny tællerværdi ud.
Disse 2 tællerværdier trukket fra hinanden giver stopurets nuværende tid.
Så er det bare at dividere det tal med 1/1000 af frekvensen (for at få det i
milisekunder).
Hvis jeg skulle lave det ville jeg bruge TTimer til at styre hvornår GUI
skal opdateres. Så sætter man timerens interval til f.eks. 100.
På dens ontimer event sørger man bare for at udregne det jeg snakkede om før
og opdatere caption på stopuret.
Dette skulle give et præcist stopur på de fleste moderne computere.
Jeg har været lidt kreativ og lige lavet et hurtigt stopur, som du kan kigge
lidt på:
<delphi 6 kode>
// Formen har 4 knapper, en timer og en label
//
// button1 er en knap til at starte stop uret
// button2 er til at stoppe uret
// button3 er til at pause uret
// button4 er til at nulstille uret
//
// Når du har oprettet de 4 knapper og timer skal alt koden erstattes med
den her i mailen.
// OnClick eventen skal sættes på knapperne - der skulle gerne være en
funktion at vælge - så ingen dobbelt klik!
// OnTimer eventen skal sættes på timeren
unit kode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
starttid : int64;
elapsed : int64;
ms_count : int64; // tællinger pr. ms
isStarted : boolean;
isPaused : boolean;
procedure endisbtns;
function itos ( value : integer; digits : integer ) : string;
procedure OpdaterTimer ( ms : integer );
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.endisbtns;
var
p : boolean;
begin;
p := isStarted;
button1.Enabled := not p and not isPaused;
button2.Enabled := p;
button3.Enabled := p;
button4.Enabled := not p and not isPaused;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
isPaused := false;
isStarted := true;
elapsed := 0;
QueryPerformanceCounter ( self.starttid );
timer1.Enabled := true;
endisbtns;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OpdaterTimer (0);
timer1.Interval := 55; // det er en god værdi
isStarted := false;
endisbtns;
QueryPerformanceFrequency ( self.ms_count );
ms_count := ms_count div 1000;
end;
function TForm1.itos ( value : integer; digits : integer ) : string;
var
res : string;
begin;
res := inttostr (value);
while length (res)<digits do res := '0'+res;
result := res;
end;
procedure TForm1.OpdaterTimer ( ms : integer );
var
_timer, _min, _sek : integer;
h : string;
begin;
_timer := ms div 3600000; // 1000 * 60 * 60 = ms pr. time
ms := ms mod 3600000;
_min := ms div 60000; // 1000 * 60 = ms pr. minut
ms := ms mod 60000;
_sek := ms div 1000; // 1000 ms. pr. sekundt
ms := ms mod 1000;
h := itos (_timer, 2)+':'+itos (_min, 2)+':'+itos (_sek, 2)+'.'+itos (ms,
4);
label1.Caption := h;
label1.Repaint;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
mellemtid : int64;
ms : integer;
begin
if isPaused then exit;
QueryPerformanceCounter (mellemtid);
ms := (elapsed+(mellemtid-starttid)) div ms_count;
OpdaterTimer ( ms );
end;
procedure TForm1.Button2Click(Sender: TObject);
var
mellemtid : int64;
ms : integer;
begin
timer1.Enabled := false;
if not isPaused then begin;
QueryPerformanceCounter (mellemtid);
ms := (elapsed+(mellemtid-starttid)) div ms_count;
OpdaterTimer ( ms );
end;
isStarted := false;
isPaused := false;
endisbtns;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
mellemtid : int64;
ms : integer;
begin
isPaused := not isPaused;
if (isPaused) then begin;
QueryPerformanceCounter (mellemtid);
elapsed := elapsed + (mellemtid-starttid);
ms := elapsed div ms_count;
OpdaterTimer (ms);
endisbtns;
timer1.Enabled := false;
end else begin;
QueryPerformanceCounter (starttid); // der er en ny starttid nu
endisbtns;
timer1.Enabled := true;
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
if not isStarted then OpdaterTimer (0);
end;
end.
</slut delphi kode>
| |
|
|