Sunteți pe pagina 1din 7

Status Bars i Toolbars (Bara de stare i de instrumente)

Lucrul cu barele de instrumente (Toolbars)


Butoanele de pe toolbar corespund la comenzi, la fel ca articolele dintr-un meniu. n general butoanele din toolbar sunt duplicate pentru comenzi din meniu (shortcut-uri). Bara de instrumente poate fi adugat cu AppWizard. AppWizard creaz bara de instrumente pentru cele mai utilizate comenzi din File, Edit i Help. Rmne n sarcina noastr s modificm bara de instrumente dup cum dorim. Fiecare buton de pe bara de instrumente are un ID care-l identific. Pe baza acestui ID vom ataa o comand pentru buton.

tergerea butoanelor din bara de instrumente


Vom exemplifica cele ce urmeaz pe baza unei aplicaii, numit Tool, cu arhitectura Document/View i de tip MDI. AppWizard furnizeaz o bar de instrumente docking (bara de instrumente nu este fix, poate fi mutat oriunde n zona client, arat ca o palet plutitoare) implicit pentru aceast aplicaie. Aceast funcionalitate este dat de AppWizard i MFC. Pentru a terge un buton din toolbar procedm n felul urmtor: 1. selectm pagina (tab) Resource View 2. expandm Tool Resources pentru a vedea resursele aplicaiei 3. selectm Toolbar 4. dublu clic pe IDR_MAINFRAME pentru a-l edita. 5. tergerea unui buton se face prin tragerea butonului respectiv din aceast list (clic pe buton, se ine butonul stng al mouse-ului apsat i se trage butonul in afara toolbar-ului i apoi eliberarea butonului).

Adugarea de butoane la Toolbar


Adugarea se face n doi pai: 1. se deseneaz icoana butonului selectnd butonul alb (blank) din toolbar; desenarea se face folosind instrumentele puse la dispoziie de mediul de programare. 2. se ataeaz o comand noului buton adugat; se selecteaz Properties pentru acest nou buton i vom indica Id-ul acestui buton (ID_CIRCLE n acest caz).

Descriere i ToolTip
n continuare vom (defini) ataa descrierea butonului i a ToolTip-ului. Descrierea apare n bara de stare, iar ToolTip-ul apare cnd mouse-ul rmne deasupra butonului pentru o secund sau dou. Aceste dou iruri de caractere le vom introduce n boxa de editare Prompt: mai nti irul pentru descrierea butonului i apoi separat cu newline (\n) irul pentru ToolTip.

Adugare comand pentru buton


Se disting dou situaii: 1. butonul din toolbar are un articol de meniu corespunztor, adic selectarea butonului sau a articolului de meniu are acelai efect;

2.

butonul din toolbar nu are un articol de meniu corespunztor.

n primul caz vom alege acelai ID pentru buton ca i pentru comanda din meniu. Se presupune c pentru comenzile din meniu am scris codul. n cel de-al doilea caz vom proceda n felul urmtor:

1. Selectm butonul pentru care dorim s crem tratarea mesajului i apoi deschidem ClassWizard. 2. Din foia de proprieti care apare, cu ID-ul butonului selectat, selectm in boxa Class Name, clasa la care vom aduga funcia, n mod obinuit clasa pentru vizualizare (derivat din CView sau alte clase din aceast ierarhie). 3. Executm dublu clic pe COMMAND din boxa Messages. 4. Acceptm numele funciei propus de MFC i apoi editm codul. Observaie: Dac nu se definete nici o comand pentru un buton din toolbar atunci MFC l va face disabled n timpul execuiei. Acelai lucru este valabil i pentru o comand din meniu.
Se va exersa acest lucru la calculator. Un rspuns posibil pentru butonul cu ID-ul ID_CIRCLE.

Listing CToolView::OnCircle()
void CToolView::OnCircle() { CClientDC clientDC(this); CBrush newBrush(RGB(255,0,0)); CBrush* oldBrush = clientDC.SelectObject(&newBrush); clientDC.Ellipse(20, 20, 200, 200); clientDC.SelectObject(oldBrush); } Recapitulare: Evidenierea folosirii pensoanelor (clasa CBrush). Ce nseamn contextul de dispozitiv? Cum se folosete? Rolul funciei SelectObject(). Alte ntrebri legate de contextul de dispozitiv.

Funciile membre ale clasei CToolBar


Dac dorim s schimbm comportarea toolbar-ului sau forma sa de afiare, vom folosi funciile din clasa CToolBar. Toolbar-ul este accesibil din clasa CMainFrame, acolo fiind definit i variabila m_wndToolBarde tip CToolBar. n general schimbarea comportrii toolbar-ului se face n funcia CMainFrame::OnCreate().

Funciile membru ale clasei CToolBar


Function CommandToIndex() Create() GetButtonInfo() GetButtonStyle() GetButtonText() GetItemID() GetItemRect() GetToolBarCtrl() LoadBitmap() Description Obtains the index of a button, given its ID Creates the toolbar Obtains information about a button Obtains a button's style Obtains a button's text label Obtains the ID of a button, given its index Obtains an item's display rectangle, given its index Obtains a reference to the CToolBarCtrl object represented by the CToolBar object Loads the toolbar's button images

