zoukankan      html  css  js  c++  java
  • 关于VC中的定时器

    写VC程序时碰到一个定时器的问题,说明一下。

    SetTimer函数用于创建一个计时器,KillTimer函数用于销毁一个计时器。计时器属于系统资源,使用完应及时销毁。
    SetTimer的函数原型如下:
    UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse,
    TIMERPROC lpTimerFunc ) ;

    其中
    hWnd是和timer关联的窗口句柄,此窗口必须为调用SetTimer的线程所有;如果hWnd为NULL,没有窗口和timer相关联并且nIDEvent参数被忽略
    nIDEvent是timer的标识,为非零值;如果hWnd为NULL则被忽略;如果hWnd非NULL而且与timer相关联的窗口已经存在一个为此 标识的timer,则此次SetTimer调用将用新的timer代替原来的timer。timer标识和窗口相关,两个不同的窗口可以拥有 nIDEvent相同的tiemr
    uElapse是以毫秒指定的计时间隔值,范围为1毫秒到4,294,967,295毫秒(将近50天),这个值指示Windows每隔多久时间给程序发送WM_TIMER消息。
    lpTimerFunc是一个回调函数的指针,俗称TimerFunc;如果lpTimerFunc为NULL,系统将向应用程序队列发送 WM_TIMER消息;如果lpTimerFunc指定了一个值,DefWindowProc将在处理WM_TIMER消息时调用这个 lpTimerFunc所指向的回调函数,因此即使使用TimerProc代替处理WM_TIMER也需要向窗口分发消息。

    关于SetTimer的返回值:如果hWnd为NULL,返回值为新建立的timer的ID,如果hWnd非NULL,返回一个非0整数,如果SetTimer调用失败则返回0 。
    我们一般用要是是CWnd::SetTimer,然后在响应WM_TIMER消息的OnTimer函数中实现定时器的操作就可以了。但是在非MFC的程序 中,用上述的::SetTimer定时调用类自身的函数该怎么办呢?由于CALLBACK函数是static的,不能在其中直接调用类成员函数。一般给出 的方法是利用::SetTimer的第二个参数UINT_PTR nIDEvent传入this指针,第四个参数传入CALLBACK回调函数的地址;然后在CALLBACK函数中利用this调用自身的成员函数。
    例:
    假设有类 class TimerEg , 在头文件中定义如下函数
    void timer_fun( HWND hwnd, UINT message, UINT_PTR idTimer,
    DWORD dwTime );
    static VOID CALLBACK timer_proc( HWND hwnd, UINT message,
    UINT_PTR idTimer, DWORD dwTime );
    在cpp文件中添加如下代码
    {
    UINT nTimer = ::SetTimer( NULL, ( UINT_PTR )this,
    time_interval * 100, ( TIMERPROC )&timer_proc);
    }
    VOID TimerEg::timer_proc( HWND hwnd, UINT message,
    UINT_PTR idTimer,DWORD dwTime)
    {
    TimerEg * pthis = (TimerEg * )dwUser;
    pthis->timer_fun(…… );
    }
    void TimerEg::timer_fun(HWND hwnd, UINT message,
    UINT_PTR idTimer, DWORD dwTime )
    {}
    注意,这样做理论上是成立,可我试过很多次就是不调用timer_proc函数!!!最后,没办法了,换了两个实现定时器的函数,以timeSetEventtimeKillEnent来代替SetTimer及KillTimer,关于这两个函数的定义大家可去MSDN中去查找,这里不详述了;下面给出改动后的例子,注意各函数的参数变化及this指针的传递:
    在头文件中定义如下函数
    void timer_fun( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser,
    DWORD_PTR dw1,DWORD_PTR dw2 );
    static VOID CALLBACK timer_proc( UINT uTimerID, UINT uMsg,
    DWORD_PTR dwUser,DWORD_PTR dw1, DWORD_PTR dw2 );
    在cpp文件中添加如下代码
    {
    UINT nTimer = ::timeSetEvent( time_interval * 1000, 100,
    ( LPTIMECALLBACK ) timer_proc,
    ( DWORD_PTR )this, TIME_PERIODIC );
    }
    VOID TimerEg::timer_proc( UINT uTimerID, UINT uMsg,
    DWORD_PTR dwUser, DWORD_PTR dw1,
    DWORD_PTR dw2 )
    {
    TimerEg * pthis = (TimerEg * )dwUser;
    pthis->timer_fun( uTimerID, uMsg, dwUser, dw1, dw2 );
    }
    void TimerEg::timer_fun( UINT uTimerID, UINT uMsg, DWORD_PTR dwUser,
    DWORD_PTR dw1, DWORD_PTR dw2 )
    {}
    {
    ::timeKillEvent( nTiimer );
    }
  • 相关阅读:
    A1023 Have Fun with Numbers (20分)(大整数四则运算)
    A1096 Consecutive Factors (20分)(质数分解)
    A1078 Hashing (25分)(哈希表、平方探测法)
    A1015 Reversible Primes (20分)(素数判断,进制转换)
    A1081 Rational Sum (20分)
    A1088 Rational Arithmetic (20分)
    A1049 Counting Ones (30分)
    A1008 Elevator (20分)
    A1059 Prime Factors (25分)
    A1155 Heap Paths (30分)
  • 原文地址:https://www.cnblogs.com/zdxster/p/1945888.html
Copyright © 2011-2022 走看看