博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SetTimer 与回调函数
阅读量:6219 次
发布时间:2019-06-21

本文共 2269 字,大约阅读时间需要 7 分钟。

在控制台应用程序中,SetTimer的函数原型为:

UINT_PTR SetTimer(  HWND ,              // handle to window  UINT_PTR ,      // timer identifier  UINT ,           // time-out value  TIMERPROC    // timer procedure); 具体的解释可以看MSDN,主要是第四个参数,定义的参数类型为 TIMERPROC
VOID CALLBACK TimerProc(  HWND ,         // handle to window  UINT ,         // WM_TIMER message  UINT_PTR ,  // timer identifier  DWORD    // 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);
}
}
}

 

刚开始的时候以为不用设置消息循环,所以没有写循环,才出现了各种错误。

 

 

转载地址:http://wwoja.baihongyu.com/

你可能感兴趣的文章
2018百度之星资格赛A B F
查看>>
App 卸载记录
查看>>
Chisel3 - util - BitPat
查看>>
多线程
查看>>
【题解】【BT】【Leetcode】Populating Next Right Pointers in Each Node
查看>>
python 判断101-200之间有多少个素数,并输出所有素数。
查看>>
[转载]position的四个属性值: relative ,absolute ,fixed,static
查看>>
韬晦术
查看>>
DirectX 12 API
查看>>
在函数形参表中,允许不给出形参数组的长度,或用一个变量来表示数组元素...
查看>>
TCAM 与CAM
查看>>
Hibernate_day03--Hibernate多对多操作
查看>>
MVVM: 通过 x:Bind 实现 MVVM(不用 Command)
查看>>
java 左移 右移
查看>>
subline text 3快捷键
查看>>
Cordova 和 React-Native对比
查看>>
leetcode621
查看>>
时间过滤器
查看>>
ATM+购物商城(第一版)
查看>>
Android 音量键拦截
查看>>