我想做一个秒表,精度是1/10秒。如何实现在每1/10秒的跳动。
菜鸟--我,使用sleep(100),但是没成功。

解决方案 »

  1.   

    用个定时器,
    每100毫秒触发一次就行了呀
    Timer1.Interval:=100;
      

  2.   

    Delphi自带有一个DEMOSX:\Program Files\Borland\Delphi6\Demos\Clx\StopWatch
      
      

  3.   

    var
        BeginTime:int64 ;     //Timer Begin time
        EndTime:int64 ;       //Timer End time
        Frequency:int64 ;     //used by system time counter
    begin
        QueryPerformanceFrequency(Frequency);
        QueryPerformanceCounter(BeginTime);         //Get Start Timer Time
        while not Terminated do
        begin
           ServiceThread.ProcessRequests(false);
           QueryPerformanceCounter(EndTime);        //Get Current Time
           if (EndTime-BeginTime)*1000/Frequency>=100 then //100 =1/10秒
           begin
              //
              //Raise Timer Event or Dosomething here
              //
              QueryPerformanceCounter(BeginTime);    //Get Next Timer Start Time
           end;
           Sleep(1);
        end;
    end;
      

  4.   

    var atime:integer;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      timer1.Interval:=100;
      timer1.Enabled:=false;
      label1.Caption:='0';
      atime:=0;
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      atime:=atime+1;
      label1.Caption:=format('%.1f秒',[atime/10])
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
     //label1.Caption:='0';
     //atime:=0;
      timer1.Enabled:=true;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      timer1.Enabled:=false;
    end;
      

  5.   

    由于Slee的原因,使用多线程,并调用VCL函数时,精确度大概为50毫秒级。
      

  6.   

    Timer的精确度有待考验,同时使用GetTickCount的精确度也比较高,不过如果需要更为精确的就使用setTimerEvent
      

  7.   

    50毫秒以上的Timer可以应付,
    一下的建议用多媒体定时器(setTimerEvent)
      

  8.   

    用下面的控件,再加上FormatDateTime('z',Now){
        作者:NeutronBoy
        EMail:[email protected] [email protected]
        说明:
        多媒体定时器,精度可以达到1ms,定时相当准确。
        大家可以任意使用,不过请保留作者的原著权。
        我相信这是最好的多媒体定时器了,代码规范简洁,优美。
        不仅方便大家使用,更多的是能够给大家的编码带来帮助。
    }
    unit MMTimer;interfaceuses
      Windows, SysUtils, Classes, MMSystem;type
      EMMTimer = class(Exception);
      TMMTimer = class(TComponent)
      private
        uTimerID: MMRESULT;
        FInterval: Cardinal;
        FResolution: Cardinal;
        FOnTimer: TNotifyEvent;
        FEnabled: Boolean;
        procedure UpdateTimer;
        procedure SetEnabled(Value: Boolean);
        procedure SetInterval(Value: Cardinal);
        procedure SetOnTimer(Value: TNotifyEvent);
        procedure SetResolution(Value: Cardinal); //设置分辨率
      protected
        procedure Timer; dynamic;
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        property Enabled: Boolean read FEnabled write SetEnabled default True;
        property Interval: Cardinal read FInterval write SetInterval default 1000;
        property Resolution: Cardinal read FResolution write SetResolution default 10;
        property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('System', [TMMTimer]);
    end;procedure TimerCallback(uTimerID, uMessage: Cardinal; dwUser, dw1, dw2: Cardinal); stdcall;
    var
      MMTimer: TMMTimer;
    begin
      MMTimer := TMMTimer(dwUser);
      if Assigned(MMTimer) then
        MMTimer.Timer;
    end;{ TMMTimer }constructor TMMTimer.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FEnabled := True;
      FInterval := 1000;
      FResolution := 10;
      uTimerID := 0;
    end;destructor TMMTimer.Destroy;
    begin
      FEnabled := False;
      UpdateTimer;
      inherited Destroy;
    end;procedure TMMTimer.SetEnabled(Value: Boolean);
    begin
      if Value <> FEnabled then
      begin
        FEnabled := Value;
        UpdateTimer;
      end;
    end;procedure TMMTimer.SetInterval(Value: Cardinal);
    begin
      if Value <> FInterval then
      begin
        FInterval := Value;
        UpdateTimer;
      end;
    end;procedure TMMTimer.SetOnTimer(Value: TNotifyEvent);
    begin
      FOnTimer := Value;
      UpdateTimer;
    end;procedure TMMTimer.SetResolution(Value: Cardinal);
    var
      Caps: TTimeCaps;
    begin
      if (Value <> FResolution) and (timeGetDevCaps(@Caps, Sizeof(TTimeCaps)) <> 0) then
      begin
        if Value < Caps.wPeriodMin then //小于最小分辨率
          Value := 0
        else if Value > Caps.wPeriodMax then //大于最小分辨率
          Value := Caps.wPeriodMax;
        FInterval := Value;
        UpdateTimer;
      end;
    end;procedure TMMTimer.Timer;
    begin
    //  if Assigned(MMTimer.OnTimer) then
    //    FOnTimer(MMTimer);
      if Assigned(OnTimer) then
        FOnTimer(Self);end;procedure TMMTimer.UpdateTimer;
    var
      lpTimerProc: TFNTimeCallBack;
    begin
      if uTimerID <> 0 then
        timeKillEvent(uTimerID); //销毁
      if (FInterval > 0) and FEnabled and Assigned(FOnTimer) then
      begin
        lpTimerProc := @TimerCallback;
        uTimerID := TimeSetEvent(FInterval, FResolution, lpTimerProc, DWORD(Self), TIME_PERIODIC);
        if uTimerID = 0 then
        begin
          FEnabled := FALSE;
          raise EMMTimer.Create('定时器创建失败!');
        end;
      end;
    end;
    end. 
      

  9.   

    同意用setTimerEvent比较精确。比如:定义一个100ms的定时器TimerID :=timeSetEvent(100,1,@MyTimer1Timer,DWORD(self),TIME_PERIODIC);这样每0.1S触发一次事件就可。procedure MyTimer1Timer(NA1,NA2,CairnTimerUser,NA3,NA4: Integer); stdcall;
    var
      Event : TEvent;
    begin
      Event.SetEvent;
    end;
      

  10.   

    要省事的话就设置一下那个DoubleBuffered属性吧。假如你用的是Label就Label.Parent.DoubleBuffered := True;
    如果你用的是Panel一类从TWinControl继承下来的就直接Panel.DoubleBuffered := True;
      

  11.   

    还是自己创建一个timer
    把时间间隔设置成你想要的100
    省事!
      

  12.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Timer1: TTimer;
        GroupBox1: TGroupBox;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        Label7: TLabel;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
    i:integer;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);begin
    i:=1;
    button1.Caption :='开始';
    button2.Caption :='退出';
    end;procedure TForm1.Button1Click(Sender: TObject);
    beginif button1.Caption='开始' then begin
    button1.Caption :='停止';
    timer1.Enabled :=true;
    label7.Caption :='00' ;
    label5.Caption :='00' ;
    label3.Caption :='00' ;
    label1.Caption :='00' ;
     end
    else
     begin
    timer1.Enabled :=false;
    button1.Caption :='开始';
    end;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    close;
    end;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if button1.Caption='停止' then
    //while strtoint(label7.Caption)<60 do
    begin
    i:=i+1;
    label7.Caption:=inttostr(i) ;
    end;
    if label7.Caption='60' then
    begin
    label7.Caption :='00';
    i:=1;
    label5.Caption :=inttostr(strtoint(label5.Caption)+1);
    end;
    if label5.Caption='60' then
    begin
    label5.Caption :='00';
    label3.Caption :=inttostr(strtoint(label3.Caption)+1);
    end;
    if label3.Caption='60' then
    begin
    label3.Caption :='00';
    label1.Caption :=inttostr(strtoint(label1.Caption)+1)
    end;//if (strtoint(label7.Caption)<10)and(strtoint(label7.Caption)>0) then
    //label7.Caption :='0'+label7.Caption ;
    //if (strtoint(label5.Caption)<10)and(strtoint(label5.Caption)>0) then
    //label5.Caption :='0'+label5.Caption ;end;
    end.
      

  13.   

    使用Timer是极不准确的,不可取.最好是用GetTickcount精确.
    为了避免闪屏,应该用多线程.TThread来解决.