Circle::Animation();的做法
¶Circle::Animation();的做法
原文連結: https://darkblack01.blogspot.com/2013/02/circleanimation.html
移植時的最後更新日期: 2013-04-11T00:20:50.739+08:00
在CPatternDlg中,宣告了一個圈圈物件
class CPatternDlg : public CDialog
{
Circle m_Goal;
};
因為想要圈圈做動畫,並且用下面的呼叫方式(漂亮的語法)void CPatternDlg::readyScreen()
{
//…
m_Goal.Animation();
}
注意事項:在此的動畫實作,是另外呼叫一個Thread來跑動畫程式段。
原本的做法
UINT CPatternDlg::vbrGoalThread(LPVOID LParam)
{
//…
for (int i = 0; i < 100; ++i)
{
PtnDlg->InvalidateRect(pGoal->VbrFun(i, oriR));
PtnDlg->UpdateWindow();
}
}
pGoal->VbrFun(i, oriR) 為動畫的數學式子(自已決定)InvalidateRect();和UpdateWindow();為更新視窗的函數。
使用
void CPatternDlg::readyScreen()
{
//…
vbrGoalThread((LPVOID)&Info1);
}
在準備畫面時,執行這個函數,就會出現動畫。難點:
動畫需要更新畫面,所以動畫的每一頁的更新步驟會建在CPattern::Animation()
但若做成CPattern::Animation(Circle& ),就違反概念整體性,也不OO了
後來的做法
我們來看看,先將動畫函數建在Circleclass Circle
{
private:
CWnd* m_pdlgcWnd;
static void elasticAnimation(LPVOID LParam); //開新的Thread
public:
CWnd* gethWnd(){ return m_pdlgcWnd; };
void setWnd(CWnd* cWnd){ m_pdlgcWnd = cWnd; };
void Animation(){ elasticAnimation((LPVOID)&m_Info1); };
};
在CPattern::CPattern()完成後,再用另一個函數將CWnd*存進Circle,為了畫面更新控制權。 void CPatternDlg::SomeFunction()
{
//…
m_Goal.setWnd(GetActiveWindow()); //GetActiveWindow()需等建構式完成才可以抓取
}
最後在Circle裡建Animation(),再將「開新的Thread」函數隱藏起來 void Circle::elasticAnimation(LPVOID LParam)
{
//…
for (UINT i = 0; i < 100; ++i)
{
_pCircle->gethWnd()->InvalidateRect(&_pCircle->DampingVibration(i, _pCircle->GetRadius()), TRUE);
_pCircle->gethWnd()->UpdateWindow();
}
}
發表於
tags:
{ WIN32 API/MFC }