該死的回調函數

MMRESULT timeSetEvent( UINT uDelay, 
                                 UINT uResolution, 
                                 LPTIMECALLBACK lpTimeProc, 
                                 WORD dwUser, 
                                 UINT fuEvent )

        uDelay:以毫秒指定事件的週期。
         Uresolution:以毫秒指定延時的精度,數值越小定時器事件分辨率越高。缺省值爲1ms。
         LpTimeProc:指向一個回調函數。
         DwUser:存放用戶提供的回調數據。
         FuEvent:指定定時器事件類型:
         TIME_ONESHOT:uDelay毫秒後只產生一次事件

         TIME_PERIODIC :每隔uDelay毫秒週期性地產生事件。

該函數的參數說明如下:

uDelay表示延遲時間;

uResolution表示時間精度,在Windows中缺省值爲1ms;

lpTimeProc表示回調函數,爲用戶自定義函數,定時調用; 

dwUser表示用戶提供的回調數據;

參數fuEvent爲定時器的事件類型,TIME_ONESHOT表示執行一次;TIME_PERIODIC:週期性執行。

具體應用時,可以通過調用timeSetEvent()函數,將需要週期性執行的任務定義在lpTimeProc回調函數中(如:定時採樣、控制等),從而完成所需處理的事件。需要注意的是:任務處理的時間不能大於週期間隔時間。另外,在定時器使用完畢後,應及時調用timeKillEvent()將之釋放。

以下代碼從這個鏈接複製來:http://blog.sina.com.cn/s/blog_605b4e400100tlg5.html,沒有用的,或者說註釋掉沒有影響的頭文件我給註釋了

//#include "stdafx.h"//這句好像是Visual Studio 的預編譯頭文件

#include <stdio.h>
#include <windows.h>
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")

 MMRESULT timer_id;
void CALLBACK onTimeFunc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2);
void main()
{
    int n = 0;
    timer_id = timeSetEvent(5000, 1, (LPTIMECALLBACK)onTimeFunc, DWORD(1), TIME_PERIODIC);
    if(NULL == timer_id)
    {
        printf("timeSetEvent() failed with error %dn", GetLastError());
exit(0);
    }
    while(n<5)
    {
        printf("Hello World!\n");
        Sleep(2000);
        n++;
    }
    timeKillEvent(timer_id);        //釋放定時器
}
void CALLBACK onTimeFunc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
{
    printf("time out\n");
    return;
}

通過對上面的代碼的修改,好像對回調函數有了一點了解,趕快記下來。

上面的代碼運行結果如下:



本人的疑惑是timeSetEvent函數在調用回調函數時,是一定要時間操作的參與還是循環的參與?所以就分別把循環和Sleep()函數註釋掉,同時把uDelay從5000改爲1000

  /*while(n<5)
    {*/
        printf("Hello World!\n");
        Sleep(2000);
  /*      n++;
    }*/


而註釋掉Sleep()函數之後結果如下:



說明與時間操作(Sleep函數)有關,和循環沒必然聯繫。

還有一點要說明,

void CALLBACK onTimeFunc(UINT wTimerID, UINT msg,DWORD dwUser,DWORD dwl,DWORD dw2)
{
    printf("time out\n");
    timer_id = timeSetEvent(5000, 1, (LPTIMECALLBACK)onTimeFunc, DWORD(1), TIME_PERIODIC);
    return;
}

在回調函數中調用自己,本例中時通過timeSetEvent,這算不算遞歸呢?答案是:不算。從結果看,回調函數被多次調用,但是不是遞歸.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章