Click to See Complete Forum and Search --> : creating timer.


promage
June 9th, 2005, 05:50 AM
hi, i just started c++(i started vb first before c++). its very simple to create a timer in vb but i do not know how to do it in c++. heres one code i used:
bool running = true;
double MainTimer = GetTickCount();
while running = true
{
if (MainTimer + 1000 = GetTickCount())
{
MainTimer = GetTickCount();
MessageBox(bla,blabla,blabla,MB_OK);
}
}

i entered the code into the case WM_CREATE and when i started my application, only the messagebox appear, not the application... can anyone help me with this? btw, when i set the timer to getkeystate, my application will freeze.. why is this so?
thanks in advance.

Andreas Masur
June 9th, 2005, 05:57 AM
'SetTimer()' (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/timers/timerreference/timerfunctions/settimer.asp)

promage
June 9th, 2005, 06:34 AM
thx but, im a noob in C++... i dont really understand it, i searched in PSC and i do not understand the code provided too. pls kindly explain to me. sorry for this. thanks.

+J_o_S_H
June 10th, 2005, 12:24 PM
Timers are really easy

first thing you must do is come up with the name you want to give your timer
I will use ID_TIMER and it will be defined as a const int. I usually put all my variables under my #include directives

Next you need to declare an integer that will handle the error(if there is one) when you create the timer

so you should have this now:

const int ID_TIMER=1;
int ret=-1;



if you have a normal window based app place the code in WM_CREATE
if your app is dialog based, put it in WM_INITDIALOG

the timer here is set to go off every 50 milliseconds


ret = SetTimer(hWndDlg, ID_TIMER, 50, NULL);

