26
Sep
2008

Exemplu de utilizare

In exemplul NewControls este evidentiat modul in care se pot introduce diferite tipuri de proprietati pentru un obiect de tipul CMFCPropertyGridCtrl, de la simple campuri de editare, liste de selectii, selectarea unei culori, la definirea de proprietati derivate (custom). Exemplul nu contine modalitatea de asociere intre diferite variabile abstracte si proprietati, precum si modalitatea de notificare a detinatorului (owner-ului).

In exemplul de mai jos se creeaza obiectul m_wndPropGrid si se specifica o serie de caracteristici ale acestuia.

Organizarea arborescenta a proprietatilor se realizeaza prin intermediul grupurilor de proprietati. In primul grup sunt inserate ca subitem-uri patru proprietati de tipul CMFCPropertyGridDateTimeProperty, doua pentru data, unul cu format specificat de afisare, celalalt cu format implicit si similar doua pentru ora. Al doilea grup contine o proprietate de tip CMFCPropertyGridIPAddressProperty care contine o adresa IP specificata ca valoare iniaiala.

      m_wndPropGrid.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP, rect, this, ID_PROPGRID);
      m_wndPropGrid.EnableHeaderCtrl(FALSE);
      m_wndPropGrid.EnableDescriptionArea();
      m_wndPropGrid.SetVSDotNetLook(TRUE);
      m_wndPropGrid.MarkModifiedProperties(TRUE);
      m_wndPropGrid.SetShowDragContext(TRUE);

      CMFCPropertyGridProperty* pGroup =
                  new CMFCPropertyGridProperty(_T("CMFCPropertyGridDateTimeProperty"));

      COleDateTime dt=COleDateTime::GetCurrentTime();
      pGroup->AddSubItem(new CMFCPropertyGridDateTimeProperty(_T("Data"),dt,
                         _T("Camp de tip data - DROPDOWN"),ID_PROPGRID_DATA,TRUE,FALSE,
                         _T("dd.MM.yyyy"),_T("%d.%m.%Y")));

      pGroup->AddSubItem(new CMFCPropertyGridDateTimeProperty(_T("Data¹"),dt,
                         _T("Camp de tip data - UPDOWN cu format implicit"),
                         ID_PROPGRID_DATA1,TRUE,TRUE));

      pGroup->AddSubItem(new CMFCPropertyGridDateTimeProperty(_T("Ora"),dt,
                         _T("Camp de tip ora cu format specificat"),ID_PROPGRID_ORA,
                         FALSE,TRUE,_T("HH:mm:ss"),_T("%H:%M:%S")));

      pGroup->AddSubItem(new CMFCPropertyGridDateTimeProperty(_T("Ora¹"),dt,
                         _T("Camp de tip ora cu format implicit"),ID_PROPGRID_ORA1,
                         FALSE,TRUE));

      m_wndPropGrid.AddProperty(pGroup);

      pGroup = new CMFCPropertyGridProperty(_T("c"));
      in_addr addr;
      addr.s_addr=inet_addr("192.168.0.1");

      pGroup->AddSubItem(new CMFCPropertyGridIPAdressProperty(_T("Adresa IP"),addr,
                         _T("Adresa IP"),ID_PROPGRID_IP));

      m_wndPropGrid.AddProperty(pGroup);

      // se poate specifica fereastra care primeste mesajele de notificare a schimbarii  
      // valorilor proprietatilor incluse in control
      m_wndPropGrid.SetOwner(this);

Setarea valorilor pentru proprietatile din control se poate realiza atat la initializarea acestora, cat si ulterior in functie de cerintele aplicatiei. Exista mai multe modalitati prin care se poate realiza setarea si extragerea valorilor din proprietati.

Fiecare proprietate poate fi asociata la initializare (in constructor) cu un ID unic specificat in parametrul dwData, iar accesarea directa a proprietatii in functie de ID-ul specificat se realizeaza cu ajutorul functiei FindItemByData.

void CPropGridDlg::Set(void)
{
      CString s;

      CMFCPropertyGridDateTimeProperty *pPropDateTime=NULL;
      pPropDateTime=reinterpret_cast<CMFCPropertyGridDateTimeProperty*>
                                    (m_wndPropGrid.FindItemByData(ID_PROPGRID_DATA));

      pPropDateTime->SetValue(m_campuri.data);
      pPropDateTime->SetOriginalValue(m_campuri.data); // (*)

      CMFCPropertyGridIPAdressProperty *pPropIPAddress=NULL;
      pPropIPAddress=reinterpret_cast<CMFCPropertyGridIPAdressProperty*>
                                    (m_wndPropGrid.FindItemByData(ID_PROPGRID_IP));

      pPropIPAddress->SetValue(ULONG_VARIANT(m_campuri.adresaIP.s_addr));
      pPropIPAddress->SetOriginalValue(ULONG_VARIANT(m_campuri.adresaIP.s_addr));
}

