MFC定时器.docx

上传人:b****5 文档编号:5013307 上传时间:2022-12-12 格式:DOCX 页数:14 大小:23.75KB
下载 相关 举报
MFC定时器.docx_第1页
第1页 / 共14页
MFC定时器.docx_第2页
第2页 / 共14页
MFC定时器.docx_第3页
第3页 / 共14页
MFC定时器.docx_第4页
第4页 / 共14页
MFC定时器.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

MFC定时器.docx

《MFC定时器.docx》由会员分享,可在线阅读,更多相关《MFC定时器.docx(14页珍藏版)》请在冰豆网上搜索。

MFC定时器.docx

MFC定时器

MFC定时器

在程序中我们经常要使用定时刷新的功能,典型的应用是在信息管理系统中表单要跟着数据库中的数据变动。

MFC提供了定时器来完成这个功能。

=========================================================================

在MFC中和定时器相关的有三个函数:

UINTSetTimer(UINTnIDEvent,UINTnElapse,void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD));

afx_msgvoidOnTimer(UINTnIDEvent);

BOOLKillTimer(intnIDEvent);

 

=========================================================================

参数说明:

UINTnIDEvent:

定时器的ID,给定时器唯一的身份验证,如果在一个程序中有多个定时器可以用这个ID来确定是那个定时器发送的消息。

UINTnElapse:

定义刷新时间,即间隔多长时间刷新一次,单位是毫秒。

void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD):

             这个回调函数中实现刷新时所做的操作,如在数据库中读取数据。

但是我们大多数时候不在这里实现,而是在OnTimer中。

=========================================================================

函数功能:

SetTimer用来定义一个定时器的属性,如改定时器的ID,刷新时间,处理函数。

OnTimer实际时系统定义消息用来响应WM_TIMER消息,在这里可以实现对多定时器中的各个定时器分别响应,这里才时定时程序大展宏图的地方。

KillTimer用来结束一个定时器。

下面我们用一个例子来说明定时器的使用:

  这个例子用来实现一个简单的功能,就是在一个单文档程序中,每间隔5秒弹出一个消息框提示“定时器1”,每隔7秒弹出一个消息框提示“定时器2”。

  建立单文档程序略,一路Next。

=========================================================================

(1)在resource.h中定义两个定时器的ID

#defineIDTIMER1 1

#defineIDTIMER2 2

 

(2)在CMainFrame的OnCreate函数中定义两个定时器的属性。

SetTimer(TIMEID1,5000,0);

SetTimer(TIMEID2,7000,0);

 

(3)CMainFrame中对WM_TIMER进行响应。

oidCMainFrame:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

