分享

VC++实现非窗口类中使用定时器的方法

 9loong 2010-09-24
http://www./dev/vc/2009-11-15/a09119886.shtml

VC++实现非窗口类中使用定时器的方法(图)

更新时间:2009-11-15 02:31:36

   定时器在Windows 的程序中的作用不可忽略,也随处可见。设定一个时间间隔每0.5秒或者1秒钟刷新一次时钟,这样就可以完成一个简单的电子钟程序。在不同的编程工具中定时器的用法也不同,Visual C++中也给我们提供了实现这种功能的方法,而且方法不只一种。在窗口类中是使用定时器比较很简单,用SetTimer()设置了定时器之后,并在Class Wizard中添加了WM_TIMER消息映射后,您就可以在映射函数OnTimer()中添加代码实现,来定时完成您的任务,而且还支持任意多个定时器,这种方法大家可能都会用。但是在非窗口的类中,使用定时器就没那么简单了,在类消息映射中就找不到OnTimer()方法了,类中也没有hWnd这个属性,SetTimer()也不能象原来那样使用了,下面给出了一种既不破坏类的完整性的同时又能巧妙的使用定时器的方法。程序运行后的界面效果如图一所示:


图一、定时器界面效果图

  实现方法

  在非窗口类中使用定时器,需要了解的知识比较多。首先非窗口类中没有消息映射,也没有象CWnd类具有的SetTimer()方法来设置定时器。没有消息映射,就只能靠我们自己定义的回调函数来处理定时器的消息,因此大家有必要了解一下回调函数的概念。因为回调函数只能用全局函数或者静态成员函数来实现,而为了维持类的完整性,又要求使用类的静态成员函数来作为回调函数。又因为定时器是在我们的程序中产生的,这又需要来管理定时器,所以又用到了映射表类CMap。

      程序代码
            CMyTimer,该类的作用是每隔一段时间提醒我们做某件事情,然后用这个类创建N个实例,每个实例以不同的时间间隔提醒我们做不同的事情。
/////////////////////////////////////////// MyTimer.h: interface for the CMyTimer class.
#if !defined(AFX_MYTIMER_H__D97674D1_B221_49CD_9637_4CBA8C3180CE__INCLUDED_)
#define AFX_MYTIMER_H__D97674D1_B221_49CD_9637_4CBA8C3180CE__INCLUDED_
#include <afxtempl.h>
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMyTimer;
typedef CMap<UINT,UINT,CMyTimer*,CMyTimer*> CTimerMap;
class CMyTimer
{
 public:
  //设置定时器,nElapse表示时间间隔,sz表示要提示的内容
  void SetMyTimer(UINT nElapse,CString sz);
  //销毁该实例的定时器
  void KillMyTimer();
  //保存该实例的定时器标志值
  UINT m_nTimerID;
  //静态数据成员要提示的内容
  CString szContent;
  //静态数据成员,映射表类,用于保存所有的定时器信息
  static CTimerMap m_sTimeMap;
  //静态成员函数,用于处理定时器的消息
  static void CALLBACK MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);

  CMyTimer();
  virtual ~CMyTimer();
};
#endif

///////////////////////////////////// MyTimer.cpp: implementation of the CMyTimer class.
#include "stdafx.h"
#include "TimerDemo.h"
#include "MyTimer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CTimerMap CMyTimer::m_sTimeMap;

CMyTimer::CMyTimer()
{
 m_nTimerID = 0;
}

CMyTimer::~CMyTimer()
{}

void CALLBACK CMyTimer::MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
 CString sz;
 sz.Format("%d号定时器:%s",idEvent,m_sTimeMap[idEvent]->szContent);
 AfxMessageBox(sz);
}

void CMyTimer::SetMyTimer(UINT nElapse,CString sz)
{
 szContent = sz;
 m_nTimerID = SetTimer(NULL,NULL,nElapse,MyTimerProc);
 m_sTimeMap[m_nTimerID] = this;
}

void CMyTimer::KillMyTimer()
{
 KillTimer(NULL,m_nTimerID);
 m_sTimeMap.RemoveKey(m_nTimerID);
}



(#)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多