我们一般用到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);
}
效果图:
圆圈不断循环运动!