switch(nIDEvent){

caseTIMEID1:

{

AfxMessageBox("定时器1!

");

break;

}

caseTIMEID2:

{

AfxMessageBox("定时器2!

");

break;

}

default:

;

}

CFrameWnd:

:

OnTimer(nIDEvent);

}

 

(4)在CMainFrame的析构函数中添加

KillTimer(IDTIMER1);

KillTimer(IDTIMER2);

==============================

参考2

 

当执行到程序的某一行代码时,需要添加计时器,就用这条语句:

SetTimer(1,1000,NULL);

参数如下:

UINT_PTRSetTimer(UINT_PTRnIDEvent,UINTnElapse,

  void(CALLBACK*lpfnTimer)(HWND,UINT,UINT_PTR,DWORD));

设置好后计时器立马生效,1秒后计时器发生中断,在代码所在的类中进行捕捉:

1.在该类的消息中添加:

BEGIN_MESSAGE_MAP(CTab1,CDialog)//CTab1是自己定义的一个类

...

ON_WM_TIMER()

...

END_MESSAGE_MAP()

 

2.所在的类中添加成员函数:

voidOnTimer(UINT_PTRnIDEvent);

 

 

3.添加函数的代码,即捕捉后的执行代码:

voidCTab1:

:

OnTimer(UINT_PTRnIDEvent)

{

switch(nIDEvent)

{

case1:

//计时器1

....//处理的代码

KillTimer

(1);//删除此计时器,否则计时器中断完后会自动重新开始计时,到下一次中断时还会发生新的中断

break;

case2:

//计时器2

....//处理的代码

break;

default:

MessageBox("default:

KillTimer");

KillTimer(nIDEvent);

break;

}

}

MFC 定时触发器 实现循环给指定线程进行发送消息

//头文件

#include"StdAfx.h"

#include"ATPC.h"

#include"TWinApp.h"

#include"MainWindow.h"

#include"TWndAttrs.h"

#include"TWinThread.h"

//窗体拖动的宏的定义

#defineSC_DRAGMOVE(0xf012)

CMainWindow:

:

CMainWindow()

{

}

CMainWindow:

:

~CMainWindow(void)

{

 m_wndAttrs.Destory();

}

//获得桌面的位置参数

voidCMainWindow:

:

GetWindowPos(RECT&_in_out_rect)

{

 :

:

GetWindowRect(:

:

GetDesktopWindow(),&_in_out_rect);

 LONGnWidth =_in_out_rect.right-_in_out_rect.left;

 LONGnHight=_in_out_rect.bottom-_in_out_rect.top;

 _in_out_rect.left=0;

 _in_out_rect.top=0;

 _in_out_rect.right=nWidth/4;

 _in_out_rect.bottom=nHight*2/3;

}

//创建主窗体

BOOLCMainWindow:

:

MainWindowInit()

{

 m_pThread.CreateThread();//启动主线程通过拦截系统时间消息进行相关处理

 RECTrect={0};

 GetWindowPos(rect);//参数引用,获得参数值的传递

 LPTWINDOWPROPERTIESpWndProperty=m_wndAttrs.GetWindowProperty(CTWndAttrs:

:

E_WND_ID_MAINWND);

 if(NULL==pWndProperty ||

  false==CMainWindow:

:

Create(pWndProperty->lpszClass,pWndProperty->lpszName,\

          pWndProperty->style,rect,NULL,\

          pWndProperty->lpszMenu,pWndProperty->dwExStyle,NULL))//构造函数直接进行窗口的创建

 {

  _tprintf(_T("CMainWindow:

:

Createfalse\r\n"));

  returnfalse;

 }

 this->SetTimer(0x11223344,2000,NULL);//触发一个定时器,每到这个时间段就会发送一个ON_WM_TIMER,然后拦截进行处理

 returntrue;

}

//创建自己的消息映射表(放在类的实现进行定义拦截消息的)

BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)

 ON_WM_MOVE()

 ON_WM_CLOSE()

 ON_WM_TIMER()

 ON_WM_CREATE()

 ON_WM_CTLCOLOR()

 ON_WM_ERASEBKGND()

 ON_WM_SYSCOMMAND()

 //ON_MESSAGE(WM_USER_THREADEND,OnMyMess)//添加的消息映射

 //ON_COMMAND()

END_MESSAGE_MAP()

//处理单击关闭标题后的工作

voidCMainWindow:

:

OnClose()

{

 :

:

DestroyWindow(m_hWnd);//销毁活动的窗口(参数是获得当前活动窗口的句柄)

 ExitThread(0);

}

//在主窗体基础上进行控件的创建

intCMainWindow:

:

OnCreate(LPCREATESTRUCTlpcreatestruct)

{

 LPTWINDOWPROPERTIESpWndproperty=m_wndAttrs.GetWindowProperty(CTWndAttrs:

:

E_WND_ID_LISTBOX);

   

 RECTrect={0};

 GetClientRect(&rect);

 

 if(NULL==pWndproperty||false==m_listbox.Create(pWndproperty->style,CRect(rect),this,pWndproperty->id))

 {

  returnfalse;

 }

 

 for(inti=0;i<50;++i)

 {

  m_listbox.AddString(_T("TESTTESTTESTTESTTESTTESTTESTTESTTEST"));

  m_listbox.AddString(_T("山东科技大学"));

 }

 returntrue;

 //returnCFrameWnd:

:

OnCreate(lpcreatestruct);//并不是非要返回父类的成员函数OnCreate

}

//修改主窗体控件背景的颜色

BOOLCMainWindow:

:

OnEraseBkgnd(CDC*pDC)

{

 returnCFrameWnd:

:

OnEraseBkgnd(pDC);

}

//设置控件的背景颜色和文本颜色

HBRUSHCMainWindow:

:

OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)

{

 if(CTLCOLOR_LISTBOX==nCtlColor&&pWnd==&m_listbox)

 {

  LPTWINDOWPROPERTIESpWndProperty=m_wndAttrs.GetWindowProperty(CTWndAttrs:

:

E_WND_ID_LISTBOX);

  if(pWndProperty)

  {

   pDC->SetTextColor(pWndProperty->colors[E_WND_COLOR_TEXT]);

   pDC->SetBkColor(pWndProperty->colors[E_WND_COLOR_BACKGROUND]);

   pDC->SetBkMode(OPAQUE);

   return:

:

CreateSolidBrush(pWndProperty->colors[E_WND_COLOR_BACKGROUND]);

  }

 }

 returnCFrameWnd:

:

OnCtlColor(pDC,pWnd,nCtlColor);//其实不返回父类,也可以成功创建窗口控件                                            

}

//拦截系统消息WM_SYSCOMMAND进行处理窗体的移动禁止

voidCMainWindow:

:

OnSysCommand(UINTnID,LPARAMlParam)

{

 if( SC_DRAGMOVE!

=nID)

 {

  CFrameWnd:

:

OnSysCommand(nID,lParam);

 }

}

//拦截系统时间消息进行处理

voidCMainWindow:

:

OnTimer(UINT_PTRnIDEvent)

{

 staticUINT_PTRevt=WM_USER+0;//用户信息的定义使用的是WM_USER+X(整数值)

 if(0x11223344==nIDEvent)

 {

  this->KillTimer(0x11223344);

  

  BOOLret=:

:

PostThreadMessage(m_pThread.m_nThreadID,evt++,0,0);//把消息传送到指定ID的线程,不等待线程对消息的处理就会立即返回

  if(!

ret)

  {

   DWORDerr=GetLastError();//获得的具体的出错信息

   LPVOIDlpMsgBuf;//空类型指针

   :

:

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,

       NULL,err,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),//Defaultlanguage

       (LPTSTR)&lpMsgBuf,0,NULL);//获得err系统消息的ID来找到具体的消息的含义,然后首地址返回到空指针lpMsgBuf

   OutputDebugString((LPCWSTR)lpMsgBuf);

  }

  this->SetTimer(0x11223344,5000,NULL);

 }

}

