SetTimer() & TimerProc [modified]
-
Hi, I've created an MDI application that has a tool bar with buttons which open dialog boxes when clicked. One Dialog Box class in this application needs a timer. After reading about CWnd::SetTimer():
UINT_PTR SetTimer(UINT_PTR nIDEvent,UINT uElapse, TIMERPROC lpTimerFunc);
I've done the following:test.h: class test : public CDialog { ... afx_msg void OnStart(); ... }; void CALLBACK EXPORT TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ); ================================= test.cpp BEGIN_MESSAGE_MAP(test, CDialog) ON_WM_TIMER() END_MESSAGE_MAP() void test::OnStart() { ... int timer; ... timer = SetTimer(1,1000,TimerProc); // 1000 milisecond timer int i = 0; while(i<999999999) { i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec. } KillTimer(timer);// <-COMES TO THIS POINT ... } void CALLBACK TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ) { MessageBeep(0xFFFFFFFF); // Beep MSMPlaybackDlg* pbDlg = NULL; pbDlg->OnButtonHddPause(); KillTimer(hWnd, pbDlg->timer); }
the problem is that it doesn't call the TimerProc. It's as if it doesn't timeout after 1000miliseconds. does anyone know what i'm doing wrong?:confused: thanks,Kitty5
-
Hi, I've created an MDI application that has a tool bar with buttons which open dialog boxes when clicked. One Dialog Box class in this application needs a timer. After reading about CWnd::SetTimer():
UINT_PTR SetTimer(UINT_PTR nIDEvent,UINT uElapse, TIMERPROC lpTimerFunc);
I've done the following:test.h: class test : public CDialog { ... afx_msg void OnStart(); ... }; void CALLBACK EXPORT TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ); ================================= test.cpp BEGIN_MESSAGE_MAP(test, CDialog) ON_WM_TIMER() END_MESSAGE_MAP() void test::OnStart() { ... int timer; ... timer = SetTimer(1,1000,TimerProc); // 1000 milisecond timer int i = 0; while(i<999999999) { i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec. } KillTimer(timer);// <-COMES TO THIS POINT ... } void CALLBACK TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ) { MessageBeep(0xFFFFFFFF); // Beep MSMPlaybackDlg* pbDlg = NULL; pbDlg->OnButtonHddPause(); KillTimer(hWnd, pbDlg->timer); }
the problem is that it doesn't call the TimerProc. It's as if it doesn't timeout after 1000miliseconds. does anyone know what i'm doing wrong?:confused: thanks,Kitty5
It looks like your while loop does not give the main window thread any chance to process its message queue. And once the while loop is exit you also kill the timer immediately.
-
It looks like your while loop does not give the main window thread any chance to process its message queue. And once the while loop is exit you also kill the timer immediately.
suhredayan® wrote:
It looks like your while loop does not give the main window thread any chance to process its message queue.
Actually the code is and I also tried the following:
int timer; int i; MSG msg; HWND hwndTimer = (HWND)this; while(something) { timer = SetTimer(1,1000,TimerProc); i = 0; while(i<999999999) { GetMessage(&msg, NULL, 0, 0); if(msg.message == WM_TIMER) msg.hwnd = hwndTimer; // <-It does come here so the timer does get to 1000 TranslateMessage(&msg); DispatchMessage(&msg); i++; } KillTimer(timer); }
but it still doesn't execute the TimerProc()Kitty5
-
Hi, I've created an MDI application that has a tool bar with buttons which open dialog boxes when clicked. One Dialog Box class in this application needs a timer. After reading about CWnd::SetTimer():
UINT_PTR SetTimer(UINT_PTR nIDEvent,UINT uElapse, TIMERPROC lpTimerFunc);
I've done the following:test.h: class test : public CDialog { ... afx_msg void OnStart(); ... }; void CALLBACK EXPORT TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ); ================================= test.cpp BEGIN_MESSAGE_MAP(test, CDialog) ON_WM_TIMER() END_MESSAGE_MAP() void test::OnStart() { ... int timer; ... timer = SetTimer(1,1000,TimerProc); // 1000 milisecond timer int i = 0; while(i<999999999) { i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec. } KillTimer(timer);// <-COMES TO THIS POINT ... } void CALLBACK TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ) { MessageBeep(0xFFFFFFFF); // Beep MSMPlaybackDlg* pbDlg = NULL; pbDlg->OnButtonHddPause(); KillTimer(hWnd, pbDlg->timer); }
the problem is that it doesn't call the TimerProc. It's as if it doesn't timeout after 1000miliseconds. does anyone know what i'm doing wrong?:confused: thanks,Kitty5
-
suhredayan® wrote:
It looks like your while loop does not give the main window thread any chance to process its message queue.
Actually the code is and I also tried the following:
int timer; int i; MSG msg; HWND hwndTimer = (HWND)this; while(something) { timer = SetTimer(1,1000,TimerProc); i = 0; while(i<999999999) { GetMessage(&msg, NULL, 0, 0); if(msg.message == WM_TIMER) msg.hwnd = hwndTimer; // <-It does come here so the timer does get to 1000 TranslateMessage(&msg); DispatchMessage(&msg); i++; } KillTimer(timer); }
but it still doesn't execute the TimerProc()Kitty5
kitty5 wrote:
msg.hwnd = hwndTimer;
Why do you need above line ? The WM_TIMER message should have a NULL hWnd for DispatchMessage to invoke the callback.
-
Take a look at the TimerQueue [^]library.
led mike
Yes, i've tried that also. but I get an Assert error in the wincore.h. I wanted to start a timer before i started doing something. if 1sec has passed then PAUSE. if complete before 1sec then stop timer.
HANDLE m_TimerHandle = INVALID_HANDLE_VALUE; void test::OnButtonStart { ... while(something) { int i = 0; ... BOOL success = ::CreateTimerQueueTimer(&m_timerHandle, NULL, TimerProc, this, 0, 1000, WT_EXECUTEONLYONCE); while(i<999999) { i++; } DeleteTimerQueueTimer(NULL, m_timerHandle, NULL); ... } } void test::QueueTimerHandler() { MessageBeep(0xFFFFFFFF); DeleteTimerQueueTimer(NULL, m_timerHandle, NULL); OnButtonPause(); //<-ASSERT Happens after this is completed (it just changes colors on the button) } void CALLBACK TimerProc(void *lpParam, BOOLEAN timeFired) { test *obj = (test*) lpParam; obj->QueueTimerHandler(); }
Kitty5
-
kitty5 wrote:
msg.hwnd = hwndTimer;
Why do you need above line ? The WM_TIMER message should have a NULL hWnd for DispatchMessage to invoke the callback.
unfortunatly i don't see the WM_TIMER invoke the callback with or without the
suhredayan® wrote:
kitty5 wrote: msg.hwnd = hwndTimer;
grrr.... This should be such a simple task... call SetTimer(1, 1000, TimerProc); is 1000milliseconds pass before the task completes "Pause" if it does complete then disable timer. until it loops back up to the top....
Kitty5
-
Yes, i've tried that also. but I get an Assert error in the wincore.h. I wanted to start a timer before i started doing something. if 1sec has passed then PAUSE. if complete before 1sec then stop timer.
HANDLE m_TimerHandle = INVALID_HANDLE_VALUE; void test::OnButtonStart { ... while(something) { int i = 0; ... BOOL success = ::CreateTimerQueueTimer(&m_timerHandle, NULL, TimerProc, this, 0, 1000, WT_EXECUTEONLYONCE); while(i<999999) { i++; } DeleteTimerQueueTimer(NULL, m_timerHandle, NULL); ... } } void test::QueueTimerHandler() { MessageBeep(0xFFFFFFFF); DeleteTimerQueueTimer(NULL, m_timerHandle, NULL); OnButtonPause(); //<-ASSERT Happens after this is completed (it just changes colors on the button) } void CALLBACK TimerProc(void *lpParam, BOOLEAN timeFired) { test *obj = (test*) lpParam; obj->QueueTimerHandler(); }
Kitty5
kitty5 wrote:
I get an Assert error in the wincore.h.
Probably because you need WINVER defined to be 5 or higher here is a snippet from one of my files that uses that library
#if WINVER < 0x0500
/**
TimerQueueTimer class implementation uses kernel objects
that are not available before the windows 5 kernel. Place the
following definitions in your stdafx.h file to remove this warning:#define _WIN32_WINNT 0x0500
#define WINVER 0x0500*/
#error TimerQueueTimer.h requires Win32 Kernel 5
#endifled mike
-
Hi, I've created an MDI application that has a tool bar with buttons which open dialog boxes when clicked. One Dialog Box class in this application needs a timer. After reading about CWnd::SetTimer():
UINT_PTR SetTimer(UINT_PTR nIDEvent,UINT uElapse, TIMERPROC lpTimerFunc);
I've done the following:test.h: class test : public CDialog { ... afx_msg void OnStart(); ... }; void CALLBACK EXPORT TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ); ================================= test.cpp BEGIN_MESSAGE_MAP(test, CDialog) ON_WM_TIMER() END_MESSAGE_MAP() void test::OnStart() { ... int timer; ... timer = SetTimer(1,1000,TimerProc); // 1000 milisecond timer int i = 0; while(i<999999999) { i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec. } KillTimer(timer);// <-COMES TO THIS POINT ... } void CALLBACK TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ) { MessageBeep(0xFFFFFFFF); // Beep MSMPlaybackDlg* pbDlg = NULL; pbDlg->OnButtonHddPause(); KillTimer(hWnd, pbDlg->timer); }
the problem is that it doesn't call the TimerProc. It's as if it doesn't timeout after 1000miliseconds. does anyone know what i'm doing wrong?:confused: thanks,Kitty5
See here[^] for a description of what you're doing wrong and some insight on how timers work. The following code from your post is the cause of the problem and is wrong in a few levels:
int i = 0;
while(i<999999999)
{
i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec.
}Firstly, as the link I gave above explains, you're not dispatching messages so the timer process will not get called. Secondly, in a multitasking system busy waits should be avoided at all costs. Try code like this:
MSG m;
while (GetMessage(&m, NULL, 0, 0) )
{
DispatchMessage(&m);
}You will have to implement some mechanism to break out of the message loop after 7 seconds for this code to be the same as your code however. Another timer would do the trick.
Steve
-
Hi, I've created an MDI application that has a tool bar with buttons which open dialog boxes when clicked. One Dialog Box class in this application needs a timer. After reading about CWnd::SetTimer():
UINT_PTR SetTimer(UINT_PTR nIDEvent,UINT uElapse, TIMERPROC lpTimerFunc);
I've done the following:test.h: class test : public CDialog { ... afx_msg void OnStart(); ... }; void CALLBACK EXPORT TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ); ================================= test.cpp BEGIN_MESSAGE_MAP(test, CDialog) ON_WM_TIMER() END_MESSAGE_MAP() void test::OnStart() { ... int timer; ... timer = SetTimer(1,1000,TimerProc); // 1000 milisecond timer int i = 0; while(i<999999999) { i++; //TIMER SHOULD TIMEOUT IN HERE take about 7sec. } KillTimer(timer);// <-COMES TO THIS POINT ... } void CALLBACK TimerProc( HWND hWnd, // handle of CWnd that called SetTimer UINT nMsg, // WM_TIMER UINT nIDEvent // timer identification DWORD dwTime // system time ) { MessageBeep(0xFFFFFFFF); // Beep MSMPlaybackDlg* pbDlg = NULL; pbDlg->OnButtonHddPause(); KillTimer(hWnd, pbDlg->timer); }
the problem is that it doesn't call the TimerProc. It's as if it doesn't timeout after 1000miliseconds. does anyone know what i'm doing wrong?:confused: thanks,Kitty5