我可以在控制台C ++应用程序中使用SetTimer()API吗?

我有一个控制台应用程序正在使用一个DLL文件,它使用SetTimer()调用来创build一个计时器并在其内部激发一个函数。 电话如下:

 SetTimer((HWND)NULL, 0, timer_num, (TIMERPROC)UnSyncMsgTimer)) == 0) 

它期望接收计时器消息,但这从来没有发生。 我假设,因为我是一个控制台应用程序,而不是一个标准的Windows GUI应用程序(如最初使用的DLL文件)。 这阻止了DLL文件function的关键部分不起作用。

我的应用程序需要保留一个控制台应用程序,我不能更改DLL。

有没有工作来做这个工作?

你可以使用CreateTimerQueueTimer函数

 HANDLE timer_handle_; CreateTimerQueueTimer(&timer_handle_, NULL, TimerProc, user_object_ptr, 10, 0, WT_EXECUTEDEFAULT); //callback void TimerProc(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { user_object* mgr = (user_object*) lpParameter; mgr->do(); DeleteTimerQueueTimer(NULL, timer_handle_, NULL); timer_handle_ = NULL; } 

使用SetTimer API设置的计时器需要Windows消息处理功能正在运行,因为这是发送时间消息的地方。

如果你需要一个计时器线程,那么你可以注册一个Window类,并创建一个默认的窗口消息泵(参见本文中的一个简短示例),但更简单的过程可能是旋转第二个线程来处理您的计时事件,发送通知。

看看下面的例子,它演示了如何在控制台应用程序中使用WM_TIMER消息:

( 感谢simplesamples.info网站)

 #define STRICT 1 #include <windows.h> #include <iostream.h> VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) { cout << "Time: " << dwTime << '\n'; cout.flush(); } int main(int argc, char *argv[], char *envp[]) { int Counter=0; MSG Msg; UINT TimerId = SetTimer(NULL, 0, 500, &TimerProc); cout << "TimerId: " << TimerId << '\n'; if (!TimerId) return 16; while (GetMessage(&Msg, NULL, 0, 0)) { ++Counter; if (Msg.message == WM_TIMER) cout << "Counter: " << Counter << "; timer message\n"; else cout << "Counter: " << Counter << "; message: " << Msg.message << '\n'; DispatchMessage(&Msg); } KillTimer(NULL, TimerId); return 0; } 

您是否考虑过等待定时器或定时器队列 ? 虽然可以从控制台应用程序使用SetTimer ,但这些其他设施可能更适合您。

使用计时器队列

创建一个计时器队列计时器。 此计时器在指定的到期时间到期,然后在每个指定的时间段结束。 当定时器到期时,调用回调函数。

以下示例创建一个计时器例程,该例程将在延迟10秒后由计时器队列中的线程执行。 首先,代码使用CreateEvent函数来创建一个事件对象,当定时器队列线程完成时,该事件对象被发信号通知。 然后它分别使用CreateTimerQueue和CreateTimerQueueTimer函数创建一个计时器队列和一个计时器队列计时器。 代码使用WaitForSingleObject函数来确定计时器例程何时完成。 最后,代码调用DeleteTimerQueue进行清理。

有关定时器例程的更多信息,请参阅WaitOrTimerCallback

来自MSDN的示例代码:

 #include <windows.h> #include <stdio.h> HANDLE gDoneEvent; VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired) { if (lpParam == NULL) { printf("TimerRoutine lpParam is NULL\n"); } else { // lpParam points to the argument; in this case it is an int printf("Timer routine called. Parameter is %d.\n", *(int*)lpParam); if(TimerOrWaitFired) { printf("The wait timed out.\n"); } else { printf("The wait event was signaled.\n"); } } SetEvent(gDoneEvent); } int main() { HANDLE hTimer = NULL; HANDLE hTimerQueue = NULL; int arg = 123; // Use an event object to track the TimerRoutine execution gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (NULL == gDoneEvent) { printf("CreateEvent failed (%d)\n", GetLastError()); return 1; } // Create the timer queue. hTimerQueue = CreateTimerQueue(); if (NULL == hTimerQueue) { printf("CreateTimerQueue failed (%d)\n", GetLastError()); return 2; } // Set a timer to call the timer routine in 10 seconds. if (!CreateTimerQueueTimer( &hTimer, hTimerQueue, (WAITORTIMERCALLBACK)TimerRoutine, &arg , 10000, 0, 0)) { printf("CreateTimerQueueTimer failed (%d)\n", GetLastError()); return 3; } // TODO: Do other useful work here printf("Call timer routine in 10 seconds...\n"); // Wait for the timer-queue thread to complete using an event // object. The thread will signal the event at that time. if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0) printf("WaitForSingleObject failed (%d)\n", GetLastError()); CloseHandle(gDoneEvent); // Delete all timers in the timer queue. if (!DeleteTimerQueue(hTimerQueue)) printf("DeleteTimerQueue failed (%d)\n", GetLastError()); return 0; } 

这是来自MSDN的另一个示例代码

这是Codeproject的另一个例子

 #include <windows.h> HANDLE hTimer = NULL; unsigned long _stdcall Timer(void*) { int nCount = 0; while(nCount < 10) { WaitForSingleObject(hTimer, 5000); cout << "5 s\n"; nCount++; } cout << "50 secs\n"; return 0; } void main() { DWORD tid; hTimer = CreateEvent(NULL, FALSE, FALSE, NULL); CreateThread(NULL, 0, Timer, NULL, 0, &tid); int t; while(cin >> t) { if(0==t) SetEvent(hTimer); } CloseHandle(hTimer); } 

资源:

非常简单的计时器没有Windows

 MSG Msg; UINT TimerId = (UINT)SetTimer(NULL, 0, 0, NULL); // 0 minute while (TRUE) { GetMessage(&Msg, NULL, 0, 0); if (Msg.message == WM_TIMER) { KillTimer(NULL, TimerId); cout << "timer message\n"; TimerId = (UINT)SetTimer(NULL, 0, 60000, NULL); // one minute. } DispatchMessage(&Msg); }