CreateWaitableTimer和SetWaitableTimer函数(转载)

用户感觉到软件的好用,就是可以定时地做一些工作,而不需要人参与进去。比如每天定时地升级病毒库,定时地下载电影,定时地更新游戏里的人物。要想实现这些功能,就可以使用定时器的API函数CreateWaitableTimer和SetWaitableTimer来实现了,这对API函数创建的时钟是比较精确的,可以达到100倍的10亿分之一秒。

函数CreateWaitableTimer和SetWaitableTimer声明如下:

WINBASEAPI
__out
HANDLE
WINAPI
CreateWaitableTimerA(
    __in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes,
    __in     BOOL bManualReset,
    __in_opt LPCSTR lpTimerName
    );
WINBASEAPI
__out
HANDLE
WINAPI
CreateWaitableTimerW(
    __in_opt LPSECURITY_ATTRIBUTES lpTimerAttributes,
    __in     BOOL bManualReset,
    __in_opt LPCWSTR lpTimerName
    );
#ifdef UNICODE
#define CreateWaitableTimer CreateWaitableTimerW
#else
#define CreateWaitableTimer CreateWaitableTimerA
#endif // !UNICODE


WINBASEAPI
BOOL
WINAPI
SetWaitableTimer(
    __in     HANDLE hTimer,
    __in     const LARGE_INTEGER *lpDueTime,
    __in     LONG lPeriod,
    __in_opt PTIMERAPCROUTINE pfnCompletionRoutine,
    __in_opt LPVOID lpArgToCompletionRoutine,
    __in     BOOL fResume
    );

lpTimerAttributes是设置定时器的属性。
bManualReset是是否手动复位。
lpTimerName是定时器的名称。
hTimer是定时器的句柄。
lpDueTime是设置定时器时间间隔,当设置为正值是绝对时间;当设置为负数是相对时间。
lPeriod是周期。
pfnCompletionRoutine是设置回调函数。
lpArgToCompletionRoutine是传送给回调函数的参数。
fResume是设置系统是否自动恢复。

调用函数的例子如下:
#001 //创建定时器
#002 //蔡军生 2007/11/06 QQ:9073204 深圳
#003 int CreateTestTimer(void)
#004 {
#005         HANDLE hTimer = NULL;
#006         LARGE_INTEGER liDueTime;
#007
#008         //设置相对时间为10秒。
#009         liDueTime.QuadPart = -100000000;
#010
#011         //创建定时器。
#012        hTimer = CreateWaitableTimer(NULL, TRUE, _T("TestWaitableTimer"));
#013         if (!hTimer)
#014         {              
#015               return 1;
#016         }
#017
#018         OutputDebugString(_T("10秒定时器/r/n"));
#019
#020         // 设置10秒钟。
#021        if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
#022         {        
#023               //
#024               CloseHandle(hTimer);
#025               return 2;
#026         }
#027
#028         //等定时器有信号。
#029         if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
#030         {
#031               OutputDebugString(_T("10秒定时器出错了/r/n"));   
#032               //
#033               CloseHandle(hTimer);
#034               return 3;
#035         }
#036         else
#037         {
#038               //10秒钟到达。
#039               OutputDebugString(_T("10秒定时器到了/r/n"));            
#040         }
#041
#042         //
#043         CloseHandle(hTimer);
#044         return 0;
#045 }

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caimouse/archive/2007/11/06/1870336.aspx