VC++-SetTimer定时器  

首先:

SetTimer()是MFC中使用的,如果是MFC工程,则直接使用即可。

在控制台程序中需要包含:

#include

如果您需要在整个程序执行期间都使用定时器,那么您将得从WinMain函数中或者在处理WM_CREATE消息时呼叫SetTimer,并在退出WinMain或响应WM_DESTROY消息时呼叫KillTimer。

根据呼叫SetTimer时使用的参数,可以下列三种方法之一使用定时器。

方法一

这是最方便的一种方法,它让Windows把WM_TIMER消息发送到应用程序的正常窗口消息处理程序中,SetTimer呼叫如下所示:

SetTimer (hwnd,1,uiMsecInterval,NULL);       

第一个参数是其窗口消息处理程序将接收WM_TIMER消息的窗口句柄。

第二个参数是定时器ID,它是一个非0数值,在整个例子中假定为1。

第三个参数是一个32位无正负号整数,以毫秒为单位指定一个时间间隔,一个60,000的值将使Windows每分钟发送一次WM_TIMER消息。

注:

您可以通过呼叫KillTimer(hwnd,1);移除定时器。

第一个参数:

与定时器相关联的窗口句柄。

第二个参数:

定时器标识符。

方法二

设定定时器的第一种方法是把WM_TIMER消息发送到通常的窗口消息处理程序,而第二种方法是让Windows直接将定时器消息发送给您程序的另一个函数。

