Jak jsem slφbil ukß₧eme si jak se pracuje s menu, panelem nßstroj∙ a stavov²m °ßdkem. Upravφme aplikcaci z p°edchozφch dφl∙ tak, aby Ülo pomocφ menu a panelu nßstroj∙ povolovat/zakazovat kreslenφ a ve stavovΘm °ßdku se zobrazoval poΦet nakreslen²ch Φar a odstranφme z menu a panelu nßstroj∙ nepot°ebnΘ polo₧ky.
JeÜt∞ ne₧ zaΦneme menu upravovat nastavφme jeho jazyk na Φesk², aby sprßvn∞ zobrazovalo diakritiku. To provedeme tak, ₧e v okn∞ workspace klikneme pravφm tlaΦφtkem na menu. Tφm se nßm zobrazφ mφstnφ nabφdka ze kterΘ zvolφme Properties (vlastnosti).
Tφm se nßm zobrazφ dialogovΘ okno s vlastnostmi menu. Tam nastavφme, ₧e mß menu jako sv∙j jazyk pou₧φvat ΦeÜtinu.
Te∩ dvojklikem na menu ho otev°ete v editoru. Nejd°φve odstranφme polo₧ky, kterΘ v naÜφ aplikaci nechceme. Jsou to v podstat∞ jen n∞kterΘ polo₧ky z menu Edit a to pro kopφrovßnφ, vyjmutφ, vklßdßnφ a odd∞lovaΦ. Polo₧ku z menu odstranφte tak, ₧e ji vyberete a stisknete delete. Potom si nßzvy zb²vajφcφch polo₧ek p°ejmenujeme, aby byly v ΦeÜtin∞ a ne v angliΦtin∞ jak nßm je vygeneroval AppWizard. To provedeme tak, ₧e op∞t klikneme prav²m tlaΦφtkem na polo₧ku menu, kterou chceme p°ejmenovat a z kontextovΘho menu, kterΘ se zobrazφ vybereme Properties. Tφm si zobrazφme vlastnosti polo₧ky menu jak vidφte na nßsledujφcφm obrßzku. (V ukßzkovΘ aplikaci, kterß bude ke sta₧enφ na konci, bude p°ejmenovßno jen menu File-New na File-Nov².)
Text zobrazovan² v menu je v polφΦku Caption. Jist∞ jste si vÜimli, ₧e tento text p°esn∞ neodpovφdß tomu co vidφte v menu. Je tam navφc na zaΦßtku znak &. Ten urΦuje, kter² znak bude v menu podtr₧en (tj. podtr₧en je znak nßsledujφcφ po &) a kter² zßrove≥ slou₧φ jako klßvesovß zkratka p°i ovlßdßnφ menu pomocφ klßvesnice. Dvojice znak∙ \t (tabulßtor) odd∞luje v menu zobrazovanou klßvesovou zkratku. Tato klßvesovß zkratka se ale takto nedefinuje. Definovßnφ klßvesovΘ zkratky se d∞lß ve zdroji Accelerators, ale o tom n∞kdy jindy. Tak₧e jedinΘ co ud∞lßme je, ₧e p°epφÜeme v polφΦku Caption New na Nov². Zbytek textu ponechßme beze zm∞ny.
DalÜφ d∙le₧itou polo₧kou ve vlastnostech menu je polφΦko ID. To je tzv. identifikßtor menu. Ten se pozd∞ji bude pou₧φvat pro vlastnφ propojenφ polo₧ky menu na obslu₧nou funkci. U v∞tÜiny polo₧ek menu generovan²ch AppWizardem je toto propojenφ ji₧ hotovo. Jedinou vyjφmkou je menu Edit a samoz°ejm∞ vÜechny polo₧ky menu, kterΘ sami p°idßte.
PolφΦko Prompt je text automaticky zobrazovan² ve stavovΘm °ßdku, kdy₧ myÜφ najedete nad tuto polo₧ku menu. Nakonci tohoto °et∞zce m∙₧e b²t text popup okna (tool tip), kterΘ se zobrazφ, kdy₧ najede nad polo₧ku panelu nßstroj∙ se stejn²m identifikßtorem (ID). Tento text musφ b²t odd∞len dvojicφ znak∙ \n (nov² °ßdek). Tak₧e po upravenφ vypadajφ vlastnosti tΘto polo₧ky menu takto:
Ze zaÜkrtßvacφch polφΦek jsou d∙le₧itΘ jen prvnφ dv∞ - Separator a Pop-up. Ostatnφ sice takΘ majφ sv∙j v²znam, ale v∞tÜinou se tyto stavy menu nastavujφ programov∞. PolφΦko Separator urΦuje, ₧e polo₧ka menu je tzv. odd∞lovaΦ (vodorovnß Φßra v menu) a Pop-up urΦuje, ₧e polo₧ka menu nenφ p°φkazem, ale obsahuje submenu (nap°. polo₧ka menu File).
Te∩ si p°idßme novΘ menu, kterΘ bude mφt jedinou polo₧ku. Postup je nßsledujφcφ:
Uchopte prßzdnou polo₧ku, kterß je na konci menu a p°etßhn∞te ji na mφsto, kde chcete novΘ menu mφt umφst∞no.
Potom na toto polφΦko klepn∞te prav²m tlaΦφtkem a z popup menu vyberte op∞t Properties (vlastnosti menu). Do polφΦka Caption napiÜte nßzev novΘho menu a zaÜkrtn∞te polφΦko Pop-up.
Tφm jste si vytvo°ili novou polo₧ku v menu aplikace. Do nφ te∩ p°idßme polo₧ku pro povolenφ zakßzßnφ kreslenφ. Kdy₧ na tuto novou polo₧ku kliknete, rozbalφ se vßm a bude obsahovat jedinou prßzdnou polo₧ku. Op∞t zobrazte jejφ vlastnosti a upravte ji takto:
Ka₧dΘ ze zakrou₧kovan²ch polφΦek m∙₧ete vyplnit libovoln∞, podle toho co mß vaÜe polo₧ka menu d∞lat. Hlavn∞ si dejte pozor aby obsah polφΦka ID byl jedineΦn² pro celΘ menu, jinak vßm budou dv∞ polo₧ky menu se stejn²m ID d∞lat stejnou Φinost. Je zvykem vypl≥ovat polo₧ku ID podle jmΘna nad°azenΘho menu a jmΘna tΘto polo₧ky.
Tφm mßte p°idanou polo₧ku do menu. Pokud zkusφte aplikaci p°elo₧it, tak zjistφte, ₧e tato polo₧ka menu je Üedß a nelze ji pou₧φt. To je proto, ₧e na nφ jeÜt∞ nemßte propojenou obslu₧nou funkci. Tu ale p°idßme a₧ po tom co upravφme panel nßstroj∙, proto₧e bude spoleΦnß pro toto menu a jednu polo₧ku panelu nßstroj∙. (Ale klidn∞ bychom ji mohli p°idat u₧ te∩ a polo₧ka panelu nßstroj∙ by se po jsvΘm nadefinovßnφ p°idala automaticky.)
Panel nßstroj∙ najdete ve zdrojφch pod nßzvem toolbar. Nejd°φve mu nastavte jako jazyk ΦeÜtinu a to stejn∞ jako u menu. Potom jej otev°ete v editoru tφm, ₧e na n∞j dvakrßt kliknete. Jako prvnφ odstrßnφme nepot°ebnß tlaΦφtka. To se d∞lß tak, ₧e tlaΦφtko uchopφte myÜφ a p°etßhnete ho mimo panel nßstroj∙, jak vidφte na nßsledujφcφm obrßzku.
Takto z panelu nßstroj∙ odstra≥te tlaΦφtka pro vyjmutφ, kopφrovßnφ a vlo₧enφ. Te∩ naopak dv∞ tlaΦφtka p°idßme. D∞lß se to stejn∞ jako u menu. Uchopφte prßzdnΘ tlaΦφtko (na konci) a p°etßhnete ho na mφsto, kde mß vaÜe novΘ tlaΦφtko b²t. Potom na n∞j nakreslete pomocφ nßstroj∙ z palety nabφzenΘ editorem obrßzek, kter² vyjad°uje co mß za ·kol. Tφm vytvo°φte novΘ tlaΦφtko. Jeho vlastnosti se nastavφ na implicitnφ hodnoty, kterΘ nßm nevyhovujφ, tak₧e je musφme zm∞nit. To ud∞lßte tak, ₧e dvojkliknete na tlaΦφtko, jeho₧ vlastnosti chcete upravit. Tφm se vßm zobrazφ jeho vlastnosti, jak vydφte na nßsledujφcφm obrßzku.
Polo₧ky ID a prompt majφ ·pln∞ stejn² v²znam jako u menu. Zbylß dv∞ polφΦka udßvajφ Üφ°ku a v²Üku tlaΦφtka. Ale pozor. Pokud zm∞nφte velikost jednoho tlaΦφtka, zm∞nφ se velikosti vÜech ostatnφch. Toto tlaΦφtko je zam²Üleno pro akci ·pravy-zp∞t (edit-undo). UrΦit∞ jste si vÜimli, ₧e jsme v menu edit ponechali polo₧ku se stejn²m ·kolem. Je tedy vhodnΘ, aby bylo toto tlaΦφtko propojeno s polo₧kou menu. Toho dostßhneme tφm, ₧e pro tlaΦφtku panelu nßstroj∙ zadßme stejnΘ ID jako polo₧ce menu. PolφΦko Prompt nemusφte vypl≥ovat, proto₧e se automaticky vyplnφ podle polo₧ky menu se stejn²m ID. (V tomto p°φpad∞ z∙stane prßzdnΘ, proto₧e je prßzdnΘ i u polo₧ky menu edit-undo.) Na nßsledujφcφm obrßzku vidφte jak vypadajφ vlastnosti po ·prav∞.
(Jestli to n∞kdo n∞pochopil, tak hodnotu polφΦka ID jsem vzal ze stejnΘho polφΦka ve vlastnostech polo₧ky menu edit-undo.)
Stejn²m zp∙sobem jeÜt∞ p°idejte tlaΦφtko pro povolenφ/zakßzßnφ kreslenφ. (Hodnota ID je ID_KRESLENI_ANO_NE, viz. vlastnosti polo₧ky menu.)
Samoz°ejm∞ m∙₧ete p°idat i tlaΦφtko, kterΘ nemß odpovφdajφcφ polo₧ku v menu. To se provßdφ ·pln∞ stejn∞, jen do ID dßte vlastnφ unikßtnφ hodnotu.
Jist∞ jste si vÜimli, ₧e mezi n∞kter²mi tlaΦφtky panelu nßstroj∙ jsou mezery. Toho dosßhnete tφm, ₧e uchopφte tlaΦφtko a trochu jej od sousednφho tlaΦφtka odtßhnete.
Tφm mßme hotovou ·pravu menu a panelu nßstroj∙ a m∙₧eme zaΦφt psßt obslu₧nΘ funkce.
Obslu₧nou funkci vytvo°φme pomocφ ClassWizardu a to tak, ₧e v polφΦku Class Name vybereme t°φdu do kterΘ chceme obslu₧nou funkci p°idat (CMfcView), v seznamu Object IDs vybereme ID polo₧ky menu nebo panelu nßstroj∙ jejφ₧ obslu₧nou funkci chceme p°idat. Potom se vßm v seznamu Messages objevφ dv∞ polo₧ky: COMMAND a UPDATE_COMMAND_UI. Vyberte COMMAND a stiskn∞te tlaΦφtko Add Function... Tφm jste p°idali obslu₧nou funkci polo₧ky menu (panelu nßstroj∙) do t°φdy vybranΘ v polφΦku Class Name. Te∩ vyberte UPDATE_COMMAND_UI a op∞t stiskn∞te tlaΦφtko Add Function... ClassWizard se vßs zeptß na jmΘno funkce. V²chozφ jmΘno se generuje podle identifikßtoru (ID) a v∞tÜφnou b²vß vyhovujφcφ, tak₧e staΦφ stisknout jen tlaΦφtko OK. Tφm p°idßte funkci, kterß se starß o to, jak se danß polo₧ka menu bude chovat (zda bude zakßzanß/povolenß, zatrhnutß/nezatrhnutß atd...). To ud∞lejte pro polo₧ky menu edit-undo (ID_EDIT_UNDO) a kreslenφ-povolit/zakßzat (ID_KRESLENI_ANO_NE). Stav ClassWizardu po provedenφ vidφte na nßsledujφcφm obrßzku.
V tΘto chvφli mßme namapovanΘ prßzdnΘ obslu₧nΘ funkce, ale jejich obsah musφme dopsat sami. ZaΦneme funkcφ pro akci edit-undo (·pravy-zp∞t).
void CMfcView::OnEditUndo()
{
// TODO: Add your command handler code here
Zφskßme ukazatel na t°φdu dokumentu.
CMfcDoc* pDoc = GetDocument();
Odstranφme naposledy p°idanou Φßru.
pDoc->cary.RemoveAt(pDoc->cary.GetSize()-1);
Vyvolßme p°ekreslenφ.
Invalidate();
}
Jist∞ jste si vÜimli, ₧e nemßme nijak oÜet°eno zda nenφ pole Φar prßzdnΘ a nenφ tedy co odebφrat. V tomto p°φpad∞ by vßm to mohlo zhroutit celou aplikaci. Ale toto oÜet°enφ se ud∞lß pomocφ nßsledujφcφ funkcφ, kterß ovlßdß stav polo₧ky menu (panelu nßstroj∙) edit-undo. Ta nßm tuto polo₧ku menu znep°φstupnφ pokud bude pole Φar prßzdnΘ.
void CMfcView::OnUpdateEditUndo(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI je ukazatel na objekt t°φdy podle kterΘ se nastavuje stav polo₧ky menu. Jeho funkce Enable povolφ/zakß₧e pou₧itφ tΘto polo₧ky menu. Parametrem funkce Enable je hodnota typu BOOL, podle kterΘ se povolφ/ zakß₧e polo₧ka menu. Kdy₧ je TRUE, tak se povolφ, jinak se zakß₧e. Tak₧e v naÜem p°φpad∞ se polo₧ka menu zakß₧e, kdy₧ je pole Φar prßzdnΘ, tj. v²raz GetDocument()->cary.GetSize()!=0 mß hodnotu FALSE.
pCmdUI->Enable(GetDocument()->cary.GetSize()!=0);
}
Pro dalÜφ funkce budeme pot°ebovat prom∞nnou typu BOOL. P°idßme ji tedy do deklarace t°φdy:
class CMfcView : public CView
{
protected: // create from serialization only
CMfcView();
DECLARE_DYNCREATE(CMfcView)
// Attributes
public:
CMfcDoc* GetDocument();
private:
BOOL blbdown;
CPoint ptPrev;
BOOL bCanDraw;
.....
a v konstruktoru ji nastavφme na TRUE.
CMfcView::CMfcView()
{
// TODO: add construction code here
blbdown = FALSE;
bCanDraw = TRUE;
}
Te∩ u₧ m∙₧eme napsat obslu₧nou funkci pro povolenφ/zakßzßnφ kreslenφ. Tato funkce d∞lß pouze to, ₧e neguje booleovskou hodnotu.
void CMfcView::OnKresleniAnoNe()
{
// TODO: Add your command handler code here
bCanDraw = !bCanDraw;
}
Jako dalÜφ napφÜeme obsluhu stavu polo₧ky menu (panelu nßstroj∙).
void CMfcView::OnUpdateKresleniAnoNe(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
Funkce SetCheck zatrhne/odtrhne polo₧ku menu (panelu nßstroj∙) podle booleovskΘ hodnoty p°edanΘ jako jejφ parametr.
pCmdUI->SetCheck(bCanDraw);
}
Tak, te∩ mßme sice napsanΘ obsluhy menu (panelu nßstroj∙), ale funguje jen edit-undo. Polo₧ka povolenφ/zakßzßnφ kreslenφ sice m∞nφ sv∙j stav, ale na aplikaci jin² vliv nemß, co₧ je logickΘ, proto₧e pouze m∞nφ hodnotu prom∞nnΘ, kterß ale nijak nenφ provßzanß se zbytkem aplikace. Proto jeÜt∞ musφme upravit funkci, kterß reaguje na stisk levΘho tlaΦφtka myÜi.
void CMfcView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
Pokud je povoleno kreslenφ (bCanDraw == TRUE) chovß se funkce jako v d°φv∞jÜφm dφle, ale pokud mß bCanDraw hodnotu FALSE z∙stane hodnota prom∞nnΘ blbdown na hodnot∞ FALSE a aplikace se chovß jako by levΘ tlaΦφtko nebylo stisknuto.
if (bCanDraw)
{
blbdown=TRUE;
ptPrev = point;
}
CView::OnLButtonDown(nFlags, point);
}
Tφm mßme dokonΦeny ·pravy t²kajφcφ se menu a panelu nßstroj∙. Zb²vß jen upravit stavov² °ßdek, aby zobrazoval poΦet nakreslen²ch Φar. K tomu pot°ebujeme do zdroj∙ p°idat textov² °et∞zec. Otev°ete si zdroj String table (textovΘ °et∞zce) tφm, ₧e na n∞j poklepete v okn∞ workspace, a poklepßnφm na prßzdnou polo₧ku zahßjφte p°idßvßnφ novΘho °et∞zce. Pokud jste si na zaΦßtku vytvß°enφ aplikace nenastavili jeho jazyk na ΦeÜtinu (klik prav²m tlaΦφtkem, properties, a v poli language zvolit Czech), mßte ve zdrojφch pravd∞podobn∞ dv∞ verze textov²ch °et∞zc∙, anglickou a Φeskou. Nelekejte se toho. Aplikace p°ednostn∞ pou₧ije Φeskou verzi a a₧ kdy₧ v nφ nenajde po₧adovan² °et∞zec, tak prohledß anglickou. Tak₧e sv∙j °et∞zec p°idejte do ΦeskΘ verze. Na nßsledujφcφm obrßzku vidφte jak by asi m∞la vypadat pracovnφ plocha t∞sn∞ p°ed dokonΦenφm p°idßnφ °et∞zce. P°idßnφ °et∞zce dokonΦφte tφm, ₧e kliknete mimo okno String properties. Pokud chcete vytvß°enφ °et∞zce zruÜit stiskn∞te klßvesu Escape.
V polφΦku ID je identifikßtor textovΘho °et∞zce a v polφΦku Caption vlastnφ text. Tento text by m∞l b²t p°ibli₧n∞ stejn∞ dlouh² jako text zobrazovan² ve stavovΘm °ßdku, proto₧e se podle n∞j nastavφ velikost pole ve stavovΘm °ßdku.
UrΦit∞ vßs zaujaly dva °et∞zce, kterΘ u₧ byly nadefinovßny. Jsou to texty z polφΦek Prompt u vlastnostφ menu (panelu nßstroj∙) a odtutd se takΘ berou, kdy₧ se majφ zobrazit, tak₧e jejich ·pravu m∙₧ete provßd∞t bu∩ zde nebo ve vlastnostech menu (panelu nßstroj∙).
╪et∞zec mßme p°idan², tak₧e jej pou₧ijeme a to v poli definujφcφm vzhled stavovΘho °ßdku. Toto pole vytvß°φ AppWizard p°i vytvß°enφ aplikace a nastavuje do n∞j standartnφ polo₧ky jejich₧ popis najdete dßle. Toto pole najdete v souboru mainfrm.cpp (soubor s definicemi funkcφ hlavnφho rßmcovΘho okna) na zaΦßtku hned za mapou zprßv. Upravte jej takto:
static UINT indicators[] =
{
Prvnφ a nejv∞tÜφ pole stavovΘho °ßdku, zobrazuje se v n∞m popis aktivnφ polo₧ky menu nebo panelu nßstroj∙. (Toto chovßnφ je p°edprogramovßno.)
ID_SEPARATOR, // status line indicator
Zde je nßmi p°idßvanΘ pole (ID textovΘho °et∞zce). Zobrazuje se v n∞m textov² °et∞zec s odpovφdajφcφm ID, dokud to programov∞ nezm∞nφme. (viz. dßle)
ID_INDICATORS_CARY,
Nßsledujφ pole, kterΘ zobrazujφ stav p°epφnaΦ∙ Caps Lock, Num Lock a Scroll Lock. (Toto chovßnφ je p°edprogramovßno.) Tyto polo₧ky m∙₧ete libovoln∞ p°idßvat a odebφrat. Pokud si prohlΘdnete anglickou verzi zdroje textov²ch °et∞zc∙, najdete zde i tyto identifikßtory.
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
Jak u₧ jsem napsal, toto pole se pou₧φvß p°i vytvß°enφ stavovΘho °ßdku. To se provßdφ ve funkci hlavnφho rßmcovΘho okna CMainFrame::OnCreate, kterß se spouÜtφ na zprßvu WM_CREATE, co₧ je prvnφ zprßva, kterou okno dostane po svΘm vytvo°enφ. Nebudeme ji nijak upravovat, ale pro ·plnost ji zde uvedu i s popisem.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
Zavolß se funkce p°edch∙dce a pokud nebyla provedena ·sp∞Ün∞ vrßtφ se -1 (chyba).
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
Vytvo°enφ panelu nßstroj∙. Pokud nebylo provedeno ·sp∞Ün∞ vrßtφ se -1 (chyba).
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
Vytvo°enφ stavovΘho °ßdku. Pokud nebylo provedeno ·sp∞Ün∞ vrßtφ se -1 (chyba).
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
Povolenφ dokovßnφ panelu nßstroj∙, povolenφ dokovßnφ v hlavnφm rßmcovΘm okn∞ a zapnutφ dokovßnφ panelu nßstroj∙.
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
Nenastala ₧ßdnß kritickß chyba, vrßtφme 0 (vÜe OK).
return 0;
}
Pokud vßs zajφmajφ podrobnΘ popisy p°edchozφch funkcφ, odkazuji vßs na MSDN.
Mßme p°idßno polφΦko do stavovΘho °ßdku, te∩ ji₧ chybφ jen napsat funkci, kterß bude m∞nit text, kter² se v n∞m zobrazuje a zavolat ji. Nazveme ji t°eba UpdateStatusBar. (Nezapome≥te ji p°idat do hlaviΦkovΘho souboru.)
void CMfcView::UpdateStatusBar()
{
Zjistφme poΦet Φar.
int pocet_car = GetDocument()->cary.GetSize();
PoÜleme hlavnφmu rßmcovΘmu oknu zprßvu, ₧e se zm∞nil poΦet Φar, aby mohlo upravit stavov² °ßdek. AfxGetMainWnd vrßtφ ukazatel na hlavnφ okno aplikace, v naÜem p°φpad∞ (tj. u aplikace s architekturou dokument/pohled) je to hlavnφ rßmcovΘ okno (CMainFrame). Tato funkce vracφ sice ukazatel na CWnd, ale bez obav jej m∙₧ete p°etypovat, i kdy₧ to v tomto p°φpad∞ nenφ t°eba.
AfxGetMainWnd()->SendMessage(WM_APP+1,WPARAM(pocet_car));
}
Te∩ ji musφme jeÜt∞ zavolat kdykoli se zm∞nφ poΦet Φar, tj. ve funkci reagujφcφ na pohyb myÜi a ve funkci na vracenφ kreslenφ zp∞t.
void CMfcView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
LINE line;
CMfcDoc* pDoc = GetDocument();
CClientDC dc(this);
if (blbdown)
{
line.first = ptPrev;
line.second = point;
ptPrev = point;
pDoc->cary.Add(line);
dc.MoveTo(line.first);
dc.LineTo(line.second);
UpdateStatusBar();
}
CView::OnMouseMove(nFlags, point);
}
void CMfcView::OnEditUndo()
{
// TODO: Add your command handler code here
CMfcDoc* pDoc = GetDocument();
pDoc->cary.RemoveAt(pDoc->cary.GetSize()-1);
Invalidate();
UpdateStatusBar();
}
Samoz°ejm∞ nesmφme zapomenout obslou₧it zprßvu, kterou funkce UpdateStatusBar() posφlß. To provedeme v procedu°e hlavnφho rßmcovΘho okna, kterΘ je p°φjemcem zprßvy:
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
int pane;
CString pane_text;
switch (message)
{
case WM_SYSCOMMAND:
if (wParam==SC_MINIMIZE) return 0;
break;
case WM_APP+1:
Zφskßme index (po°adφ) naÜeho polφΦka ve stavovΘm °ßdku.
pane = m_wndStatusBar.CommandToIndex(ID_INDICATORS_CARY);
Vytvo°φme textov² °et∞zec, kter² nastavφme na po₧adovan² text.pane_text je objekt typu CString. CString je t°φda zapouzd°ujφcφ textovΘ °et∞zce a jeho funkce Format je ekvivalentem funkce sprintf. (Viz. nßsledujφcφ dφl.)
pane_text.Format("PoΦet Φar: %d",int(wParam));
Nastavφme polφΦku stavovΘho °ßdku o indexu pane text pane_text.
m_wndStatusBar.SetPaneText(pane,pane_text);
break;
};
return CFrameWnd::WindowProc(message, wParam, lParam);
}
PoΦet Φar se m∞nφ jeÜt∞ p°i vytvß°enφ novΘho dokumentu a p°i otevφrßnφ ulo₧enΘho.
BOOL CMfcDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
Zφskßme ukazatel na hlavnφ rßmcovΘ okno aplikace.
CWnd* pMainWnd = AfxGetMainWnd();
P°ed nastavenφm poΦtu Φar musφme v tomto p°φpad∞ jeÜt∞ zkontrolovat zda byl vrßcen platn² ukazatel a okno bylo vytvo°eno, proto₧e se tato funce volß ne₧ je ukazatel na hlavnφ rßmcovΘ okno p°i°azen do prom∞nnΘ CMfcApp::m_pMainWnd odkud jej funkce AfxGetApp bere.
if (pMainWnd) pMainWnd->SendMessage(WM_APP+1,WPARAM(0));
return TRUE;
}
void CMfcDoc::Serialize(CArchive& ar)
{
int pocet,i;
LINE l;
if (ar.IsStoring())
{
// TODO: add storing code here
pocet = cary.GetSize();
ar << pocet;
for (i=0; i<pocet; i++)
{
ar << cary[i].first;
ar << cary[i].second;
}
}
else
{
// TODO: add loading code here
ar >> pocet;
for (i=0; i<pocet; i++)
{
ar >> l.first;
ar >> l.second;
cary.Add(l);
}
AfxGetMainWnd()->SendMessage(WM_APP+1,WPARAM(pocet));
}
}
Zdrojov² k≤d tΘto lekce m∙₧ete stßhnout zde.
A to je pro tentokrßt vÜe. V p°φÜtφm dφlu se jeÜt∞ krßtce vrßtφme k dokumentu a podφvßme se na t°φdu CString.