29
Sep
2008

Ca incepator in MFC si C++, m-am lovit de o serie de probleme in a intelege mecanismele interne ale framework-ului. In acest articol voi incerca sa expun ce am aflat despre ferestrele dockabile. Prin citirea acestui articol veti putea invata:

  • Cum se creaza si se incarca un toolbar.
  • Cum functioneaza mecanismul de dockare.
  • Cum se pot afla informatii despre starea de dockare.
  • Cum se poate asigura persistenta starii unui obiect de tip CControlBar intre mai multe rulari ale aplicatiei.

Prin dockare intelegem atasarea unei ferestre la una din laturile zonei client a altei ferestre. In MFC, pentru a suporta functionalitatea de dockare, o fereastra trebuie sa deriveze din clasa CControlBar. Clasa CControlBar este clasa de baza pentru clasele CStatusBar, CToolBar, CDialogBar, CReBar si COleResizeBar.

In acest articol vom folosi clasa CToolBar pentu a exemplifica pasii necesari pentru folosirea functionalitatii de dockare oferita de MFC. Pentru inceput, sa lamurim prin cateva imagini diferitele stari in care se poate afla un toolbar:

  • toolbar dockat in partea de sus:

  • toolbar dockat in partea din stanga:

  • toolbar flotant:

Pentru a crea un toolbar, trebuie parcursi urmatorii pasi:

  • Din fereastra "Solution Explorer", executam click dreapta pe elementul "Resource Files", Add->Resource. Din dialogul care apare selectam "Toolbar" si apasam butonul "New". In acest moment Visual Studio a creat o imagine in format bitmap, care va fi folosita la desenarea toolbar-ului. De asemenea acestei imagini i-a fost atasat un ID de resursa, IDR_TOOLBAR1, dupa cum putem vedea in fisierul "Resource.h".
  • Pregatim ferestra principala pentru a suporta atasarea altor ferestre la laturile zonei sale client. Aceasta se face prin apelul metodei CFrameWnd::EnableDocking care are urmatorul prototip:

    void EnableDocking( DWORD dwDockStyle );
    

    unde dwDockStyle poate lua urmatoarele valori:

    • CBRS_ALIGN_TOP: Permite dockarea pe latura de sus a zonei client.
    • CBRS_ALIGN_BOTTOM: Permite dockarea pe latura de jos a zonei client.
    • CBRS_ALIGN_LEFT: Permite dockarea pe latura din stanga a zonei client.
    • CBRS_ALIGN_RIGHT:Permite dockarea pe latura din dreapta a zonei client.
    • CBRS_ALIGN_ANY: Permite dockarea pe orice latura a zonei client.

    Prin apelul metodei CFrameWnd::EnableDocking, fereastra in cauza creaza pentru fiecare latura care permite dockarea cate un obiect de tip CDockBar, care va fi utilizat mai tarziu ca fereastra parinte pentru ferestra care se dockeaza.

  • Declaram in interiorul clasei ferestrei principale variabila membru

    CToolBar m_toolBar1; 
    
  • Daca nu este deja creata, adaugam in clasa fereastrei pricipale metoda pentru tratarea mesajului ON_WM_CREATE. Aceasta se face dupa cum urmeaza:
    • adaugam in definitia clasei metoda:

      afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct); 
      
    • in harta de mesaje a ferestrei, adaugam codul pentru atasarea metodei handler la mesajul ON_WM_CREATE:
      BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
         ON_WM_CREATE()
      END_MESSAGE_MAP()
      
    • adaugam implementarea metodei in clasa ferestrei principale.
  • In metoda OnCreate definita la pasul anterior, adaugam urmatoarele linii de cod:

    CFrameWnd::EnableDocking( CBRS_ALIGN_ANY);
    m_toolBar1.Create( this);
    m_toolBar1.LoadToolBar( IDR_TOOLBAR1);
    m_toolBar1.EnableDocking( CBRS_ALIGN_ANY);
    

    Efectul apelului metodei CFrameWnd::EnableDocking a fost explicat la pasul 2. Apelul metodei:

    BOOL CToolBar::Create( 
       CWnd* pParentWnd, 
       DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, 
       UINT nID = AFX_IDW_TOOLBAR );
    

    creaza un toolbar Windows si il asociaza cu obiectul de tip CToolBar. Valorile posibile pentru parametrul dwStyle sunt:

    • CBRS_TOP:Toolbar-ul este in partea de sus a ferestrei.
    • CBRS_BOTTOM: Toolbar-ul este in partea de jos a ferestrei.
    • CBRS_NOALIGN: Toolbar-ul nu este repozitionat atunci cand fereastra este redimensionata.
    • CBRS_TOOLTIPS: Toolbar-ul afiseaza tool tip-uri.
    • CBRS_SIZE_DYNAMIC: Toolbar-ul are dimensiuni variabile.
    • CBRS_SIZE_FIXED: Toolbar-ul are dimensiuni fixe.
    • CBRS_FLOATING: Toolbar-ul este flotant.
    • CBRS_FLYBY: Status bar-ul afiseaza informatii despre butonul curent.
    • CBRS_HIDE_INPLACE: Toolbar-ul nu este vizibil.

    Apelul metodei

    BOOL CToolBar::LoadToolBar( UINT nIDResource);
    

    incarca imaginea de tip bitmap specificata de ID-ul resursei create anterior. Apelul metodei

    void CControlBar::EnableDocking( DWORD dwDockStyle); 
    

    stabileste tipurile de dockare pe care le poate executa obiectul de tip CControlBar. Valorile posibile pentru parametrul dwDockStyle sunt:

    • CBRS_ALIGN_TOP: Permite dockarea in partea de sus a zonei client.
    • CBRS_ALIGN_BOTTOM: Permite dockarea in partea de jos a zonei client.
    • CBRS_ALIGN_LEFT: Permite dockarea in partea din stanga a zonei client.
    • CBRS_ALIGN_RIGHT: Permite dockarea in partea din dreapta a zonei client.
    • CBRS_ALIGN_ANY: Permite dockarea in orice parte a zonei client.
    • CBRS_FLOAT_MULTI: Permite obiectului se tip CControlBar sa floteze in acelasi mini frame cu alte obiecte de tip CControlBar.
  • Scriem urmatoarea linie de cod in metoda din clasa ferestrei principale in care vrem sa executam dockarea:

    DockControlBar( &m_toolBar1);
    

    Apelul metodei

    void DockControlBar(CControlBar* pBar, UINT nDockBarID = 0, LPCRECT lpRect = NULL);
    

    are ca efect incercarea de a docka toolbar-ul la una din laturile zonei client a ferestrei principale. Pentru ca operatie de dokare sa se termine cu succes, este necesar ca atat fereastra cat si toolbar-ul sa permita dockarea la o anumita latura. In cazul in care nu se specifica latura dorita, ordinea de incercare este urmatoarea: sus, jos, stanga, dreapta. Optional, parametrul nDockBarID poate specifica latura la care se doreste a se incerca dockarea. Acesta poate avea urmatoarele valori:

    • AFX_IDW_DOCKBAR_TOP: Dockare in partea de sus a zonei client.
    • AFX_IDW_DOCKBAR_BOTTOM: Dockare in partea de jos a zonei client.
    • AFX_IDW_DOCKBAR_LEFT: Dockare in partea din stanga a zonei client.
    • AFX_IDW_DOCKBAR_RIGHT: Dockare in partea din dreapta a zonei client.

    In urma dockarii, obiectul de tip CDockBar asociat laturii la care s-a facut dockarea devine fereastra parinte pentru toolbar. Acest lucru ne poate ajuta sa determinam la un anumit moment la ce latura est dockat toolbar-ul prin urmatoarele linii de cod:

    int parentID = m_toolBar1.GetParent()->GetDlgCtrlID();
    
    switch( parentID)
    {
       case  AFX_IDW_DOCKBAR_TOP:
       // ...
       break;
    
       case  AFX_IDW_DOCKBAR_LEFT:
       // ...
       break;
       
       ...
    }
    

Pana in acest moment, am reusit operatia de dockare a toolbar-ului la una din laturile zonei client. Operatia inversa, de flotare, permite tool bar-ului sa "pluteasca" in propria fereastra. Aceasta se face prin apelul metodei

void CFrameWnd::FloatControlBar( CControlBar * pBar, CPoint point, DWORD dwStyle = CBRS_ALIGN_TOP );

In urma apelului acestei metode este creata o fereastra de tip CMiniDockFrameWnd, care are ca membru un singur obiect de tip CDockBar. Toolbar-ul va fi dockat la acest CDockBar si va umple zona client a mini ferestrei nou create, putand astfel fi tras cu ajutorul mouse-ului. Pentru a verifica daca un obiect de tip CControlBar este flotant, putem apela metoda:

BOOL CControlBar::IsFloating( ) const;

sau putem folosi

int parentID = m_toolBar1.GetParent()->GetDlgCtrlID();

si testa conditia parentID == AFX_IDW_DOCKBAR_FLOAT.

Pentru asigurarea persistentei pozitiei toolbar-ului intre rulari succesive ale aplicatiei se pot folosi metodele CFrameWnd::SaveBarState() si CFrameWnd::LoadBarState() care salveaza respectiv incarca din registrii Windows sau fisierul .ini al aplicatiei starea fiecarui obiect de tip CControlBar detinul de fereastra.

[phpBB Debug] PHP Warning: in file [ROOT]/phpbb/db/driver/mysqli.php on line 317: mysqli_free_result(): Couldn't fetch mysqli_result