colincaprani.com

Structural Engineering, Bridge Research, Programming, and more…

Entries Comments


Getting properties from CMFCPropertyGridProperty

2 September, 2011 (02:15) | General

It’s been a while…but this is a good one – if it is what you need!

In Visual C++, the MFC Feature Pack gives the property grid control, but one of the questions regularly asked (see stackoverflow.com) is how to return properties once changes by the user. Part of the problem is the COLEVariant is the return type from the framework, but what if you want a double, or CString for example?

I bashed together a few different ideas and have a nice little functoid that essentially overloads the output type and so this can be used as an argument to your function. The references I used were

I defined the functoid in the header file for the CPropertiesWnd class (which contains the CMFCPropertyGridProperty control) as:

1
2
3
4
5
6
7
8
9
10
11
12
class getPropValue
{
public:
    getPropValue(CMFCPropertyGridProperty* pProp):m_pProp(pProp) {};
    operator CString()        {return (LPCTSTR)(_bstr_t)m_pProp->GetValue();}
    operator int()            {return m_pProp->GetValue().iVal;}
    operator unsigned int()   {return (unsigned int)m_pProp->GetValue().iVal;}
    operator double()         {return m_pProp->GetValue().dblVal;}
    operator bool()           {return m_pProp->GetValue().boolVal == VARIANT_TRUE;}
private:
    CMFCPropertyGridProperty* m_pProp;
};

An example call using this is then:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LRESULT CPropertiesWnd::OnWindowPropertyChanged(WPARAM wparam, LPARAM lparam)
{
    CMFCPropertyGridProperty *pProp = (CMFCPropertyGridProperty*)lparam;
    if (!pProp) return 0;
    CMyView* pView = getActiveView();  // Helper function uses CMainframe
    const int id = (int)pProp->GetData();  // storing property id as a DWORD using SetData
    switch(id)
    {
    case idWindow_OverallScale:
        pView->setScale( getPropValue(pProp) );    // double as an argument to func
        break;
    case idWindow_PenWidth:
        pView->setPenWidth( getPropValue(pProp) ); // int as an argument to func
        break;
    case idWindow_Title:
        pView->setTitle( getPropValue(pProp) );    // CString as an argument to func
        break;
    }
}

There you have it – it could be exactly what you need, or maybe not!

«

  »

Comments

Comment from Daniel
Time: 26 July, 2012, 18:59

This is a really nice solution! Very elegant. You might want to add that ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnWindowPropertyChanged) is also needed, and for completeness you can add operator unsigned long() {return m_pProp->GetValue().lVal;} to handle DWORDs, which CMFCPropertyGridColorProperty uses. Also, all of these member functions can be marked as const!

Write a comment