windows定时器

在DOS操作系统中要用到定时器功能的时候一般有两种方法:一是用一个空循环来延时;一是截获时钟中断,计算机的硬件时钟中断会以每55ms一次的频率触发8号中断,而在默认的int 08h中断处理程序中有一句int 1ch的代码,所以截获int 08h和int 1ch都可以达到定时的要求。

而在Windows操作系统中,用户程序不可能去截获时钟中断,而是使用定时器功能。

在应用程序中需要使用定时器时,可以用SetTimer函数向Windows申请一个定时器,要求系统在指定时间以后“通知”应用程序,如果申请成功,系统会以指定时间周期调用SetTimer函数指定的回调函数,或者向指定的窗口过程发送WM_TIMER消息,SetTimer函数可以指定的时间间隔以ms为单位,可以指定的时间周期为一个32位的整数,也就是从1~4294967295ms,(即232-1ms),这是一个将近50天的范围。

但在实际应用中,由于Windows的定时器是基于时钟中断的,所以虽然参数的单位ms,但精度是55ms,如果指定一个小于55ms的周期,Windows最快也只能在每个时钟中断的时候触发这个定时器,即实际上这个定时器是以55ms为触发周期的;另外,指定一个时间间隔时,Windows以与这个间隔最接近的55ms的整数倍时间来触发定时器。

由于定时器消息是一个低级别的消息,这表现在两方面:

1)Windows只有在消息队列中没有其他消息的情况下才会发送WM_TIMER消息,如果窗口过程忙于处理这个消息没有返回,使消息队列中有消息积累起来,那么WM_TIMER消息就会被丢弃,在消息队列空闲时,被丢弃的WM_TIMER消息不会补发;

2)消息队列中不会有多条WM_TIMER消息,如果消息队列中已经有一条WM_TIMER消息,还没来得及处理,又到了定时时刻,那么两条WM_TIMER消息会被合并成一条。

因此,应用程序不能依靠定时器来保证某件事情必须在规定的时刻被处理,另外,也不能依赖对定时器消息计数来确定已经过去了多长时间。

申请一个定时器使用SetTimer函数:

UINT_PTR WINAPI SetTimer(

__in_opt HWND hWnd, //WM_TIMER消息发往的窗口句柄

__in UINT_PTR nIDEvent, //用户指定的任意整数,用来标识一个程序中的多个定时器

__in UINT uElapse, //时间周期,以ms为单位

__in_opt TIMERPROC lpTimerFunc //定时器过程

);

如果定时器创建成功,返回的是定时器的标识符。

当在SetTimer中指定的定时器标识已经存在,则Windows会用新的参数代替旧的定时器参数,函数执行后,这个标识的定时器消息将以新的时间周期发送。

定时器过程定义如下:

VOID CALLBACK TimerProc(

__in HWND hwnd, //与定时器关联的窗口句柄

__in UINT uMsg, //总是WM_TIMER

__in UINT_PTR idEvent, //SetTimer返回的定时器标识符

__in DWORD dwTime //系统启动至今经过的ms数,该值是由函数GetTickCount返回的

);

撤销定时器的函数是KillTimer:

BOOL WINAPI KillTimer(

__in_opt HWND hWnd, // WM_TIMER消息发往的窗口句柄

__in UINT_PTR uIDEvent //用户指定的任意整数,用来标识一个程序中的多个定时器

);

使用SetTimer函数的方法有两种:

1)要求Windows将WM_TIMER消息发往指定的窗口过程,这时lpTimerProc必须为NULL;

例如如下:

HICON hIcon1; // icon handle

POINT ptOld; // previous cursor location

UINT uResult; // SetTimer's return value

HINSTANCE hinstance; // handle to current instance

//

// Perform application initialization here.

//

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

// Record the initial cursor position.

GetCursorPos(&ptOld);

// Set the timer for the mousetrap.

uResult = SetTimer(hwnd, // handle to main window

IDT_MOUSETRAP, // timer identifier

10000, // 10-second interval

(TIMERPROC) NULL); // no timer callback

if (uResult == 0)

{

ErrorHandler("No timer is available.");

}

LONG APIENTRY MainWndProc(

HWND hwnd, // handle to main window

UINT message, // type of message

WPARAM wParam, // additional information

LPARAM lParam) // additional information

{

HDC hdc; // handle to device context

POINT pt; // current cursor location

RECT rc; // location of minimized window

switch (message)

{

//

// Process other messages.

//

case WM_TIMER:

// If the window is minimized, compare the current

// cursor position with the one from 10 seconds

// earlier. If the cursor position has not changed,

// move the cursor to the icon.

if (IsIconic(hwnd))

{

GetCursorPos(&pt);

if ((pt.x == ptOld.x) && (pt.y == ptOld.y))

{

GetWindowRect(hwnd, &rc);

SetCursorPos(rc.left, rc.top);

}

else

{

ptOld.x = pt.x;

ptOld.y = pt.y;

}

}

return 0;

case WM_DESTROY:

// Destroy the timer.

KillTimer(hwnd, IDT_MOUSETRAP);

PostQuitMessage(0);

break;

//

// Process other messages.

//

}

2)要求Windows在时间到的时候调用指定的定时器过程,而不是窗口过程,那么只需要指定lpTimerFunc参数即可。

例子如下:

UINT uResult; // SetTimer's return value

HICON hIcon1; // icon handle

POINT ptOld; // previous cursor location

HINSTANCE hinstance; // handle to current instance

//

// Perform application initialization here.

//

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));

wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

// Record the current cursor position.

GetCursorPos(&ptOld);

// Set the timer for the mousetrap.

uResult = SetTimer(hwnd, // handle to main window

IDT_MOUSETRAP, // timer identifier

10000, // 10-second interval

(TIMERPROC) MyTimerProc); // timer callback

if (uResult == 0)

{

ErrorHandler("No timer is available.");

}

LONG APIENTRY MainWndProc(

HWND hwnd, // handle to main window

UINT message, // type of message

WPARAM wParam, // additional information

LPARAM lParam) // additional information

{

HDC hdc; // handle to device context

switch (message)

{

//

// Process other messages.

//

case WM_DESTROY:

// Destroy the timer.

KillTimer(hwnd, IDT_MOUSETRAP);

PostQuitMessage(0);

break;

//

// Process other messages.

//

}

// MyTimerProc is an application-defined callback function that

// processes WM_TIMER messages.

VOID CALLBACK MyTimerProc(

HWND hwnd, // handle to window for timer messages

UINT message, // WM_TIMER message

UINT idTimer, // timer identifier

DWORD dwTime) // current system time

{

RECT rc;

POINT pt;

// If the window is minimized, compare the current

// cursor position with the one from 10 seconds earlier.

// If the cursor position has not changed, move the

// cursor to the icon.

if (IsIconic(hwnd))

{

GetCursorPos(&pt);

if ((pt.x == ptOld.x) && (pt.y == ptOld.y))

{

GetWindowRect(hwnd, &rc);

SetCursorPos(rc.left, rc.top);

}

else

{

ptOld.x = pt.x;

ptOld.y = pt.y;

}

}

}

可等待定时器的相关内容见:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值