我们一般用到settimer函数的时候,第三个参数一般都设置为NULL,这意味着调用缺省的回调函数,叫OnTimer,如果你有几个定时器的话,那么也可以在OnTimer函数里边判断后做出不同的反应。
但今天我们自己编写回调函数来响应定时器的函数!
1.首先我们需要编写两个静态的回调函数,放在主对话框类中,声明如下:
public: static void CALLBACK timeup1(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime); static void CALLBACK timeup2(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime);
2.这是一个静态函数,所以在这个函数里边不能出现Dlg对象,只能出现指针,所以我们只能在这个函数中,声明一个对话框指针,然后通过AfxGetMainWnd()获取到对话框的指针,这样才能在这个函数中运用到相关的功能及其变量!
void CMyDlg::timeup1(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) { pWnd = (CMyDlg*) AfxGetMainWnd(); m_npicNum1++; CClientDC dc(pWnd); if ( m_npicNum1 == 4) { //pWnd->KillTimer(nIDEvent); //return ; m_npicNum1 = -1; } pWnd->mdc->SelectObject(pWnd->bitmap[m_npicNum1]); dc.BitBlt(0,0,rect1.right,rect1.bottom,pWnd->mdc,0,0,SRCCOPY); } void CMyDlg::timeup2(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) { pWnd = (CMyDlg*) AfxGetMainWnd(); m_npicNum2++; CClientDC dc(pWnd); if ( m_npicNum2 == 4) { m_npicNum2 = -1; } pWnd->mdc->SelectObject(pWnd->bitmap[m_npicNum2]); dc.BitBlt(0,300,rect1.right,rect1.bottom,pWnd->mdc,0,0,SRCCOPY); }
注意该函数里边出现的m_npicNum1,m_npicNum2,rect1都是全局变量!
3.在OnInitialDlg中我们添加如下代码:
char ch[7]; for (int i=1;i<=4;i++) { sprintf(ch,"%d.bmp",i);//取得图文件的文件字符串 bitmap[i-1] = new CBitmap; //建立每个CBitmap对象 bitmap[i-1]->m_hObject = (HBITMAP)::LoadImage(NULL,ch,IMAGE_BITMAP,594,177,LR_LOADFROMFILE);//加载图文件 if ( bitmap[i-1]->m_hObject == NULL) { AfxMessageBox("error"); } } GetClientRect(&rect1); CClientDC dc(this); mdc->CreateCompatibleDC(&dc); SetTimer(1,1000,timeup1);//建立定时器 SetTimer(2,2000,timeup2);
4.为了保持屏幕上始终有图像显示。我们在OnPaint函数中也重绘一下(不是必要的!但是里边的CClinent dc(this)这句很关键,如果删除将看不到效果!)
void CMyDlg::OnPaint() { CPaintDC dc(this); // device context for painting if( m_npicNum1 != -1 && m_npicNum1 < 4) mdc->SelectObject(bitmap[m_npicNum1]); dc.BitBlt(0,0,rect1.right,rect1.bottom,mdc,0,0,SRCCOPY); if( m_npicNum2 != -1 && m_npicNum2 < 4) mdc->SelectObject(bitmap[m_npicNum2]); dc.BitBlt(0,300,rect1.right,rect1.bottom,mdc,0,0,SRCCOPY); }
效果图:
圆圈不断循环运动!