VC++默认的定时器,好像精度不大,秒内的不错,但是如果精确到毫秒(ms),不行,如果使用媒体定时器,multimedia timer,则效果显著,基本上精确到毫秒吧,一般的10ms之类的延时,应该可以保证了。
如何使用呢?网上有例子,但没有完整的,大部分只是介绍,因此我根据网上的代码实现了一下,使用MFC实现,可以在下面的链接下载下来学习与研究。
可能通过MSDN找到操作媒体定时器(multimedia timer)的相关介绍,主要的操作函数:
(1)timeSetEvent设置定时器(配置并开启)
(2)timeKillEvent关闭定时器
(3)CALLBACK TimerCallBack也可回调函数,(定时器中断了,要执行的函数),名字可以随便起,只是格式上,要符合标准的格式。
(4)OnMMTimer 具体的实现函数:网上是定义为虚函数,然后重写,这里我觉得随便取个名字应该可以,就是用定时器干什么,延时到了,用户要实现什么功能,可以写在这里。上面第三个函数就调用这个函数进行用户程序的实现。
(1)首先工程中要加入头文件:
#include "windows.h"
#include "Mmsystem.h"
(2)设置工程选项:加入Winmm.lib 库,这是使用媒体定时器的库。
界面如下:
对话框类的成员函数与成员变量:
public:
UINT m_ms;//毫秒,注意在构造函数里初始化为0
UINT m_timerId;
UINT m_s;
UINT m_m;
UINT m_h;
virtual void OnMMTimer();//声明要回调的成员方法
void TimerCtrl(const bool bEn);//定时器打开与关闭
int i;
MMRESULT TimerID;//媒体定时器的ID,标识
-
void CTimeSetEvent_V1Dlg::OnBtnTimerStart()
-
{
-
// TODO: Add your control notification handler code here
-
TimerCtrl(TRUE);
-
GetDlgItem(IDC_BTN_TIMER_START)->EnableWindow(FALSE);
-
GetDlgItem(IDC_BTN_TIMER_STOP)->EnableWindow(TRUE);
-
}
-
-
void CTimeSetEvent_V1Dlg::OnBtnTimerStop()
-
{
-
// TODO: Add your control notification handler code here
-
TimerCtrl(FALSE);
-
GetDlgItem(IDC_BTN_TIMER_START)->EnableWindow(TRUE);
-
GetDlgItem(IDC_BTN_TIMER_STOP)->EnableWindow(FALSE);
-
}
-
-
void CTimeSetEvent_V1Dlg::OnMMTimer()
-
{
-
CString str = "";
-
m_ms++;
-
str.Format("%ld",m_ms);
-
str+="";
-
SetDlgItemTextA(IDC_STATIC_MS,str);
-
CEdit *pEt = (CEdit *)GetDlgItem(IDC_EDIT_HIST);
-
int nLen=pEt->GetWindowTextLength();
-
pEt->SetSel(nLen,nLen);
-
pEt->ReplaceSel(str);
-
//GetDlgItem(IDC_EDIT_HIST)->
-
}
-
-
void CTimeSetEvent_V1Dlg::TimerCtrl(const bool bEn)
-
{
-
if (bEn)
-
{
-
m_h = m_m = m_s = 0;
-
m_timerId = timeSetEvent(1,1,&TimerCallBack,(DWORD)this,TIME_PERIODIC);
-
}
-
else
-
timeKillEvent(m_timerId);
-
}
-
-
void CTimeSetEvent_V1Dlg::OnOK()
-
{
-
// TODO: Add extra validation here
-
GetDlgItem(IDC_EDIT_HIST)->SetWindowText("");
-
m_ms=0;
-
//CDialog::OnOK();
-
}
-
-
void CTimeSetEvent_V1Dlg::OnCancel()
-
{
-
// TODO: Add extra cleanup here
-
-
CDialog::OnCancel();
-
}
-
static void CALLBACK TimerCallBack(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
-
{
-
CTimeSetEvent_V1Dlg * pThis=(CTimeSetEvent_V1Dlg *)dwUser;//由this指针获得实例的指针
-
-
pThis->OnMMTimer(); //调用要回调的成员方法
-
}
-
-
/////////////////////////////////////////////////////////////////////////////
-
// CTimeSetEvent_V1Dlg dialog
-
-
CTimeSetEvent_V1Dlg::CTimeSetEvent_V1Dlg(CWnd* pParent /*=NULL*/)
-
: CDialog(CTimeSetEvent_V1Dlg::IDD, pParent)
-
{
-
//{{AFX_DATA_INIT(CTimeSetEvent_V1Dlg)
-
// NOTE: the ClassWizard will add member initialization here
-
//}}AFX_DATA_INIT
-
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
-
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
-
m_ms=0;
-
m_s=0;
-
m_m=0;
-
m_h=0;
-
}
以上为主要的函数实现功能。
目前只是打印出数字来,证明定时器中断可以用,当然,如果设置什么数据发送,如1S中发送100次或是200次,也可以加入。
VC6工程下载:
TimeSetEvent_V1.zip
阅读(2329) | 评论(0) | 转发(0) |