BOOL CPropGridDlg::Get(void)
{
      int ret=0;

      CMFCPropertyGridDateTimeProperty *pPropDateTime=NULL;
      pPropDateTime=reinterpret_cast<CMFCPropertyGridDateTimeProperty*>
                                    (m_wndPropGrid.FindItemByData(ID_PROPGRID_DATA));

      if(pPropDateTime->IsModified())
      {
            m_campuri.data=pPropDateTime->GetValue().date;
            ret++;
      } // (*)

      CMFCPropertyGridIPAdressProperty *pPropIPAddress=NULL;
      pPropIPAddress=reinterpret_cast<CMFCPropertyGridIPAdressProperty*>
                                    (m_wndPropGrid.FindItemByData(ID_PROPGRID_IP));

      if(pPropIPAddress->IsModified())
      {
            m_campuri.adresaIP.s_addr=pPropIPAddress->GetValue().ulVal;
            ret++;
      }

      return ret!=0;
}

(*) – exemplul complet este atasat la articol

O alta modalitate este parcurgerea structurii arborescente a obiectului m_wndPropGrid, cautarea proprietatii dupa numele acesteia si setarea valorii corespunzatoare.

void CPropGridDlg::Set1(void)
{
      CString s;
      CMFCPropertyGridProperty *pPropGrid=NULL,*pPropGridChild=NULL;
      int nrp=m_wndPropGrid.GetPropertyCount(),nrc=0;
      for(int i=0;i<nrp;i++)
      {
            pPropGrid=m_wndPropGrid.GetProperty(i);
            nrc=pPropGrid->GetSubItemsCount();
            for(int j=0;j<nrc;j++)
            {
                  pPropGridChild=pPropGrid->GetSubItem(j);
                  s=pPropGridChild->GetName();
                  if(s==_T("Data"))
                        pPropGridChild->SetValue(m_campuri.data),
                        pPropGridChild->SetOriginalValue(m_campuri.data);

                  // ...
            }
      }
}

BOOL CPropGridDlg::Get1(void)
{
      BOOL ret=FALSE;
      CString s;
      CMFCPropertyGridProperty *pPropGrid=NULL,*pPropGridChild=NULL;

      int nrp=m_wndPropGrid.GetPropertyCount(),nrc=0;
      for(int i=0;i<nrp;i++)

      {
            pPropGrid=m_wndPropGrid.GetProperty(i);
            nrc=pPropGrid->GetSubItemsCount();
            for(int j=0;j<nrc;j++)
            {
                  pPropGridChild=pPropGrid->GetSubItem(j);
                  if(!pPropGridChild->IsModified())
                        continue;

                  s=pPropGridChild->GetName();
                  if(s==_T("Data"))
                        m_campuri.data=pPropGridChild->GetValue().date,ret=TRUE;

                  // ...
            }
      }

      return ret;
}

Figura 1. Exemplu de utilizare pentru proprietati de tip data / timp sau adresa IP.

Exemplu de utilizare pentru proprietati de tip data / timp sau adresa IP
Vezi imaginea la dimenisunea normala

Se poate utiliza mecanismul de notificare al detinatorului (owner-ului) controlului pentru transferul valorilor modificate din proprietati in variabile abstracte asociate. Astfel, utilizarea functiei Get sau Get1 devine inutila. In exemplul de mai jos sunt monitorizate schimbarile valorilor din proprietati (Figura 1).

BEGIN_MESSAGE_MAP(CPropGridDlg, CDialog)
      // ...
      ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED,OnPropGridChanged)
END_MESSAGE_MAP()

LRESULT CPropGridDlg::OnPropGridChanged(WPARAM /*wParam*/, LPARAM lParam)
{
      CMFCPropertyGridProperty* pPropGrid =
                  reinterpret_cast<CMFCPropertyGridProperty*>(lParam);

      if (pPropGrid==NULL)
            return 0L;

//  Actualizare m_campuri la modificarea valorilor poate inlocui utilizarea functiei Get()
//    CString s=pPropGrid->GetName();
//    if(s==_T("Data"))
//          m_campuri.data=pPropGrid->GetValue().date;
//    else
//          if(s==_T("Data¹"))
//                m_campuri.data1=pPropGrid->GetValue().date;
//          else
//                if(s==_T("Ora"))
//                      m_campuri.ora=pPropGrid->GetValue().date;
//                else
//                      if(s==_T("Ora¹"))
//                            m_campuri.ora1=pPropGrid->GetValue().date;
//                      else
//                            if(s==_T("Adresa IP"))
//                                  m_campuri.adresaIP.s_addr=pPropGrid->GetValue().ulVal;

 
      m_sLog.AppendFormat(_T("Campul '%s' a fost modificat: %s\n"),
                  pPropGrid->GetName(), pPropGrid->FormatProperty());

      return 0L;
}

Toate exemplele de cod prezentate in articol sunt incluse intr-un proiect creat in Microsoft Visual Studio 2008.

Concluzii

Visual C++ Feature Pack este o confirmare a faptului ca programarea C++ si in special MFC ramane in actualitate, oferind programatorilor "unmanaged" instrumente pentru crearea de aplicatii cu interfete asemanatoare celor din suita Office 2007, Internet Explorer sau Visual Studio.

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