MFC Feature Pack Tutorial – Part 3 – CMFCPropertyGridCtrl
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…
- Allows custom properties
- Allows custom controls inside property values
- Allows nested properties
- Allows font properties
- Allows color properties
- Fires events when a property is updated
- Allows grouping of properties
- VS look and feel
- Allows custom colors
- Allows feedback for properties that has changed, changes text style to bold
- One touch expand of all nodes
- Allows a toolbar to be placed at the top
- 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.
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…