Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Stopwatch



Permlink Replies: 8 - Last Post: Jan 22, 2018 9:48 AM Last Post By: Remy Lebeau (Te...
Krzysztof Bzoma

Posts: 7
Registered: 2/20/18
Stopwatch
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 20, 2018 2:24 PM
I just started my adventure with Rad Studio and resume my adventure with C++ after about 2 years of break. For school purposes i need to make Stopwatch app which have label and 2 buttons (Start and Stop).
When i click Start timer should start and about every 50ms it should refresh label printing elapsed time. I have problem because i can't find any proper class to do it. I looked on TStopwatch class but:
1. I don't know exacly how use it (I don't know if i should create object of it first and if yes then how because TStopwatch stopwatch is not working (For sure it's super easy and only i'm dumb after working so long on other languagues than C++)
2. It don't help refreshing displayed time. Is there any way to refresh it every 50-100ms ?

Thx you for any help and hints.
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Stopwatch
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 20, 2018 10:12 PM   in response to: Krzysztof Bzoma in response to: Krzysztof Bzoma
Krzysztof Bzoma wrote:

For school purposes i need to
make Stopwatch app

File->New C++ VCL forms app C++

which have label and 2 buttons (Start and Stop).

Find (on Standard page) and drop on the form TLabel and 2 TButton.

When i click Start timer should start

Find (on System page) and drop on the form TTimer. Its (default) name
will be Timer1.

Select Label1 and change its caption to "Please, start timer".

Select TButton1, rename it to btnStart, for example, change its caption
on "Start".

Select "Events" of the your Strat button and double click on "OnClick".
IDE will generate btnStartClick method. Place the following code in
this method:

Timer1->Start();

and about every 50ms it should

Select your Timer1 on the form and set Interval property to 50.

refresh label printing elapsed time.

In btnStartClick method add:

StartTime=Now();

Goto Form1.h and add in

private: // User declarations

or in

public: // User declarations

section a variable:

TDateTime StartTime;

Select Events of the timer and double click on OnTimer event. In newly
created Timer1Timer method add:

TDateTime ElapsedTime=Now()-StartTime;
Label1->Caption=TimeToStr(ElapsedTime);

Select TButton2, rename it to btnStop, for example, change its caption
on "Stop". Double-click on your Stop button an add in newly created
btnStopClick method:

Timer1->Stop();

Run and enjoy.

For school purposes

Select component on the form and press F1.
Study all properties, events and methods of the component.
Do it for all components on your form and form itself.

--
Alex
Krzysztof Bzoma

Posts: 7
Registered: 2/20/18
Re: Stopwatch
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 21, 2018 1:44 AM   in response to: Alex Belo in response to: Alex Belo
Alex Belo wrote:
Krzysztof Bzoma wrote:

For school purposes i need to
make Stopwatch app

File->New C++ VCL forms app C++

which have label and 2 buttons (Start and Stop).

Find (on Standard page) and drop on the form TLabel and 2 TButton.

When i click Start timer should start

Find (on System page) and drop on the form TTimer. Its (default) name
will be Timer1.

Select Label1 and change its caption to "Please, start timer".

Select TButton1, rename it to btnStart, for example, change its caption
on "Start".

Select "Events" of the your Strat button and double click on "OnClick".
IDE will generate btnStartClick method. Place the following code in
this method:

Timer1->Start();

and about every 50ms it should

Select your Timer1 on the form and set Interval property to 50.

refresh label printing elapsed time.

In btnStartClick method add:

StartTime=Now();

Goto Form1.h and add in

private: // User declarations

or in

public: // User declarations

section a variable:

TDateTime StartTime;

Select Events of the timer and double click on OnTimer event. In newly
created Timer1Timer method add:

TDateTime ElapsedTime=Now()-StartTime;
Label1->Caption=TimeToStr(ElapsedTime);

Select TButton2, rename it to btnStop, for example, change its caption
on "Stop". Double-click on your Stop button an add in newly created
btnStopClick method:

Timer1->Stop();

Run and enjoy.

For school purposes

Select component on the form and press F1.
Study all properties, events and methods of the component.
Do it for all components on your form and form itself.

--
Alex

I only got 2 errors, first that Label don't have caption property so i used Label1->Text for it. 2nd Error is that TTimer don't have "Start" member so i solved it by disabling TTimer in form and then on startButton click event putting Timer1->Enabled=true; Can i only somehow make time including milliseconds? Like up to 3 numbers.

Edited by: Krzysztof Bzoma on Jan 21, 2018 1:46 AM
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Stopwatch [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 21, 2018 6:42 AM   in response to: Krzysztof Bzoma in response to: Krzysztof Bzoma
Krzysztof Bzoma wrote:

I only got 2 errors

My "recipe" is untested (without BCB in hand) so it is good result. :-)

TTimer don't have "Start" member

yes, use Enabled/Disabled.

Can i somehow make time including milliseconds? Like up to 3 numbers.

Use

System.SysUtils.DecodeTime
http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.SysUtils.DecodeTime

and format output string like this:

unsigned short H, M, S, MS;
DecodeTime(DateTime, H, M, S, MS);

String s;
s.printf("%02hu:%02hu:%02hu.%03hu", H, M, S, MS);
Label->Text=s;

More about print formats see, for example on

http://www.cplusplus.com/reference/cstdio/printf/

--
Alex
Krzysztof Bzoma

Posts: 7
Registered: 2/20/18
Re: Stopwatch [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 21, 2018 7:37 AM   in response to: Alex Belo in response to: Alex Belo
Alex Belo wrote:

Use

System.SysUtils.DecodeTime
http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.SysUtils.DecodeTime

and format output string like this:

unsigned short H, M, S, MS;
DecodeTime(DateTime, H, M, S, MS);

String s;
s.printf("%02hu:%02hu:%02hu.%03hu", H, M, S, MS);
Label->Text=s;

More about print formats see, for example on

http://www.cplusplus.com/reference/cstdio/printf/

--
Alex

I try it and have 2 errors, first (and i think it make 2nd too)
[bcc64 Error] RadStudioTimer.cpp(33): cannot initialize a parameter of type 'const wchar_t *' with an lvalue of type 'const char [24]'
ustring.h(63): passing argument to parameter 'format' here
where here is: int __cdecl printf(const wchar_t* format, ...); // Returns formatted length
2nd error is:
bcc64 command line for "RadStudioTimer.cpp"
c:\program files (x86)\embarcadero\studio\19.0\bin\bcc64.exe -cc1 -D _DEBUG -D USEPACKAGES -n .\Win64\Debug -I F: -I "c:\program files
(x86)\embarcadero\studio\19.0\include\windows\fmx" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include" -isystem "c:\program files
(x86)\embarcadero\studio\19.0\include\dinkumware64" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\crtl" -isystem
"c:\program files (x86)\embarcadero\studio\19.0\include\windows\sdk" -isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\rtl"
-isystem "c:\program files (x86)\embarcadero\studio\19.0\include\windows\vcl" -isystem "c:\program files
(x86)\embarcadero\studio\19.0\include\windows\fmx" -isystem C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win64 -isystem
C:\Users\Public\Documents\Embarcadero\Studio\19.0\hpp\Win64 -g -fno-limit-debug-info -fborland-extensions -nobuiltininc -nostdsysteminc -triple
x86_64-pc-win32-elf -emit-obj -fexceptions -fcxx-exceptions -fseh -munwind-tables -fno-spell-checking -fno-use-cxa-atexit -main-file-name
RadStudioTimer.cpp -x c++ -std=c++11 -O0 -fmath-errno -tR -tM -tU -tW -o .\Win64\Debug\RadStudioTimer.o -dependency-file
.\Win64\Debug\RadStudioTimer.d -MT .\Win64\Debug\RadStudioTimer.o -sys-header-deps -include-pch .\Win64\Debug\Project1PCH1.pch RadStudioTimer.cpp

I checked printf documentation and it seems ok.
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Stopwatch [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 21, 2018 9:12 AM   in response to: Krzysztof Bzoma in response to: Krzysztof Bzoma
Krzysztof Bzoma wrote:

String s;
s.printf("%02hu:%02hu:%02hu.%03hu", H, M, S, MS);

I try it and have 2 errors, first (and i think it make 2nd too)
[bcc64 Error] RadStudioTimer.cpp(33): cannot initialize a parameter
of type 'const wchar_t *' with an lvalue of type 'const char [24]'

Try adding L before format string to make it Unicode:

s.printf(L"%02hu:%02hu:%02hu.%03hu", H, M, S, MS);

String is unicode now (i still use CB2007 where this parameter is const
char*, not wide char*).

--
Alex
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Stopwatch [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 22, 2018 9:48 AM   in response to: Alex Belo in response to: Alex Belo
Alex Belo wrote:

Try adding L before format string to make it Unicode:

s.printf(L"%02hu:%02hu:%02hu.%03hu", H, M, S, MS);

Better is to use the _D() macro instead, so the string literal matches
the character type of the String class that printf() is being called on:

s.printf(_D("%02hu:%02hu:%02hu.%03hu"), H, M, S, MS);

--
Remy Lebeau (TeamB)

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Stopwatch [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 22, 2018 9:47 AM   in response to: Krzysztof Bzoma in response to: Krzysztof Bzoma
Krzysztof Bzoma wrote:

first that Label don't have caption property so i used Label1->Text
for it.

That means you are using FMX instead of VCL. In VCL, TLabel has a
Caption property. In FMX, it has a Text property instead.

Next time, please be sure to state which framework you are using. It
makes a big difference.

2nd Error is that TTimer don't have "Start" member

That is correct. But TStopWatch does.

so i solved it by disabling TTimer in form and then on startButton
click event putting Timer1->Enabled=true;

That is the correct way to use TTimer.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Stopwatch
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 22, 2018 9:44 AM   in response to: Krzysztof Bzoma in response to: Krzysztof Bzoma
Krzysztof Bzoma wrote:

I have problem because i can't find any proper class to do it.

Look at the VCL's TTimer component, with its OnTimer event.

I looked on TStopwatch class

That class is meant for timing code. Even if you used it for your
actual clock, you would still need to poll its elapsed time
periodically, such as with a TTimer.

1. I don't know exacly how use it

Did you read the documentation?

http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Diagnostics.TStopwatch

I don't know if i should create object of it first

Yes.

and if yes then how because TStopwatch stopwatch is not working

Then you are likely not using it correctly. But you didn't show your
code, so noone can explain why to you.

2. It don't help refreshing displayed time.

No. TStopWatch is a non-visual class. You have to update the GUI
separately.

Is there any way to refresh it every 50-100ms ?

Something like this:

TStopWatch sw;
 
void __fastcall TForm1::StartButtonClick(TObject *Sender)
{
    sw.Start();
    Timer1->Enabled = true;
}
 
void __fastcall TForm1::StopButtonClick(TObject *Sender)
{
    sw.Stop();
    Timer1->Enabled = false;
}
 
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    TTimeSpan elapsed = sw.Elapsed;
    Label1->Caption = String().sprintf(_D("%02d:%02d:%02d.%03d"),
elapsed.Hours, elapsed.Minutes, elapsed.Seconds, elapsed.Milliseconds);
}


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02