• 关于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 );
    }
  • 相关阅读:
    后台http请求参数为json 【转】
    【转】java获取当前年、月、日 、小时 、分钟、 秒、 毫秒
    java 增强for循环对于空集和null的判断
    jquery中对地址中的中文进行encodeURI编码
    System.arraycopy() 数组复制方法
    增强for循环的简单总结
    【转载】oracle中decode函数用法
    【转载】用jquery给select option 赋值
    【转载】execute、executeUpdate、executeQuery三者的区别(及返回值)
    小程序table正确姿势
  • 原文地址:https://www.cnblogs.com/zdxster/p/1945888.html
Copyright © 2020-2023  润新知