MFC积累整理

文章目录

    • 一、定时器Timer
      • 1.MFC方式
        • (a)创建方法:
        • (b)使用方法:
      • 2.Windows API方式
      • 3.区别总结

一、定时器Timer

1.MFC方式

(a)创建方法:

资源视图->类向导->消息->WM_TIMER->添加处理程序,即可自动生成相应的函数
xx.h 中自动生成:
afx_msg void OnTimer(UINT_PTR nIDEvent);
xx.cpp中如下所示

  • 消息映射(宏定义)自动新增一条ON_WM_TIMER():
    BEGIN_MESSAGE_MAP(CPannelTransBill, CDialogEx)
    	xxx
    	ON_WM_TIMER()
    END_MESSAGE_MAP()
    
  • 功能函数自动构建:
    void CExample::OnTimer(UINT_PTR nIDEvent)
    {
    	// TODO: 在此添加消息处理程序代码和/或调用默认值
    
    	CDialogEx::OnTimer(nIDEvent);
    }
    

(b)使用方法:

如需在BeginTimer函数中调用本对话框中的定时器,使用SetTimer(UINT_PTR nIDEvent, UINT nElapse,
void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))方法即可:

void CExample::BeginTimer()
{
	//启动ID为1的定时器,定时1000ms(1s)
	SetTimer(1,1000,null);
}

使用到此结束

  • SetTimer(x,x,x)函数原型:
    启动定时器就需要使用CWnd类的成员函数SetTimer。CWnd::SetTimer的原型如下:
    UINT_PTR SetTimer(         
       UINT_PTR nIDEvent, //定时器ID
       UINT nElapse,  //定时时间(ms)
    	void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD)//回调函数,没有可设为NULL
    );
    
    • 参数nIDEvent指定一个非零的定时器ID;参数nElapse指定间隔时间,单位为毫秒;参数lpfnTimer指定一个回调函数的地址,如果该参数为NULL,则WM_TIMER消息被发送到应用程序的消息队列,并被CWnd对象处理。如果此函数成功则返回一个新的定时器的ID,我们可以使用此ID通过KillTimer成员函数来销毁该定时器,如果函数失败则返回0。

    • 通过SetTimer成员函数我们可以看出,处理定时事件可以有两种方式,一种是通过WM_TIMER消息的消息响应函数,一种是通过回调函数。

    • 如果要启动多个定时器就多次调用SetTimer成员函数。另外,在不同的CWnd中可以有ID相同的定时器,并不冲突。

  • KillTimer(nIDEvent)函数原型:
    BOOL KillTimer(UINT_PTR nIDEvent)
    {
    	UINT_PTR nIDEvent, //定时器ID
    }
    
  • 多个定时器的例子:
    	void CExample::OnTimer(UINT_PTR nIDEvent)
    	{
    		// TODO: 在此添加消息处理程序代码和/或调用默认值
    		switch(nIDEvent)
    		{
    			case 1:   //ID为1的定时器
    				doFuncOne;
    				break;
    			case 2:  //ID为2的定时器
    				doFuncTwo;
    				break;
    			default:
    				break;
    		}
    		CDialogEx::OnTimer(nIDEvent);
    	}
    
  • *(重点)通过回调函数设置定时器的例子:
    注:回调函数为全局函数,需要写在使用它的位置的前面,或者写在后面然后在使用之前声明。
    • xx.h无需定义内容
    • xx.cpp:
      • 定义一个显示当前时间的对话框(写在cpp#include之后):
        void MyTimer()
        {
        	// TODO: 在此添加消息处理程序代码和/或调用默认值
        	CTime t = CTime::GetCurrentTime();
        	CString str;
        	str.Format("当前时间:  %04d/%02d/%02d  %02d:%02d:%02d", t.GetYear(), t.GetMonth(), t.GetDay(), t.GetHour(), t.GetMinute(), t.GetSecond());
        	Util::ShowSysMsg(str);
        }
        
      • 定义一个回调函数,调用之前的方法(写在MyTimer()之后,其中CALLBACK EXPORT为关键字,函数名可自定义,但返回值类型、参数的类型和个数不能改变。)
        void CALLBACK EXPORT TimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
        {
        	switch (nTimerid)
        	{
        	case 1:
        		MyTimer();
        		break;
        	default:
        		break;
        	}
        }
        
      • 通过SetTimer()调用回调函数
        SetTimer(1, 1000, TimerProc);//1进入case = 1的控制,1000ms,TimerProc为回调函数名称,不加()

2.Windows API方式

  • SetTimer函数原型:
    UINT_PTR SetTimer(         
        HWND    
               hWnd,   //窗口句柄
        UINT_PTR    
               nIDEvent,   //定时器ID
       UINT    
              uElapse,   //定时间隔
       TIMERPROC    
             lpTimerFunc   //回调函数
    );
    
    • 参数hWnd为与定时器关联的窗口的句柄;参数nIDEvent为非零的定时器ID,如果hWnd等于NULL,且还不存在ID为nIDEvent的定时器,那么nIDEvent参数被忽略,然后生成一个新ID的定时器,而如果hWnd不为NULL,且hWnd指定的窗口已存在ID为nIDEvent的定时器,那么这个已存在的定时器被新定时器所取代。参数uElapse和lpTimerFunc同CWnd::SetTimer函数。

    • 如果调用SetTimer函数时最后一个参数为NULL,我们需要自己为WM_TIMER消息添加处理函数,要注意的是,WM_TIMER消息的附加数据wParam为定时器ID,lParam为回调函数的指针,如果调用SetTimer时回调函数为NULL,那么lParam也为NULL。

    • 而如果调用SetTimer函数时最后一个参数不为NULL,我们就需要定义回调函数。回调函数的定义同MFC定时器。

  • 销毁定时器KillTimer API函数:
    BOOL KillTimer(HWND hWnd,UINT_PTR uIDEvent);
    • 参数hWnd为与定时器关联的窗口的句柄,与启动定时器时SetTimer函数的hWnd参数值相同;参数uIDEvent为要销毁的定时器的ID,如果传递给SetTimer的参数hWnd有效,则uIDEvent应与传递给SetTimer的参数nIDEvent相同,而如果SetTimer的参数hWnd为NULL,则uIDEvent应为SetTimer返回的定时器ID。该函数成功则返回TRUE,否则返回FALSE。

3.区别总结

  • CWnd类的SetTimer成员函数只能在CWnd类或其派生类中调用,而API函数SetTimer则没有这个限制,这是一个很重要的区别。因为本教程主要是讲解MFC编程,所以这里就先重点讲解MFC定时器的用法,关于API函数SetTimer的用法鸡啄米会在MFC定时器讲解的基础上进行延伸。

你可能感兴趣的:(MFC学习总结,难点剖析,C++)