반응형

http://ntcoder.com/bab/mfc-feature-pack-tutorial-part-3-cmfcpropertygridctrl/

MFC Feature Pack Tutorial – Part 3 – CMFCPropertyGridCtrl

 

It’s a cool new control found in MFC feature pack. Those who’ve used VB, C#, must be familiar with this control. It’s the good old vb property control. This is how the old vb control looked.

It can be called a two column list control with a tree embedded inside it. But it is not just that, here are some properties of this new control…

  1. Allows custom properties
  2. Allows custom controls inside property values
  3. Allows nested properties
  4. Allows font properties
  5. Allows color properties
  6. Fires events when a property is updated
  7. Allows grouping of properties
  8. VS look and feel
  9. Allows custom colors
  10. Allows feedback for properties that has changed, changes text style to bold
  11. One touch expand of all nodes
  12. Allows a toolbar to be placed at the top
  13. Allows boolean properties

So what’s the class name of this new control?

Of course it’s CMFCPropertyGridCtrl.

Basic architecture

Base class of all properties in this control is called CMFCPropertyGridProperty. Derive from this class to add on more properties. Each CMFCPropertyGridProperty can take additional sub properties which in turn again can take further sub properties, which in turn can take further sub properties… So kinda makes a tree structure.

All items get removed in OnDestroy of this control. Every property get’s “delete”d which turn callsCMFCPropertyGridProperty’s destructor which in turn calls child properties destructor which again in turn calls any futher child properties destructor and this goes on for every property in the control.

All properties must be allocated on the heap using “new”. An exception to this rule are nested child properties of CMFCPropertyGridProperty which can be on the stack but make sure that you remove them before the call to OnDestroy of this control, since delete get’s applied to every property and it’s sub property. Also make sure that such an object has sufficient life time. There is an option in CMFCPropertyGridProperty::RemoveSubItemto prevent “delete”ing of such properties.

Adding properties

To add a property to this control we use the function called CMFCPropertyGridCtrl::AddProperty, note that properties should be dynamically allocated, because CMFCPropGridCtrl::OnDestroy uses delete to free properties.

Deleting properties

To remove a property we use the function called CMFCPropertyGridCtrl::DeleteProperty. Note what was said earlier, all properties should be dynamically allocated. Also note that only properties that was directly given to this control will be deleted, sub properties should be deleted via their parent property class only.

Adding sub properties

To add a sub property call CMFCPropertyGridProperty::AddSubItem with the address of the new sub item. It’s up to you to decide whether this sub property should be on the heap or on the stack. If it’s on the stack then make sure you remove such an item before the call to main property grid control’s OnDestroy.

Removing sub properties

All sub properties get removed when the control is destroyed but such properties should be allocated on the heap.

To remove sub properties in between call CMFCPropertyGridProperty::RemoveSubItem. It takes a pointer reference to the item that is to be deleted and optional last boolean parameter which if set will delete given pointer, else won’t.

Show us some code man!

Ok don’t loose your cool, enough of preaching now it’s all practical stuff mate. :P

Here is a function which sets up a simple property grid control. With some properties and some nested properties.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
void CPropertyGridCtrlTestDlg::InitPropGrid()
{
    // Switch look and feel to office 2007 style
    CMFCVisualManagerOffice2007::SetStyle( CMFCVisualManagerOffice2007::Office2007_ObsidianBlack );
    CMFCVisualManager::SetDefaultManager( RUNTIME_CLASS( CMFCVisualManagerOffice2007 ));
 
    CRect Rect;
    m_wndPropListLocation.GetClientRect( Rect );
    m_wndPropListLocation.MapWindowPoints( this, &Rect );
 
    m_wndPropList.Create( WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP, Rect, this, 1231 );
    m_wndPropList.EnableHeaderCtrl( TRUE, _T( "Nibu's Property" ), _T( "Nibu's Value" ));
    m_wndPropList.SetVSDotNetLook( TRUE );
 
    // Create a property group for appearance
    CMFCPropertyGridProperty * pGroupTest = new CMFCPropertyGridProperty( _T( "Group Test" ) );
    m_wndPropList.AddProperty( pGroupTest );
 
    const int MaxNesting = 5;
    CMFCPropertyGridProperty *pParent = pGroupTest;
    for( int Index = 0; Index < MaxNesting; ++Index )
    {
        CString Text;
        Text.Format( _T( "Nesting %d" ), Index + 1 );
 
        CMFCPropertyGridProperty* pParentTemp = new CMFCPropertyGridProperty( Text );
 
        // Display's a combo with options as True, False, Cool!
        COleVariant Bool((short)VARIANT_FALSE, VT_BOOL);
        pParent->AddSubItem(new CMFCPropertyGridProperty(_T("Bool test"), Bool, _T("Testing kids")));
        pParent->AddSubItem( pParentTemp );
        pParent = pParentTemp;
    }
 
    // A font property
    LOGFONT lf = { 0 };
    GetFont()->GetLogFont( &lf );
    CMFCPropertyGridFontProperty* pFntProp = new CMFCPropertyGridFontProperty( _T( "Font (Font dialog comes up)" ), lf );
    pGroupTest->AddSubItem( pFntProp );
 
    // Combo property, set sub options which are displayed in a combo
    CMFCPropertyGridProperty* pCmbProp = new CMFCPropertyGridProperty(_T("Border (A combo box)"), _T("Dialog Frame"), _T("One of: None, Thin, Resizable, or Dialog Frame"));
    pCmbProp->AddOption(_T("None"));
    pCmbProp->AddOption(_T("Thin"));
    pCmbProp->AddOption(_T("Resizable"));
    pCmbProp->AddOption(_T("Dialog Frame"));
    pCmbProp->AllowEdit(FALSE);
    pGroupTest->AddSubItem( pCmbProp );
 
    // A folder browse dialog property
    CMFCPropertyGridFileProperty* pFolderProp = new CMFCPropertyGridFileProperty( _T( "Select folder (Browse for folder dialog)" ), _T( "C:\\Windows" ));
    pGroupTest->AddSubItem( pFolderProp );
 
    // A file open dialog property
    CMFCPropertyGridFileProperty* pFileProp = new CMFCPropertyGridFileProperty( _T( "Select file (Open file dialog)" ), TRUE, _T( "C:\\Windows" ));
    pGroupTest->AddSubItem( pFileProp );
 
    // A masked edit control for phone number
    pGroupTest->AddSubItem( new CMFCPropertyGridProperty(_T("Phone (Masked edit)"), _T("(123) 123-12-12"), _T("Enter a phone number"), 0, _T(" ddd  ddd dd dd"), _T("(___) ___-__-__")));
 
    // A color property
    CMFCPropertyGridColorProperty* pColorProp = new CMFCPropertyGridColorProperty( _T( "Select color" ), RGB( 120, 198, 250 ));
    pGroupTest->AddSubItem( pColorProp );
 
    // Set custom colors for property grid
    m_wndPropList.SetCustomColors(RGB(228, 243, 254), RGB(46, 70, 165), RGB(200, 236, 209), RGB(33, 102, 49), RGB(255, 229, 216), RGB(128, 0, 0), RGB(159, 159, 255));
}

And the output looks like this…

반응형

+ Recent posts