我尝试使用SetTimer
API每隔X分钟调用一个函数。因此,我编写了以下的测试代码:
void f()
{
printf("Hello");
}
int main()
{
SetTimer(NULL, 0, 1000*60,(TIMERPROC) &f);
}
我应该每分钟都写Hello,但它不起作用。
我尝试使用SetTimer
API每隔X分钟调用一个函数。因此,我编写了以下的测试代码:
void f()
{
printf("Hello");
}
int main()
{
SetTimer(NULL, 0, 1000*60,(TIMERPROC) &f);
}
我应该每分钟都写Hello,但它不起作用。
你的程序存在一些问题:
main()
时就会结束,因此计时器无法起作用。Win32计时器需要消息泵(见下文)在工作,因为它们是通过WM_TIMER
消息实现的,即使它们没有与任何窗口相关联,并且如果您提供了函数回调。
当您指定TimerProc回调函数时,默认窗口过程会在处理WM_TIMER时调用回调函数。因此,即使您使用TimerProc而不是处理WM_TIMER,您也需要在调用线程中分派消息。
回调函数的原型有问题。请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/ms644907%28v=vs.85%29.aspx
void CALLBACK f(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
printf("Hello");
}
int main()
{
MSG msg;
SetTimer(NULL, 0, 1000*60,(TIMERPROC) &f);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
(请注意,此示例程序永远不会结束,实际程序应通过发送 WM_QUIT
进行一些额外的逻辑以达到结束的目的。)
KillTimer
停止。或者使用一个带有标志变量和定时器过程中的一个 if
的定时器。 - mity#include <stdio.h>
#include <windows.h>
void CALLBACK f(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
printf("Hello\n");
}
int main()
{
MSG msg;
SetTimer(NULL, 0, 1000 * 3, (TIMERPROC)& f);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
我发现最佳实现方式如下:
#define TIMER1 1001
#define TIMER2 1002
SetTimer(hWndMainWnd, // handle to main window
TIMER1, // timer identifier
1000,
NULL); // no timer callback
SetTimer(hWndMainWnd, // handle to main window
TIMER2, // timer identifier
5000,
NULL); // no timer callback
然后,在主事件循环的一部分:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_TIMER:
if (wParam == TIMER1)
{
// do something1
}
else
if (wParam == TIMER2)
{
// do smoething2
}
break;
window
参数是可选的。当您提供回调函数时,WM_TIMER
消息将不再发布到您的窗口。在这种情况下,窗口过程是无意义的。如果使用计时器回调,则计时器ID不再与窗口关联,并且必须在应用程序中全局唯一。使用第三方代码的应用程序不能使用硬编码的ID值,否则可能会发生冲突。使用具有适当生命周期的对象的地址是确保唯一性的传统技术。 - IInspectableWM_TIMER
消息和让系统调用回调来使用。问题提出者询问的是后者,而您的答案解释了如何使用前者。这两种方法有显著的区别:处理计时器(在窗口过程中处理消息 vs. 提供回调)和ID唯一性的范围(窗口 vs. 应用程序)。虽然此答案未能解释如何使用带有回调的计时器,但也未能解释为什么问题提出者的代码无法运行。此答案没有用处。 - IInspectable