//////////////////////////////////////////////////////
강의실에보면요 타락천사님이 쓰신걸로 기억하는데
멀티미디어 타이머 라고 검색해보시면
타이머를 쓸때 시간이 맞지 않음을 이해하시게 될겁니다.
아래는 소스는 지도상에서 레이더처럼 사용하기전 폼캔퍼스로 테스트 했던건데요, 참조해보세요.소스와 폼디자인을 보냅니다.
<1.소스>
unit Unit1;
Fms := 1000; // 타이머 주기를 100ms 마다 한 번씩 호출되게 한다.
if timeGetDevCaps(@TimeCaps,sizeof(TimeCaps)) <> TIMERR_NOERROR then
raise Exception.Create(' Error !!');
if Fms < TimeCaps.wPeriodMin then
Fms := TimeCaps.wPeriodMin; // 실제 가능한 호출 주기보다 작으면
if Fms > TimeCaps.wPeriodMax then
Fms := TimeCaps.wPeriodMax; // 실제 가능한 호출 주기보다 크면
end;
procedure TimerProc(uTimer, uMessage, dwUser, dw1, dw2 : DWORD);stdcall;
begin
PostMessage(dwUser,USR_TIMER_ELAPSED,0,0);
end;
procedure TFrmmain.MultiBegin;
begin
if FTimerID = 0 then begin
// 타이머 디바이스에 대한 정보를 얻어 온다.
timeBeginPeriod(Fms); // 타이머 주기를 지정한다.
FTimerID := timeSetEvent(Fms,Fms,@TimerProc,integer(handle),TIME_PERIODIC);
// 타이머를 설정한다. 콜백 함수를 지정하고, TIME_PERIODIC를 사용하여
// 주기적으로 계속 호출되게 만든다.
if FTimerID = 0 then begin
timeEndPeriod(Fms);
raise Exception.Create(' Error !!');
timeKillEvent(FTimerID); // 타이머를 해제한다.
timeEndPeriod(Fms); // 타이머 주기를 해제한다.
Exit; // 에러 처리 루틴
end;
Button2.Tag := 0;
end;
end;
procedure TFrmmain.MultiEND;
begin
if FTimerID <> 0 then begin
timeKillEvent(FTimerID);
timeEndPeriod(Fms);
FTimerID := 0;
Button2.Tag := 1;
end
end;
procedure TFrmmain.TimerCallback(var M : TMessage);
begin
MultiDrawLine;
end;
procedure TFrmmain.MultiDrawLine;
var
str1, str2 : string;
DT_Count: TDateTime;
begin
MultiTime_num := MultiTime_num + 6;
if MultiTime_num > 359 then MultiTime_num := MultiTime_num - 360;
//시계 24시간 이후는 0시로 셋팅
str1 := Edit1.Text;
str2 := copy(str1,1,Pos(':',str1)-1);
str1 := intToStr(StrToint(str2) mod 24) + copy(str1,Pos(':',str1),length(str1));
DT_Count := StrToTime(str1);
DT_Count := DT_Count + EncodeTime(0, 0, 1, 0);
Edit1.Text := FormatDateTime('HH:MM:SS', DT_Count-Trunc(DT_Count));
//############################################################################//
procedure TFrmmain.Button2Click(Sender: TObject);
begin
if Button2.Tag = 0 then begin
MultiEND;
end
else begin
MultiBegin;
end;
end;
procedure TFrmmain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MultiEND;
end;
end.
<2.폼디자인>
object Frmmain: TFrmmain
Left = 192
Top = 107
Width = 870
Height = 640
Caption = 'Frmmain'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 304
Top = 544
Width = 75
Height = 25
Caption = '시작'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 448
Top = 544
Width = 75
Height = 25
Caption = '끝'
TabOrder = 1
OnClick = Button2Click
end
object Edit1: TEdit
Left = 336
Top = 424
Width = 121
Height = 21
ImeName = '한국어(한글) (MS-IME98)'
TabOrder = 2
Text = '0:00:00'
end
end
강의실에보면요 타락천사님이 쓰신걸로 기억하는데
멀티미디어 타이머 라고 검색해보시면
타이머를 쓸때 시간이 맞지 않음을 이해하시게 될겁니다.
아래는 소스는 지도상에서 레이더처럼 사용하기전 폼캔퍼스로 테스트 했던건데요, 참조해보세요.소스와 폼디자인을 보냅니다.
<1.소스>
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, mmSystem;
const
USR_TIMER_ELAPSED = WM_USER+100;
type
TFrmmain = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
procedure TimerCallback(var M : TMessage); message USR_TIMER_ELAPSED;
public
{ Public declarations }
procedure MultiDrawLine;
procedure MultiBegin;
procedure MultiEND;
end;
var
Frmmain: TFrmmain;
MultiTime_Pos0, MultiTime_Pos1, MultiTime_Pos2 : TPoint;
MultiTime_num, MultiTime_R: integer;
MultiTime_radians :double;
FTimerID: UINT;
Fms : UINT;
implementation
{$R *.DFM}
//############################################################################//
//(멀티타이머)
procedure TFrmmain.FormShow(Sender: TObject);
var
TimeCaps : TTimeCaps;
begin
//초기값
MultiTime_radians := pi / 180;
canvas.pen.mode := pmNotXor;
canvas.pen.Width := 5;
canvas.pen.Color := clRed;
MultiTime_num := 90;
MultiTime_R := 300;
MultiTime_Pos0 := point(400,300);
MultiTime_Pos2 := MultiTime_Pos0;
Edit1.Text := '0:00:00';
Fms := 1000; // 타이머 주기를 100ms 마다 한 번씩 호출되게 한다.
if timeGetDevCaps(@TimeCaps,sizeof(TimeCaps)) <> TIMERR_NOERROR then
raise Exception.Create(' Error !!');
if Fms < TimeCaps.wPeriodMin then
Fms := TimeCaps.wPeriodMin; // 실제 가능한 호출 주기보다 작으면
if Fms > TimeCaps.wPeriodMax then
Fms := TimeCaps.wPeriodMax; // 실제 가능한 호출 주기보다 크면
end;
procedure TimerProc(uTimer, uMessage, dwUser, dw1, dw2 : DWORD);stdcall;
begin
PostMessage(dwUser,USR_TIMER_ELAPSED,0,0);
end;
procedure TFrmmain.Button1Click(Sender: TObject);
begin
//타이머 가동
//마지막 자취지우기
canvas.MoveTo(MultiTime_Pos0.x, MultiTime_Pos0.y);
canvas.LineTo(MultiTime_Pos2.x, MultiTime_Pos2.y);
if FTimerID <> 0 then begin
MultiEND;
end;
MultiTime_num := 90;
MultiTime_Pos0 := point(400,300);
MultiTime_Pos1 := point(MultiTime_Pos0.x, MultiTime_Pos0.y-MultiTime_R);
canvas.MoveTo(MultiTime_Pos0.x, MultiTime_Pos0.y);
canvas.LineTo(MultiTime_Pos1.x, MultiTime_Pos1.y);
Edit1.Text := '00:00:00';
MultiBegin;
end;
procedure TFrmmain.MultiBegin;
begin
if FTimerID = 0 then begin
// 타이머 디바이스에 대한 정보를 얻어 온다.
timeBeginPeriod(Fms); // 타이머 주기를 지정한다.
FTimerID := timeSetEvent(Fms,Fms,@TimerProc,integer(handle),TIME_PERIODIC);
// 타이머를 설정한다. 콜백 함수를 지정하고, TIME_PERIODIC를 사용하여
// 주기적으로 계속 호출되게 만든다.
if FTimerID = 0 then begin
timeEndPeriod(Fms);
raise Exception.Create(' Error !!');
timeKillEvent(FTimerID); // 타이머를 해제한다.
timeEndPeriod(Fms); // 타이머 주기를 해제한다.
Exit; // 에러 처리 루틴
end;
Button2.Tag := 0;
end;
end;
procedure TFrmmain.MultiEND;
begin
if FTimerID <> 0 then begin
timeKillEvent(FTimerID);
timeEndPeriod(Fms);
FTimerID := 0;
Button2.Tag := 1;
end
end;
procedure TFrmmain.TimerCallback(var M : TMessage);
begin
MultiDrawLine;
end;
procedure TFrmmain.MultiDrawLine;
var
str1, str2 : string;
DT_Count: TDateTime;
begin
MultiTime_num := MultiTime_num + 6;
if MultiTime_num > 359 then MultiTime_num := MultiTime_num - 360;
//시계 24시간 이후는 0시로 셋팅
str1 := Edit1.Text;
str2 := copy(str1,1,Pos(':',str1)-1);
str1 := intToStr(StrToint(str2) mod 24) + copy(str1,Pos(':',str1),length(str1));
DT_Count := StrToTime(str1);
DT_Count := DT_Count + EncodeTime(0, 0, 1, 0);
Edit1.Text := FormatDateTime('HH:MM:SS', DT_Count-Trunc(DT_Count));
//시계그리기
canvas.MoveTo(MultiTime_Pos0.x, MultiTime_Pos0.y);
canvas.LineTo(MultiTime_Pos1.x, MultiTime_Pos1.y);
MultiTime_Pos2.x := Round(MultiTime_Pos0.x - MultiTime_R*Cos(MultiTime_radians * MultiTime_num));
MultiTime_Pos2.y := Round(MultiTime_Pos0.y - MultiTime_R*sin(MultiTime_radians * MultiTime_num));
canvas.MoveTo(MultiTime_Pos0.x, MultiTime_Pos0.y);
canvas.LineTo(MultiTime_Pos2.x, MultiTime_Pos2.y);
MultiTime_Pos1 := MultiTime_Pos2;
end;
//############################################################################//
procedure TFrmmain.Button2Click(Sender: TObject);
begin
if Button2.Tag = 0 then begin
MultiEND;
end
else begin
MultiBegin;
end;
end;
procedure TFrmmain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MultiEND;
end;
end.
<2.폼디자인>
object Frmmain: TFrmmain
Left = 192
Top = 107
Width = 870
Height = 640
Caption = 'Frmmain'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 304
Top = 544
Width = 75
Height = 25
Caption = '시작'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 448
Top = 544
Width = 75
Height = 25
Caption = '끝'
TabOrder = 1
OnClick = Button2Click
end
object Edit1: TEdit
Left = 336
Top = 424
Width = 121
Height = 21
ImeName = '한국어(한글) (MS-IME98)'
TabOrder = 2
Text = '0:00:00'
end
end