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 calls CMFCPropertyGridProperty’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::RemoveSubItem to 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.

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…

Advertisements
  1. Sandeep
    October 14, 2009 at 12:00 pm

    Hi

    Please tell me how to create Dialog box with MFC feature pack without property sheet. Is it possible?

    Feel and look of form is not gud (It is simple just like VB form look)

    Thanks
    Sandeep

  2. Sandeep
    September 9, 2009 at 11:37 am

    Hi

    Please tell me how to create a setup and deployment of mfc feature pack appication to install application on another system.

    Thanks

    • September 10, 2009 at 8:14 pm

      Install the runtime from here -> Runtime – on the target machine. Bundle it along with your installer.

  3. He WANG
    April 9, 2009 at 12:09 am

    thanks, but I got a question. I build a project of Office 2007 style with a property window and a output window on the right and the bottom respectively. When I hide both, they never come out again. I am a rookie of MFC, especially the UI part, so could you show me how to get them out again. This kind of sliding windows are really cool.

  4. Bob J
    January 10, 2009 at 3:11 pm

    Thanks for this: helps muchly.

  5. Esaias
    August 21, 2008 at 9:53 pm

    Hey! I’d like to add properties which can be validated, let’s say I want to display a value where the minumum value is 7 and the max is 10.5. How can I do that? Before saving it in the Document.. I want to be able to validate the data… Thank you!

  6. July 31, 2008 at 4:28 am

    Hi Dan,

    Thanks for your comments!

    Well the screenshot is the result of those two lines on my system at least.

    MFC feature pack has a demo called NewControls, it’s an excellent sample which demostrates these features.

    Tell me if you still have problems!

  7. DanC
    July 30, 2008 at 5:26 pm

    Really helpful code thanks – got this working in no time.

    I’ve a question about a detail in this code which isn’t really to do with the article – the first two lines don’t seem to do anything, at least not if you’re running XP. I can’t actually find a way to get a dialog box to use the Office 2007 styles at all if you’re running XP. My MDI application works fine with them, but any dialog box I launch from it uses the XP style which looks a bit strange. Any ideas how to get a dialog box to use the Office 2007 styles?

  1. January 6, 2011 at 2:46 am
  2. June 28, 2008 at 9:10 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: