C++ 如何使用 SetTimer API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15685095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:39:17  来源:igfitidea点击:

How to use SetTimer API

c++windowsapi

提问by user2219913

I tried to use SetTimerAPI to call a function every X minutes. So, i have written this test code

我尝试使用SetTimerAPI 每 X 分钟调用一个函数。所以,我写了这个测试代码

void f()
{
 printf("Hello");
}
int main() 
{
 SetTimer(NULL, 0, 1000*60,(TIMERPROC) &f); 
}

I should have Hello written every minute but it does not work.

我应该每分钟都写你好,但它不起作用。

回答by mity

There are few problems with your program:

你的程序有几个问题:

  1. C programs do end when they leave main()so there is no time when the timer can occur.
  2. Win32 timers need the message pump (see below) to be working, as they are implemented through WM_TIMERmessage, even when they are not associated with any window, and if you provide function callback.

    When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

    Source: MSDN: SetTimer function

  3. The callback function has bad prototype. See 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;
    }
    
  1. C 程序在离开时确实结束,main()因此没有时间可以发生计时器。
  2. Win32 计时器需要消息泵(见下文)才能工作,因为它们是通过WM_TIMER消息实现的,即使它们不与任何窗口关联,并且如果您提供函数回调。

    当您指定 TimerProc 回调函数时,默认窗口过程在处理 WM_TIMER 时调用该回调函数。因此,您需要在调用线程中调度消息,即使您使用 TimerProc 而不是处理 WM_TIMER。

    来源:MSDN:SetTimer 函数

  3. 回调函数的原型不好。请参阅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;
    }
    

(Note this example program never ends, instead, real program should have some additional logic to do so by sending WM_QUIT).

(注意这个示例程序永远不会结束,相反,真正的程序应该有一些额外的逻辑来通过发送来做到这一点WM_QUIT)。

回答by qux

This can compile and run:

这可以编译和运行:

#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;
}

回答by Michael Haephrati

I found the best implementation to be as follow:

我发现最好的实现如下:

#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 

Then, as part of the main event loop:

然后,作为主事件循环的一部分:

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;