SetTimer(hwnd,iTimerID,iMsecInterval,TimerProc);

方法三

设定定时器的第三种方法类似于第二种方法,只是传递给SetTimer的hwnd参数被设定为NULL,并且第二个参数(通常为定时器ID)被忽略了,最后,此函数传回定时器ID:

iTimerID=SetTimer(NULL,0,wMsecInterval,TimerProc);       

如果没有可用的定时器,那么从SetTimer传回的iTimerID值将为NULL。

KillTimer的第一个参数(通常是窗口句柄)也必须为NULL,定时器ID必须是SetTimer的传回值:

KillTimer(NULL,iTimerID);

--------------------

voidCALLBACKTimerProc(HWNDhWnd,UINTnMsg,UINTnTimerid,DWORDdwTime);

SDK编程笔记 — 计时器篇两个计时器API的讨论

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

KillTimer的函数原型为:

BOOL KillTimer(HWND hWnd,UINT_PTR uIDEvent ); 

参数意义同SetTimer。

关于KillTimer对消息队列中剩余未处理的WM_TIMER消息的影响,MSDN和ProgrammingWindows上的说法完全相反。

MSDN的说法很干脆:

TheKillTimerfunctiondoesnotremoveWM_TIMERmessagesalreadypostedtothemessagequeue. 而petzold则说 TheKillTimercallpurgesthemessagequeueofanypendingWM_TIMERmessages.YourprogramwillneverreceiveastrayWM_TIMERmessagefollowingaKillTimercall.(KillTimer消除消息队列中任何未处理的WM_TIMER消息,调用KillTimer后你的程序永远不会收到一条“漂泊游荡”的WM_TIMER消息)

关于WM_TIMER消息

wParam为计时器的ID;如果需要设定多个计时器,那么对每个计时器都使用不同的计时器ID。

wParam的值将随传递到窗口过程中的WM_TIMER消息的不同而不同。

lParam为指向TimerProc的指针,如果调用SetTimer时没有指定TimerProc(参数值为NULL),则lParam为0(即NULL)。

可以通过在窗口过程中提供一个WM_TIMERcase处理这个消息,或者,默认窗口过程会调用SetTimer中指定的TimerProc来处理WM_TIMER消息

 

使用计时器的三种方法

如果在程序的整个执行过程中使用计时器,一般在处理WM_CREATE消息时或WinMain中消息循环前调用SetTimer,在处理WM_DESTROY消息时或在WinMain中消息循环后return前调用KillTimer。

根据SetTimer中的参数不同,有三种方法使用计时器。

方法一:

调用SetTimer时指定窗口句柄hWnd,nIDEvent中指定计时器ID,将lpTimerFunc置NULL从而不使用TimerProc;在窗口过程中处理WM_TIMER消息。

调用KillTimer时,使用SetTimer中指定的hWnd和id。

最好使用#define定义timer的id,例如:

#defineID_TIMER1

SetTimer(hWnd,ID_TIMER,1000,NULL);

KillTimer(hWnd,ID_TIMER);

方法二:

调用SetTimer时指定窗口句柄hWnd,nIDEvent中指定计时器ID,lpTimerFunc参数不为NULL而指定为TimerProc函数的指针。

这种方法使用TimerProc函数(名字可自定)处理WM_TIMER消息:

VOIDCALLBACKTimerProc(HWNDhwnd,UINTmessage,UINTiTimerID,DWORDdwTime)

{

//处理WM_TIMER讯息

}

TimerProc的参数hwnd是在调用SetTimer时指定的窗口句柄。

Windows只把WM_TIMER消息送给TimerProc,因此消息参数总是等于WM_TIMER。

iTimerID值是计时器ID,dwTimer值是与从GetTickCount函数的返回值相容的值。

这是自Windows启动后所经过的毫秒数。

 使用这种方法时,相关函数调用的形式为:

SetTimer(hWnd,ID_TIMER,1000,TimerProc);

K

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1