Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.01.09;
Скачать: CL | DM;

Вниз

Обратный отсчет времени.   Найти похожие ветки 

 
UDS   (2003-12-23 23:37) [0]

Люди погибаю помогите! Уже четыре часа бьюсь, чтобы сделать счетчик времени в обратную сторону. Стартовое время 30:00 (мин).
Со счетчиками "вперед" проблем нету, а тут... с этими нулями...назад. Никак не получается. Киньте какой-нибудь совет.


 
Юрий Зотов ©   (2003-12-23 23:45) [1]

Берем исходное значение GetTickCount + 1800000 (миллисекунд). Из него в цикле вычитаем текущее значение GetTickCount, а остаток переводим в МИН:СЕК вручную.


 
UDS   (2003-12-23 23:50) [2]

Я с этим не сталкивался...
Можно подробнее?


 
Юрий Зотов ©   (2003-12-24 00:36) [3]

На форму положить таймер, создать обработчики OnShow (у формы) и OnTimer (у таймера). В implementation написать следующее.

const
FullTime = 30*60*1000; // Исходный интервал в миллисекундах
var
TickCount: DWORD;

procedure TForm1.FormShow(Sender: TObject); // OnShow
begin
TickCount := GetTickCount + FullTime;
Caption := "30:00"
end;

procedure TForm1.Timer1Timer(Sender: TObject); // OnTimer
var
Rest: integer; // Остаток времени в секундах
begin
Rest := Round((TickCount - GetTickCount)/1000);
if Rest <= 0 then
begin
Timer1.Enabled := False;
Rest := 0
end;
Caption := Format("%2.2d:%2.2d", [Rest div 60, Rest mod 60])
end;

Обратный отсчет увидите в Caption формы.


 
sniknik ©   (2003-12-24 01:02) [4]

тоже озадачило немного :о), нестандартная задача.
только сделал чуть иначе, на форме нужны лебел и кнопка, по кнопке запуск


unit Tiks;

interface

uses
Windows, Messages, Controls, Forms, StdCtrls, Classes, SysUtils;

const
UM_USERCOUNT = WM_USER + 101;

BACK_TIME = 30 * 60 * 1000; {30 мин в млск}

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
StartTiks: DWORD;
public
procedure UserTimeCount(var Msg: TMessage); message UM_USERCOUNT;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.UserTimeCount(var Msg: TMessage); // message UM_USERCOUNT;
var TickNow: DWORD;

function TickCountToStr(Ticks: DWORD): string;
var mm,cc: DWORD;
begin
Ticks:= Ticks div 1000; //переводим в секунды
mm:= (Ticks mod 3600) div 60;
cc:= Ticks mod 60;

if mm < 10 then result:= "0" + IntToStr(mm)
else result:= IntToStr(mm);

if cc < 10 then result:= result + ":0" + IntToStr(cc)
else result:= result + ":" + IntToStr(cc);
end;

begin
TickNow:= GetTickCount;
if TickNow < StartTiks then begin
Label1.Caption:= TickCountToStr(StartTiks - TickNow);
Application.ProcessMessages;
sleep(100);
PostMessage(Form1.Handle, UM_USERCOUNT, 0, 0);
end else begin
Label1.Caption:= "00:00";
Button1.Enabled:= true;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:= "30:00";
StartTiks:= GetTickCount + BACK_TIME;
Button1.Enabled:= false;
PostMessage(Form1.Handle, UM_USERCOUNT, 0, 0);
end;

end.


 
Shirson ©   (2003-12-24 06:52) [5]

procedure TFMain.button1click(sender:Tobject);
begin
T_Main.tag=30*60;
T_Main.enabled:=true;
end;

function TFMain.itime(tm:integer):string;
var h,m,s:integer;
begin
h:=Trunc(tm/3600);
m:=Trunc((tm-h*3600)/60);
s:=Trunc((tm-h*3600-m*60));
result:=rightstr("0"+inttostr(h),2)+":"+rightstr("0"+inttostr(m),2)+":"+rightstr("0"+inttostr(s),2);
end;

procedure TFmain.T_MainTimer(Sender: TObject);
begin
T_main.Tag:=T_main.Tag-1;
FMain.Caption:=Itime(T_main.Tag);
if T_Main.Tag <= 0 then // время пришло
end;


TFmain - форма
T_main - таймер


 
Anatoly Podgoretsky ©   (2003-12-24 09:20) [6]

EndTime := Now + StrToTime("00:30:00");

TimeToStr(EndTime - Now)


 
Floppy   (2003-12-24 09:29) [7]

Красиво


 
Piople ©   (2003-12-24 09:31) [8]

Я писал программу которая через определенное время что-то делает, если надо то вышли мне на мыло что она тебе нужна, я могу ее тебе скинуть


 
Юрий Зотов ©   (2003-12-24 12:54) [9]

> Anatoly Podgoretsky © (24.12.03 09:20) [6]

[3] и [6] - совершенно одно и то же, но [3]- надежнее. Примерно в 49.71 раза.

:о)


 
Rem ©   (2003-12-24 12:59) [10]

[6] в варианте TDateTime надежнее [3] в... n-дцать раз.


 
Юрий Зотов ©   (2003-12-24 13:25) [11]

> Rem © (24.12.03 12:59) [10]

Не позволите ли Ваши доказательства? И, желательно, значение N.


 
Anatoly Podgoretsky ©   (2003-12-24 13:29) [12]

В моем коде нет ничего про анализ, только как организовать обратый показ, но если говорить про анализ, то конечно мой код не будет привязан к границе 32 бит и поэтому тут нельзя даже говорить о порядках, он просто будет правильно работать.


 
Rem ©   (2003-12-24 15:24) [13]

TDateTime учитывает не только время, но и дату. TDateTime = double; где целая часть - количество дней от начальной даты. Начальная дата определена как 12/30/1899.
Переполнение 8-байтового double при таком распределении между целой и дробной частями возникает только в 65535 году. Это приблизительно (без учета високосных дней и поправок в григорианском календаре) 23920275 дней. Тогда N = 488168 (естественно, очень приблизительно).

var
EndDate: TDateTime;

EndDate := Now + StrToInt("0"){неявное количество дней} + StrToTime("00:30:00");
LeftTime := EndTime - Now;

P.S. Впрочем, TTime = TDateTime, так что никакой разницы нет.


 
Arm79 ©   (2003-12-24 15:35) [14]

2 Anatoly Podgoretsky © (24.12.03 09:20) [6]

Самое простое и правильное решение. В вопросе ничего не говориться о суперточности времнных интервалов, а просто обратный отчет. В таком случае погрешность в несколько десятков миллисекунд роли не играет.



Страницы: 1 вся ветка

Текущий архив: 2004.01.09;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.017 c
9-25172
vaskin
2003-06-23 18:14
2004.01.09
Глюк


1-25405
Ik
2003-12-24 10:49
2004.01.09
как удалить непустой каталог


4-25670
igornov
2003-10-15 15:31
2004.01.09
Как определить момент когда пользователь сделал Log off?


3-25251
x_x_x
2003-12-10 12:42
2004.01.09
TAdoCommand и параметры


9-25169
At
2003-06-16 13:35
2004.01.09
Стрельба