if(ret == 0)
{
MessageBox(hWndDlg, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
}

break;


Now comes the part where you can decide what you want to do with the timer:


case WM_TIMER:
{
//your code goes here
}


the WM_TIMER event will be called every 50 milliseconds in my case and it will perform whatever code you have in the WM_TIMER event.

when you close the window, you must have it so it gets rid of the timer.
Use KillTimer() for this

in the end you should have something like this:

const int ID_TIMER=1;
int ret=-1;

//---------------------------------------------
//all other code to create window, messages etc
//---------------------------------------------

case WM_CREATE:
ret = SetTimer(hWndDlg, ID_TIMER, 50, NULL);

if(ret == 0)
{
MessageBox(hWndDlg, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
}

break;

//---------------------------------------------
case WM_TIMER:
{
//your code
}
//---------------------------------------------

case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
KillTimer(hwnd,ID_TIMER) //set HWND to proper variable
PostQuitMessage(0);
break;



I hope t hat helps

golanshahar
June 12th, 2005, 01:44 AM
you can also look at the ::timeSetEvent(..) u can determine the timers resulotion and its more accurate.

if i helped dont forget to rate :-)
Cheers

promage
June 12th, 2005, 08:10 AM
thx guys, now that i know how add timer, can you guys teach me how to add multiple timer? i know i can simple add more hwnd, hmenu, but what do i do with the WM_TIMER?
btw, how do i add a resource file?

Andreas Masur
June 12th, 2005, 09:02 AM
thx guys, now that i know how add timer, can you guys teach me how to add multiple timer? i know i can simple add more hwnd, hmenu, but what do i do with the WM_TIMER?
btw, how do i add a resource file?
Well...take a closer look at 'SetTimer()'...you pass in a timer ID...thus, passing in different ID's will create different timers. Note, that timer are system resources which are limited...

promage
June 12th, 2005, 09:31 AM
yea i see the ID_thingy..... what i mean is that i wanna know how to give each timer a specific event...in the WM_TIMER...or can you just give me an example ? thanks

+J_o_S_H
June 13th, 2005, 11:52 AM
ok so ya want more than one timer.

first -> Create another ID and give it another value i.e 2

const int ID_TIMER2=2;


second -> initialize it with another SetTimer() event

SetTimer(hwnd, ID_TIMER2, 50, NULL);


third -> in the WM_TIMER event

case WM_TIMER:
{
switch (wParam)
{
case ID_TIMER:
//your code

return TRUE;

case ID_TIMER2:
// your code

return TRUE;
}
}


last -> dont forget to kill the timer

KillTimer(hwnd,ID_TIMER2);


that should take care of multiple timers

promage
June 14th, 2005, 01:27 AM
thanks +J_o_S_H, can anyone help me with this problem ? :
Im trying to get the colour value of a pixel with GetPixel and then input it into the textbox. heres my code :
void InGame()
{
COLORREF Color;
HDC hDC;
hDC = GetDC(0);
Color = GetPixel(hDC,50,550);
SendMessage(TxtWnd,WM_SETTEXT,255,(LPARAM)(long)(Color));
}

what is wrong with my code?

+J_o_S_H
June 14th, 2005, 09:36 AM
What happens in your code? Do you get an error when compiling? If not then does anything show up in the textbox?

COLORREF is meant to show an RGB value i.e 0x00bbggrr

tell me more about the problem and maybe i can help

promage
June 14th, 2005, 07:32 PM
while compiling, theres no error nor warning, but when i press the hotkey i assigned to do the event : InGame(), and error message pops up:

The instruction at" 0x77d60b3c" referenced memory at "0x00d8e8ec. The memory could not be "read".

heres the other code(for the hotkeys which i think has no error) :
case WM_TIMER:
{
case ID_Timer:
if (GetKeyState(VK_TAB) < 0)
{
DrawLine();
}
if (GetKeyState(VK_PRIOR) < 0)
{
InGame();
}
break;
}
break;

+J_o_S_H
June 14th, 2005, 08:26 PM
have you tried debugging your project and seeing exactly where the error arises??

If you dont know how, I will help.

SuperKoko
June 15th, 2005, 01:43 AM
void InGame()
{
COLORREF Color;
HDC hDC;
hDC = GetDC(0);
Color = GetPixel(hDC,50,550);
SendMessage(TxtWnd,WM_SETTEXT,255,(LPARAM)(long)(Color));
}

what is wrong with my code?
You don't release the DC, but what is really bad and crashes, is the use of WM_SETTEXT with an invalid parameter : the Color:
MSDN says that lParam of WM_SETTEXT must be a pointer to a zero-terminating character string.
If you want to output the color in text form, in the TxtWnd, you should use a code like that:

void InGame()
{
COLORREF Color;
HDC hDC;
hDC = GetDC(NULL);
Color = GetPixel(hDC,50,550);
TCHAR Text[12];
wsprintf(Text,TEXT("06%x"),DWORD(Color));
SendMessage(TxtWnd,WM_SETTEXT,255,(LPARAM)(long)(Text));
ReleaseDC(NULL,hDC);
}

Or if you prefer a non-hexa output:


void InGame()
{
COLORREF Color;
HDC hDC;
hDC = GetDC(NULL);
Color = GetPixel(hDC,50,550);
TCHAR Text[32];
wsprintf(Text,TEXT("RGB(%u, %u, %u)"),UINT(Color&0xFF),UINT(Color>>8)&0xFF,UINT(Color>>16)&0xFF);
SendMessage(TxtWnd,WM_SETTEXT,255,(LPARAM)(long)(Text));
ReleaseDC(NULL,hDC);
}

SuperKoko
June 15th, 2005, 01:51 AM
yea i see the ID_thingy..... what i mean is that i wanna know how to give each timer a specific event...in the WM_TIMER...or can you just give me an example ? thanks
There is an alternative way:
Using timers not associated with any window:
You must call SetTimer with a NULL hwnd parameter, and a non-NULL tmprc parameter:

AnIdentifierIMustSave=SetTimer(NULL,0,500,MyTimerProc); // creates a timer with a 500 milliseconds interval.

MyTimerProc must be prototyped like that:

VOID CALLBACK MyTimerProc(
HWND hwnd, // handle of window for timer messages = NULL in your case
UINT uMsg, // WM_TIMER message : useless
UINT idEvent, // timer identifier : the identifier returned by SetTimer (AnIdentifierIMustSave)
DWORD dwTime // current system time
);

And finally, don't forget to KillTimer when the timer is no longer needed, or if your program is exited:

KillTimer(NULL,AnIdentifierIMustSave);

You can use the same TimerProc for more than one timer, and the idEvent parameter of the TimerProc identifies the timer, but you can also choose to write a different TimerProc for each timer.

promage
June 15th, 2005, 08:10 AM
Thanks SuperKoko but i tried both codes but none of them worked.

You don't release the DC
I forgotten to release >_<...btw, is there any difference in DeleteDC and ReleaseDC? I don't use ReleaseDC but instead, DeleteDC.

have you tried debugging your project and seeing exactly where the error arises??

If you dont know how, I will help.
Well i don't know how to debug it, I never learnt how to do debugging in c++, only in vb.

SuperKoko
June 15th, 2005, 08:45 AM
I forgotten to release >_<...btw, is there any difference in DeleteDC and ReleaseDC? I don't use ReleaseDC but instead, DeleteDC.

Yes, there is a difference:
DeleteDC destroys the DC. You should call DeleteDC only with memory dc (returned by CreateCompatibleDC), or with a dc returned by CreateDC.

But ReleaseDC is used to release a dc that you have got with GetDC on a window (or NULL if you want the dc of the desktop).
It does not destroys the dc, and the dc can be get a new time, with GetDC, instead it only frees the context of the dc.
If you are lucky DeleteDC probably failed properly, but theorically, it can also have undefined behaviours, that means crash.
But the crash you described probably does not comes from here, because of the address of the crash which is under 0x7FFFFFFF indicating a non-system dll (so not user32.dll nor kernel32.dll), at least if you use Windows 95/98/Me.

SuperKoko
June 15th, 2005, 08:51 AM
Hey, i am really stupid.
When i posted the "supposed to be correct" in post #14, i used copy/paste/correct, and forgot to replace the LPARAM from Color to Text.
Now, i have edited my post.

SuperKoko
June 15th, 2005, 08:55 AM
The pixel you got is RGB(236,232,216)=0x00d8e8ec. is not it?
So, the memory violation is an access to the address reinterpret_cast<TCHAR *>(Color).