LoadToolBar() SetBitmap() SetButtonInfo() SetButtons() SetButtonStyle() SetButtonText() SetHeight() SetSizes()

Loads a toolbar resource Sets a new toolbar button bitmap Sets a button's ID, style, and image number Sets the IDs for the toolbar buttons Sets a button's style Sets a button's text label Sets the toolbar's height Sets the button sizes

Lucrul cu bara de stare (Status Bars)


Bara de stare const n afiarea unui text ce descrie comanda ce urmeaz a fi selectat. De asemenea bara de stare conine starea unor taste (CAPS, NUM Lock, etc.). Comportamentul barei de stare este ncapsulat n clasa CStatusBar. O bar de stare este asemntoare cu toolbar-ul. Se creaz n CMainFrame::Create().

Metodele clasei CStatusBar


Method CommandToIndex() Create() GetItemID() GetItemRect() GetPaneInfo() GetPaneStyle() GetPaneText() GetStatusBarCtrl() SetIndicators() SetPaneInfo() SetPaneStyle() SetPaneText() Description Obtains an indicator's index, given its ID Creates the status bar Obtains an indicator's ID, given its index Obtains an item's display rectangle, given its index Obtains information about an indicator Obtains an indicator's style Obtains an indicator's text Obtains a reference to the CStatusBarCtrl object represented by the CStatusBar object Sets the indicators' IDs Sets the indicators' IDs, widths, and styles Sets an indicator's style Sets an indicator's text

Bara de stare conine mai multe pri, numite panes, care afieaz informaii despre starea aplicaiei i a sistemului. Metoda cea mai folosit pentru a personaliza bara de stare, este de aduga noi pri. Pentru a face acest lucru procedm astfel:

1. Crem un ID pentru o comand pentru noul pane. 2. Crem un string implicit pentru acest pane. 3. Adugm comanda ID a pane-ului la tabloul (array) indicatorilor barei de stare. 4. Crem funcia corespunztoare pentru acest ID.
Explicm aceste lucruri n detaliu.

Crearea unui ID pentru o nou comand


Pentru a aduga un ID pentru o comand (definirea ID-ului) procedm astfel: View -> Resource Symbols -> New Symbol i apoi tastm ID-ul in boxa Name, de ex. ID_MYNEWPANE, apoi OK i Close.

Crearea stringului implicit


Presupunem c am creat ID-ul. Pentru a defini stringul procedm astfel: 1. selectm Resource View (din panelul workspace)-> i apoi dublu clic pe resursa String Table pentru a o deschide; 2. alegem Insert, New String pentru a deschide boxa de dialog String Properties.

3.

tastm ID-ul, ID_MYNEWPANE n boxa ID (sau l alegem din lista drop-down) i apoi tastm textul (stringul) in boxa Caption .

Adugarea Id-ului la tabloul (array) indicatorilor


MFC folosete un tablou de ID-uri pentru a determina ce paneluri s afieze. Acest tablou este pasat ca argument n funcia membru a barei de stare SetIndicators(), care este apelat n funcia Create() din CMainFrame.

Listing MainFrm.cpp--The Indicator Array


