SetTimer 與回調函數


在控制台應用程序中,SetTimer的函數原型為:

UINT_PTR SetTimer(
  HWND hWnd,              // handle to window
  UINT_PTR nIDEvent,      // timer identifier
  UINT uElapse,           // time-out value
  TIMERPROC lpTimerFunc   // timer procedure
);


具體的解釋可以看MSDN,主要是第四個參數,定義的參數類型為 TIMERPROC
VOID CALLBACK TimerProc(
  HWND hwnd,         // handle to window
  UINT uMsg,         // WM_TIMER message
  UINT_PTR idEvent,  // timer identifier
  DWORD dwTime   // current system time
);

怎樣在控制台應用程序中定義自己的回調函數呢?

回調函數說白了就是 事件 響應程序,Windows的每個消息可以理解為一個事件,事件的響應代碼要由用戶自己來定義。用戶定義了事件響應的代碼,但還要Windows知道這段代碼的位置(要不然Windows就不知道如何去調用,這也沒有用),於是用戶需要將回調函數的指針告訴Windows,最典型的例子是在窗口類的結構(WNDCLASS)中給lpfnWndProc分量賦回調函數指針值。    回調函數的參數格式是由回調函數的調用者(一般是Windows)來定義的,而回調函數的實現者必須遵循這種格式。Windows程序是以事件驅動模型為基礎的,這就必然要用到回調函數這種機制。

        如果有時間,不妨看看MESSAGE_MAP宏,消息映射是回調函數,只是這種回調函數的用法不同而已。普通的回調函數是要你提供地址,傳進某個函數,由它去調用;而消息映射函數,卻是由你定義函數,由MESSAGE_MAP宏去取得地址,並實現它的調用。

        回調函數是一個程序員不能顯式調用的函數;通過將回調函數的地址傳給調用者從而實現調用。要實現回調,必須首先定義函數指針。盡管定義的語法有點不可思議,但如果你熟悉函數聲明的一般方法,便會發現函數指針的聲明與函數聲明非常類似。

      

typedef void ( *f1 ) (       );// 為函數指針聲明類型定義
void ( *p ) (   ); //p是指向某函數的指針

//定義一個函數
void func1() 

 /* do something */
 printf("From func1(), Hello World!/n");
}

//定義一個調用函數指針的回調函數

void caller(     void(*ptrfunc1)(   )    )
{
 ptrfunc1(    ); /* 調用ptr指向的函數 */ 
}

//typedef bool (*f2) (int *);// 為函數指針聲明類型定義
//bool (*q) (int *); //p是指向某函數的指針

bool func2(int* t_i) 
{
 printf("From func2() = %d, Hello World!/n", (*t_i)++);
 return true;
}

void caller2    (   bool (*ptrfunc2)(int *),       int * i      )
{
 ptrfunc2(i); /* 調用ptr指向的函數 */ 
}


int main(int argc, char* argv[])
{
 printf("From main(), Hello World!/n");
 printf("/n");

 //無參數調用
 p = func1; /* 傳遞函數地址地址 */
 caller(p); /* 傳遞函數地址到調用者 */

 //有參數調用
 int i = 0; 
 for (int j = 0; j < 10; j++)
 {
  caller2(func2, &i); //* 傳遞函數地址到調用者 */
 }

 //有參數調用第二次

  i = 0;
 //q = func2; /* 傳遞函數地址地址 */
 //caller2(q, &i); /* 傳遞函數地址到調用者 */

 printf("/n");
 printf("From main(), Hello World!/n");

 getchar();

 return 0;
}

我們以在控制台中定義一個SetTimer函數為例子,見如下代碼:

 

#include <iostream>
#include <windows.h>
using namespace std;

 

VOID CALLBACK Func(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
{
MessageBox(NULL,"Hello","ALARM",1);
}

 


void main()
{

MSG msg;
SetTimer(NULL,1,1000, (TIMERPROC)Func);
while( GetMessage(&msg,NULL,NULL,NULL))
{
if (msg.message == WM_TIMER)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}
}

 

剛開始的時候以為不用設置消息循環,所以沒有寫循環,才出現了各種錯誤。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM