none
Zugriff auf CMFCPropertyGridProperty Elemente

    Frage

  • Hallo Forum

    Ich habe mich wieder mal auf ein MFC-MDI Projekt eingelassen und festgestellt, dass sich seit meinen Visual C++ 6.0 Zeiten einiges geändert hat. Die von Visual Studio (2010) erstellten MDI Grundgerüste sind wesentlich aufwändiger und natürlich schöner (mit FileView/Classview Bäumen, mit Propertysheets und Debug/Find/Output Logs.

    Mit ein wenig Ausprobieren und viel Doku lesen habe ich mich nun in die MFCProperyGrids eingearbeitet und bin auf folgende Probleme gestoßen:

            CMFCMenuBar       m_wndMenuBar;
    	CMFCToolBar       m_wndToolBar;
    	CMFCStatusBar     m_wndStatusBar;
    	CMFCToolBarImages m_UserImages;
    	CFileView         m_wndFileView;
    	CClassView        m_wndClassView;
    	COutputWnd        m_wndOutput;
    	CPropertiesWnd    m_wndProperties;

    Zunächst erstellt der Wizard im Mainframe eine Menge von zusätzlichen Klassen, die eben für all die neuen Features sorgen. Diese Deklaration erfolgt  jedoch im "protected" Bereich. Wie kann man von anderen Programmteilen auf diese Klassen dann zugreifen? (ich habe mir die Sache vorerst einfach gemacht, und diese einfach "public" erklärt, doch frage ich mich, ob das der von Microsoft vorgesehene Weg ist).

    In weiterer Folge habe ich mich den MFCPropertyGrids angenommen und es alsbald geschafft, ein Dropdown-Element nach eigenem Geschmack einzubauen:

    CMFCPropertyGridProperty* pGroup0 = new CMFCPropertyGridProperty(_T("Diagrams"));
    CMFCPropertyGridProperty* pFiltProp = new CMFCPropertyGridProperty(_T("Filter"), _T("Light"), _T("One of: None, Light, Medium, or Strong"));
    pFiltProp->AddOption(_T("None"));
    pFiltProp->AddOption(_T("Light"));
    pFiltProp->AddOption(_T("Medium"));
    pFiltProp->AddOption(_T("Strong"));
    pFiltProp->AllowEdit(FALSE);
    
    pGroup0->AddSubItem(pFiltProp);
    m_wndPropList.AddProperty(pGroup0);


    Nun kann ich auf dem PropertyGrid ein Filter auswählen, aber wie bekomme ich die Info, was ausgewählt wurde?

    Auch hier bin ich mittlerweile so weit vorgedrungen, dass ich mit GetValue eine Information bekomme:

    CMainFrame* pMainFrm = (CMainFrame*)AfxGetMainWnd(); 
    CMFCPropertyGridProperty *pDiag = pMainFrm->m_wndProperties.GetPropertyList()->GetProperty(0); // Diagrams
    CMFCPropertyGridProperty* pFiltProp = pDiag->GetSubItem(0); // Filter Auswahl
    COleVariant pV = pFiltProp->GetValue();

    Nur in allen Varianten des "COleVariant" Objektes finde ich keine Integervariable, die mir einen Elementeindex liefert. Ich konnte bislang nur das Element 

    pV.bstrVal

    ausfindig machen, das mir als wchar_t den Text des ausgewählten Elements liefert. Dummerweise liefert die Funktion CMFCProperyGridProperty::GetOption aber einen char String, sodass die Methode, das ausgewählte Element durch Vergleich aller Optionselemente mit bstrVal einigermaßen komplex wird und ich mir ziemlich sicher bin, dass es wesentlich einfachere Wege zum Ziel gibt....nur welche?

    COleVariant pV = pFiltProp->GetValue();
    ToAscii(pV.bstrVal,strTmp,32); for (int i = 0; i < pFiltProp->GetOptionCount(); i++) { if (!strcmp(pFiltProp->GetOption(i),strTmp)) { ...
    }
    }


    Grüße

    FireHeart

    Dienstag, 5. Februar 2019 14:55

Antworten

  • Hallo Fire-Heart

    Diese Deklaration erfolgt  jedoch im "protected" Bereich. Wie kann man von anderen Programmteilen auf diese Klassen dann zugreifen? (ich habe mir die Sache vorerst einfach gemacht, und diese einfach "public" erklärt, doch frage ich mich, ob das der von Microsoft vorgesehene Weg ist).

    Von anderen Programmteilen sollte nicht drauf zugegriffen werden, genau darum sind diese auch protected. Dies war aber auch schon unter 6.0 so.

    In weiterer Folge habe ich mich den MFCPropertyGrids angenommen und es alsbald geschafft, ein Dropdown-Element nach eigenem Geschmack einzubauen:

    CMFCPropertyGridProperty* pGroup0 = new CMFCPropertyGridProperty(_T("Diagrams"));
    CMFCPropertyGridProperty* pFiltProp = new CMFCPropertyGridProperty(_T("Filter"), _T("Light"), _T("One of: None, Light, Medium, or Strong"));
    pFiltProp->AddOption(_T("None"));
    pFiltProp->AddOption(_T("Light"));
    pFiltProp->AddOption(_T("Medium"));
    pFiltProp->AddOption(_T("Strong"));
    pFiltProp->AllowEdit(FALSE);
    
    pGroup0->AddSubItem(pFiltProp);
    m_wndPropList.AddProperty(pGroup0);


    Nun kann ich auf dem PropertyGrid ein Filter auswählen, aber wie bekomme ich die Info, was ausgewählt wurde?

    Behandele das OnPropertyChanged Event, damit erhältst Du das entsprechende Property und kannst direkt damit Filtern oder geeignete andere Dinge machen.

    Viel Erfolg.


    - Gruß Florian

    Freitag, 8. Februar 2019 15:28

Alle Antworten

  • Hallo FireHeart,

    Du kannst versuchen, CMFCPropertyGridProperty::OnUpdateValue zu überschreiben und FALSE zurückzugeben, wenn das Fenstertext mit direkter Bearbeitung außerhalb des Bereichs liegt, wie in diesem Artikel beschrieben:
    CMFCPropertyGridCtrl ValidateData
    Ausführlichere Informationen über CMFCPropertyGridProperty entsprechend Deinen Anforderungen findest Du hier:
    CMFCPropertyGridCtrl: How to Validate and Update Data?

    Gruß,

    Ivan Dragov


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.


    Mittwoch, 6. Februar 2019 13:10
    Moderator
  • Hallo Fire-Heart

    Diese Deklaration erfolgt  jedoch im "protected" Bereich. Wie kann man von anderen Programmteilen auf diese Klassen dann zugreifen? (ich habe mir die Sache vorerst einfach gemacht, und diese einfach "public" erklärt, doch frage ich mich, ob das der von Microsoft vorgesehene Weg ist).

    Von anderen Programmteilen sollte nicht drauf zugegriffen werden, genau darum sind diese auch protected. Dies war aber auch schon unter 6.0 so.

    In weiterer Folge habe ich mich den MFCPropertyGrids angenommen und es alsbald geschafft, ein Dropdown-Element nach eigenem Geschmack einzubauen:

    CMFCPropertyGridProperty* pGroup0 = new CMFCPropertyGridProperty(_T("Diagrams"));
    CMFCPropertyGridProperty* pFiltProp = new CMFCPropertyGridProperty(_T("Filter"), _T("Light"), _T("One of: None, Light, Medium, or Strong"));
    pFiltProp->AddOption(_T("None"));
    pFiltProp->AddOption(_T("Light"));
    pFiltProp->AddOption(_T("Medium"));
    pFiltProp->AddOption(_T("Strong"));
    pFiltProp->AllowEdit(FALSE);
    
    pGroup0->AddSubItem(pFiltProp);
    m_wndPropList.AddProperty(pGroup0);


    Nun kann ich auf dem PropertyGrid ein Filter auswählen, aber wie bekomme ich die Info, was ausgewählt wurde?

    Behandele das OnPropertyChanged Event, damit erhältst Du das entsprechende Property und kannst direkt damit Filtern oder geeignete andere Dinge machen.

    Viel Erfolg.


    - Gruß Florian

    Freitag, 8. Februar 2019 15:28
  • Hallo Florian

    Irgendwie verfranze ich mich bei dem Thema mit Tante Google. Ist das OnPropertyChanged eine Message oder tatsächlich ein Event? Wie sieht das konkret dann aus?

    Grüße

    FireHeart

    Dienstag, 12. Februar 2019 06:51
  • OnPropertyChanged ist eine Message, bzw. du behandelst die Message, diese wird durch das Ereignis(Event) "Property Changed" ausgelöst.

    Sieh Dir die Links von Ivan Dragov an, dort ist es mit Eintrag in der Message Map gezeigt.


    - Gruß Florian

    Dienstag, 12. Februar 2019 07:42