以下是贪吃蛇的C语言代码,使用了线程和定时器实现: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h> #define MAP_WIDTH 40 #define MAP_HEIGHT 20 #define SNAKE_INIT_LENGTH 3 #define SNAKE_MAX_LENGTH 100 // 定义方向 enum Direction { UP, DOWN, LEFT, RIGHT }; // 定义蛇的结构体 struct Snake { int x[SNAKE_MAX_LENGTH]; int y[SNAKE_MAX_LENGTH]; int length; enum Direction direction; }; // 定义食物的结构体 struct Food { int x; int y; }; // 定义地图 char map[MAP_HEIGHT][MAP_WIDTH]; // 定义蛇和食物 struct Snake snake; struct Food food; // 定义线程和定时器 HANDLE hTimer; HANDLE hThread; // 初始化地图 void init_map() { int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { if (i == 0 || i == MAP_HEIGHT - 1 || j == 0 || j == MAP_WIDTH - 1) map[i][j] = '#'; else map[i][j] = ' '; } } } // 初始化蛇 void init_snake() { int i; snake.length = SNAKE_INIT_LENGTH; snake.direction = RIGHT; for (i = 0; i < SNAKE_INIT_LENGTH; i++) { snake.x[i] = MAP_WIDTH / 2 - i; snake.y[i] = MAP_HEIGHT / 2; } } // 初始化食物 void init_food() { srand(time(NULL)); food.x = rand() % (MAP_WIDTH - 2) + 1; food.y = rand() % (MAP_HEIGHT - 2) + 1; } // 更新地图 void update_map() { int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { if (i == 0 || i == MAP_HEIGHT - 1 || j == 0 || j == MAP_WIDTH - 1) map[i][j] = '#'; else map[i][j] = ' '; } } for (i = 0; i < snake.length; i++) { map[snake.y[i]][snake.x[i]] = '*'; } map[food.y][food.x] = '@'; } // 控制蛇的移动 void move_snake() { int i; for (i = snake.length - 1; i > 0; i--) { snake.x[i] = snake.x[i - 1]; snake.y[i] = snake.y[i - 1]; } switch (snake.direction) { case UP: snake.y[0]--; break; case DOWN: snake.y[0]++; break; case LEFT: snake.x[0]--; break; case RIGHT: snake.x[0]++; break; } } // 判断蛇是否吃到食物 void eat_food() { if (snake.x[0] == food.x && snake.y[0] == food.y) { snake.length++; if (snake.length > SNAKE_MAX_LENGTH) snake.length = SNAKE_MAX_LENGTH; init_food(); } } // 判断蛇是否撞墙或者撞到自己 int is_dead() { int i; if (snake.x[0] == 0 || snake.x[0] == MAP_WIDTH - 1 || snake.y[0] == 0 || snake.y[0] == MAP_HEIGHT - 1) return 1; for (i = 1; i < snake.length; i++) { if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) return 1; } return 0; } // 游戏结束 void gameover() { printf("Game Over!\n"); printf("Press any key to continue...\n"); _getch(); exit(0); } // 控制蛇的方向 void control() { if (_kbhit()) { switch (_getch()) { case 'w': if (snake.direction != DOWN) snake.direction = UP; break; case 's': if (snake.direction != UP) snake.direction = DOWN; break; case 'a': if (snake.direction != RIGHT) snake.direction = LEFT; break; case 'd': if (snake.direction != LEFT) snake.direction = RIGHT; break; } } } // 定时器回调函数 VOID CALLBACK timer_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { move_snake(); eat_food(); update_map(); control(); if (is_dead()) gameover(); } // 线程函数 DWORD WINAPI thread_func(LPVOID lpParam) { while (1) { WaitForSingleObject(hTimer, INFINITE); } return 0; } // 主函数 int main() { init_map(); init_snake(); init_food(); update_map(); printf("Press any key to start...\n"); _getch(); hTimer = CreateWaitableTimer(NULL, FALSE, NULL); LARGE_INTEGER liDueTime; liDueTime.QuadPart = 0; SetWaitableTimer(hTimer, &liDueTime, 1000 / 10, timer_callback, NULL, FALSE); hThread = CreateThread(NULL, 0, thread_func, NULL, 0, NULL); while (1) { system("cls"); int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { printf("%c", map[i][j]); } printf("\n"); } Sleep(1000 / 10); } return 0; } ``` 上面的代码中,使用了定时器和线程来控制蛇的移动和游戏的进行。其中,定时器用来定时调用回调函数,线程用来等待定时器的信号。回调函数中包含了蛇的移动、吃食物、更新地图、控制方向等逻辑,线程函数中输出地图并等待定时器的信号。通过这种方式,可以实现一个简单的贪吃蛇游戏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值