Tady m∙₧ete stßhnout ukßzkovou aplikaci.
Pokud jste n∞kdy zkouÜeli vytvß°et pomocφ MFC n∞jakou hru, kterß pot°ebovala ΦastΘ p°ekreslovßnφ (animaci), urΦit∞ jste p°em²Üleli jak za°φdit aby animace nebyla trhanß. Kdy₧ pou₧ijete timer, tak i u timeru s velmi mal²m intervalem je znatelnΘ trhßnφ. Zp∙sob, kter² vßm ukß₧u podstatn∞ zkrßtφ interval p°ekreslovßnφ. U testovacφ aplikace, kde jsem m∞°il jak dlouho trvß tisφckrßt p°ekreslit jednoduch² °ßdek textu pomocφ timeru a stotisφckrßt (abych v∙bec n∞co nam∞°il) to samΘ pomocφ metody, kterou budu popisovat jsem zφskal tyto hodnoty (pomocφ funkce clock):
Timer: 52120 cykl∙ na tisφc p°ekreslenφ
Run: 1640 cykl∙ na stotisφc p°ekreslenφ
To znamenß, ₧e metoda pomocφ Run je 3178 krßt rychlejÜφ.
A te∩ koneΦn∞ p°edvedu jak to ud∞lat. Princip spoΦφvß v tom, ₧e mφsto abychom p°ekreslovßnφ provßd∞li v reakci na timer, p°ekreslenφ vyvolßvßme v p°etφ₧enΘ funkci CWinApp::Run. Tato funkce p∙vodn∞ obsahuje hlavnφ smyΦku aplikace GetMessage, TranslateMessage, DispatchMessage, jak to znßme z API WinMain.
Ne₧ se pustφme do jejφho p°episovßnφ musφme si napsat krßtk² pomocn² k≤d. Nejd°φve si v naÜφ t°φd∞ aplikace vlo₧φme public ukazatel na naÜi t°φdu pohledu (nazvan² pView) a v konstruktoru jej nastavφme na NULL.
Potom musφme tento ukazatel nastavit, aby ukazoval na nßÜ pohled. To se nejlΘpe ud∞lß v naÜφ t°φd∞ pohledu v reakci na zprßvu WM_CREATE (funkce OnCreate) a to takto:
Zφskßme ukazatel na naÜi t°φdu aplikace (nazvanou CTstApp):
CTstApp* pApp = NULL;
pApp = ((CTstApp*)AfxGetApp());
Nastavφme ukazatel ve t°φd∞ aplikace aby ukazoval na nßÜ pohled:
pApp->pView = this;
Abychom p°edeÜli pokusu k p°φstupu k neexistujφcφmu oknu, musφme tento ukazatel v reakci na zprßvu WM_DESTROY (funkce OnDestroy) nastavit op∞t na NULL a to nap°φklad takto:
CTstApp* pApp = NULL;
pApp = ((CTstApp*)AfxGetApp());
pApp->pView = NULL;
Te∩ jeÜt∞ musφme do naÜφ t°φdy pohledu p°idat funkci, kterß bude vlastnφ p°ekreslenφ provßd∞t (nazveme ji t°eba Redraw). Jejφ obsah nechßm na vßs. Pro vyvolßnφ p°ekreslenφ m∙₧ete pou₧φt funkce Invalidate, RedrawWindow a nebo p°φmo zavolat OnPaint.
A nakonec ta hlavnφ Φßst. Ve svΘ t°φd∞ aplikace p°et∞₧te virtußlnφ funkci CWinApp::Run (jde to i pomocφ ClassWizardu). Pokud pou₧ijete ClassWizard dostanete takto vypadajφcφ funkci Run, kterß d∞lß jen to, ₧e volß funkci Run svΘho p°edka.
int CTstApp::Run()
{
// TODO: Add your specialized code here and/or call the base class
return CWinApp::Run();
}
Vy jφ musφte upravit takto:
int CTstApp::Run()
{
// TODO: Add your specialized code here and/or call the base class
MSG msg;
while(1)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Pokud je ve front∞ zprßva zpracujeme ji
{
if (msg.message==WM_QUIT) break; // Pokud je zprßva WM_QUIT ukonΦφme smyΦku (a tφm i aplikaci)
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else // Jinak vyvolßme p°ekreslenφ
{
if (pView) pView->Redraw();
}
}
return 0;
}
Novß verze funkce Run obsahuje nekoneΦnou smyΦku, kterß je p°eruÜena jen kdy₧ p°ijde zprßva WM_QUIT. V tΘto smyΦce se pomocφ funkce PeekMessage testuje zda je ve front∞ n∞jakß zprßva a pokud je, tak se zpracuje, jinak se vyvolß p°ekreslenφ. Tφm mßme zajiÜt∞no, ₧e se nejd°φve zpracujφ zprßvy a a₧ v p°φpad∞, ₧e ve front∞ zprßv nenφ ₧ßdnß zprßva se vyvolß p°ekreslenφ.
SouΦasn∞ s p°ekreslenφm by se m∞l vyvolßvat i p°epoΦet poloh animovan²ch objekt∙, aby trhßnφ nezp∙soboval namφsto pomalΘho p°ekreslovßnφ pomal² p°epoΦet pozic.
A to je vÜe.