我有一个控制台应用程序正在使用一个DLL文件,该文件使用SetTimer()
调用来创建一个计时器并在其自身内部启动一个函数。电话如下:
SetTimer((HWND)NULL, 0, timer_num, (TIMERPROC)UnSyncMsgTimer)) == 0)
期待接收定时器消息,但这种情况永远不会发生。我假设因为我的是一个控制台应用程序而不是标准的Windows GUI应用程序(就像最初使用DLL文件的地方一样)。这将阻止DLL文件功能的关键部分工作。
我的应用程序需要保留一个控制台应用程序,我无法更改DLL。
是否有工作要做到这一点?
答案 0 :(得分:9)
您可以使用CreateTimerQueueTimer function
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;
}
答案 1 :(得分:5)
使用SetTimer
API设置的计时器需要Windows消息处理功能才能主动运行,因为这是发送时间消息的地方。
如果你需要一个计时器线程,那么你可以注册一个Window类并创建一个默认的窗口消息泵(参见this article的简短例子),但更简单的过程可能只是启动第二个线程处理你的计时事件并发送通知。
答案 2 :(得分:4)
查看以下示例,其中显示了如何在控制台应用程序中使用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;
}
答案 3 :(得分:2)
您是否考虑过Waitable Timers或Timer Queues?虽然可以从控制台应用程序中使用SetTimer
,但这些其他设施可能更适合您。
答案 4 :(得分:1)
使用计时器队列
创建一个计时器队列计时器。此计时器在指定的到期时到期 时间,然后在每个指定的时期之后。当计时器到期时, 调用回调函数。
以下示例创建将由其执行的计时器例程 延迟10秒后来自timer queue的线程。首先, 代码使用
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
的另一个示例代码 的另一个例子#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);
}
资源:
答案 5 :(得分:0)
非常简单的没有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);
}