static UINT indicators[] = { ID_SEPARATOR, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; // status line indicator

Pentru a aduga noul pane, tastm ID-ul n acest vector n poziia n care vrem s apar panelul nou, urmat de virgul dac nu este pe ultima poziie.

Listing MainFrm.cppVectorul indicatorilor dup adugare


static UINT indicators[] = { ID_SEPARATOR, ID_MYNEWPANE, ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; // status line indicator // ID adaugat

Crearea funciei pentru Update (CCmdUI)


MFC nu actualizeaz (enable) n mod automat noul pane adgat. Trebuie s crem o funcie pentru actualizarea (enable) noului pane. n mod normal se folosete ClassWizard pentru a trata mesajele, dar ClassWizard nu face nimic pentru bara de stare. Va trebui s adgm manual intrrile n harta de mesaje, n fiierul .h i n n .cpp. Aceste modificri le vom face n afara comentariilor speciale AFX_MSG_MAP folosite de ClassWizard.

Listing MainFrm.h--Message Map


// Generated message map functions protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG afx_msg void OnUpdateMyNewPane(CCmdUI *pCmdUI); DECLARE_MESSAGE_MAP()

Listing MainFrm.cpp--Message Map


BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code ! ON_WM_CREATE() //}}AFX_MSG_MAP ON_UPDATE_COMMAND_UI(ID_MYNEWPANE, OnUpdateMyNewPane) END_MESSAGE_MAP()

Listing CMainFrame::OnUpdateMyNewPane()
void CMainFrame::OnUpdateMyNewPane(CCmdUI *pCmdUI) { pCmdUI->Enable(); pCmdUI->SetText(m_paneString); } m_paneString conine stringul (este de tip CString).

Modificarea stringului pentru m_paneString


Se adaug data membru la clasa CMainFrame: private: CString m_paneString; Prima varianta: Se iniializeaz aceast variabil n constructorul clasei CMainFrame: m_paneString = "Default string"; Pentru a afia bara de stare pentru prima dat, se adaug urmtoarele linii de cod n CMainFrame::OnCreate(), nainte instruciunea return: CClientDC dc(this); SIZE size = dc.GetTextExtent(m_paneString); int index = m_wndStatusBar.CommandToIndex(ID_MYNEWPANE); m_wndStatusBar.SetPaneInfo(index,ID_MYNEWPANE, SBPS_POPOUT, size.cx); Acest cod seteaz stringul i mrimea panelului. Setarea mrimii panelului se face printr-un apel la funcia SetPaneInfo(), care are nevoie de indexul panelului, ID-ul, stilul de afiare i mrimea acestui panel. CommandToIndex() obine indexul panelului avnd ca parametru ID-ul panelului. i GetTextExtent() obine mrimea, calculat conform fontului utilizat, mrimii caracterelor i lungimii irului m_paneString. A doua variant: Adugarea unei opiuni n meniu pentru modificarea coninutului variabilei m_paneString. De obicei se creaz o box de dialog n care se preia noua valoare. Acest lucru implic adugarea unei opiuni de meniu i tratarea acesteia (scrierea codului pentru funcie). De asemenea implic crearea unei boxe de dialog. Se vor explica n detaliu aceste lucruri. Cod posibil:

Listing CMainFrame::OnFileChangestring()
void CMainFrame::OnFileChangestring() { CPaneDlg dialog(this); dialog.m_paneString = m_paneString; int result = dialog.DoModal(); if (result == IDOK) { m_paneString = dialog.m_paneString; CClientDC dc(this); SIZE size = dc.GetTextExtent(m_paneString); int index = m_wndStatusBar.CommandToIndex(ID_MYNEWPANE); m_wndStatusBar.SetPaneInfo(index, ID_MYNEWPANE, SBPS_POPOUT, size.cx); } } De observat asemnarea codului cu cel din prima variant.

Lucrul cu Rebar
Rebar sunt toolbar-uri care conin alte controale dect butoanele toolbar. Ca exemplificare vom aduga un check box care este reprezentat de clasa CButton. Etape: n CMainFrame (.h) adugm: public: CReBar m_rebar; CButton m_check; n CMainFrame::Create() adugm la sfrit urmtoarele linii: if (!m_rebar.Create(this) ) { TRACE0("Failed to create rebar\n"); return -1; // fail to create } Controlul check box are nevoie de un ID. Selectm View->Resource Symbols->New i tastm IDC_CHECK. Acceptm aceast alegere. Se adaug astfel o linie n resource.h i aceast resurs nu poate fi utilizat i de alte controale. Din nou n CMainFrame::OnCreate(), adugm urmtoarele linii pentru a crea check box-ul: if (!m_check.Create("Check Here", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, CRect(0,0,20,20), this, IDC_CHECK) ) { TRACE0("Failed to create checkbox\n"); return -1; // fail to create } n final, se adaug acest control la rebar: m_rebar.AddBar(&m_check, "On The Bar", NULL, RBBS_BREAK | RBBS_GRIPPERALWAYS); AddBar() are patru parametri: un pointer la controlul care va fi adugat, textul afiat alturi de control, un pointer la un bitmap pentru a fi folosit pentru imaginea background-ului pe rebar i stilul rebar-ului. Alte stiluri sunt: RBBS_BREAK puts the band on a new line, even if there's room for it at the end of an existing line. RBBS_CHILDEDGE puts the band against a child window of the frame. RBBS_FIXEDBMP prevents moving the bitmap if the band is resized by the user. RBBS_FIXEDSIZE prevents the user from resizing the band. RBBS_GRIPPERALWAYS guarantees sizing wrinkles are present. RBBS_HIDDEN hides the band. RBBS_NOGRIPPER suppresses sizing wrinkles. RBBS_NOVERT hides the band when the rebar is vertical. RBBS_VARIABLEHEIGHT enables the band to be resized by the rebar.

n acest moment aplicaia funcioneaz dar nu se ntpl nimic la selecie sau deselecie check box. Pentru ca aplicaia s reacioneze la clic pe check box trebuie s prindem mesajul i s-l tratm. Cel mai simplu mod pentru a face acest lucru este s schimbm ceea ce se deseaneaz n OnDraw() din vizualizare. Adugm la clasa vizualizare tratarea mesajului care apare cnd se face clic pe acest buton. Adugarea se face manual ca la bara de stare, n afara codului generat de ClassWizard:

nainte de DECLARE_MESSAGE_MAP, adugm: afx_msg void OnClick(); Adugm funcia la clasa vizualizare: void CRebarView::OnClick() { Invalidate(); } Aceasta va apela OnDraw(). n harta de mesaje adugm (tot n afara codului generat de ClassWizard): ON_BN_CLICKED(IDC_CHECK, OnClick) La nceputul fiierului adugm: #include "mainFrm.h" n OnDraw() adugm: CString message; if ( ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_check.GetCheck()) message = "The box is checked"; else message = "The box is not checked"; pDC->TextOut(20,20,message); Nimic mai simplu..