在实现一个简单动画时,往往都会使用定时器,现在我们在代码中不使用定时器来实现一个动画,首先我们要找一个计时器,这是关键,动画是有祯频的,计时是必须的。查了MSDN,GetTickCount()这个函数能够满足我们的需要。例子的特效是实现逐行扫描的效果,因此代码实现如下
//在动画体类中写入两个函数
//计时操作的函数,实现频率触发
BOOL CACTThumb::ACTThing( UINT* uiStop )
{
int tick = 0;
//得到当前设备运行的毫秒数
tick = GetTickCount();
//m_uiRate就是定时器中的delaytime
if ( tick-m_uiTick >= m_uiRate )
{
//这里开始处理祯的控制变量
//这是行控制,因为我的目标是实现一个逐行扫描的效果,因此我的祯控制包括行控制和列控制
m_uiAddAct++;
//47表示行扫到最末,要换行了
if ( m_uiAddAct > 47 )
{
m_uiCount++;
m_uiAddAct = 0;
}
//64表示逐行扫描到最后一行,结束了,此时传一个标志,结束循环体的循环
if( m_uiCount >= 64 )
{
*uiStop = 0;
}
m_uiTick = tick;
return 1;
}
return 0;
}
//画DC的函数,具体的绘制
void CACTThumb::DrawACT( HDC hdc )
{
HBRUSH hBrush = CreateSolidBrush( RGB(255,0,0) );
CRect rt;
rt.left = 0;
rt.right = 5 + 5*m_uiAddAct;
rt.top = 5*m_uiCount;
rt.bottom = 5 + 5*m_uiCount;
FillRect( hdc, &rt, hBrush );
}
然后找个地方写上下面这段调用上面的函数
BOOL bCtrol = TRUE;
UINT uicor = 1;
while( bCtrol )
{
HDC hdc = CreateDC( NULL, NULL, NULL, NULL );
if( m_actThumb.ACTThing( &uicor ) )
{
//画DC
m_actThumb.DrawACT( hdc );
//退出循环点
bCtrol = uicor;
}
DeleteDC( hdc );
}
这段代码很邪恶,看上去是一个死循环,但在循环体中有一个控制退出循环时机。
另外这个hdc也很邪恶,如果说会有问题,可能就在这个dc上。
这种方式与定时器相比有一个好处,就是可以在普通类里操作,不受窗口消息的限制,但它有个问题,就是在动画时间内不能执行其他的动作,必须等这个动画执行完了才能进入下个动作(也许加到线程里可以解决这个问题),因此它比较适合用来做屏幕切换操作和对动画的封装
实际上只要API提供了计时函数,不管什么平台,都能采用上面的方法模拟定时器
GetTickCount()是取从设备开机时开始算到执行这个函数止的毫秒数。MSDN上说的是BOOT,是开机还是wince运行起来就不清楚了,我取的是时间差,不影响的。