MFCPropertyGridCtrl是VC2008引入的控件,是MFC中功能比较抢到的控件之一。这篇博客将详细介绍空间的使用,包括空间的属性、方法、类的继承、点击、编辑、事件等,希望能有帮助。

–官方手册–

1. MFCPropertyGridCtrl简介

MFCPropertyGridCtrl的外观如下图所示,主要由三部分组成:表头、属性、描述。对于属性,可以进行分组,每一组可以由多个不同属性组成,可以接受(不局限于)一下几项:颜色、字体、文件、选项等。

2. MFCPropertyGridCtrl的属性

选中控件,F4插卡属性,会弹出左边的属性窗口,可以简单控制控件的一些外观和行为:

Description Rows Count 描述部分的行数
Enable Description Area 是否启用描述功能
Enable Header 是否启用表头
Notify 是否允许编辑
Mark Modified Properties 是否着重显示修改
Use Alphabetic mode 启用该模式将按字母排列,不分组

 

3. 更改表头宽度

刚创建的空间,Property模式只有5pixel,我们需要添加一段代码来改变Property的宽度,让属性能够显示正常。

	HDITEM item;
	item.cxy = 120;
	item.mask = HDI_WIDTH;
	m_properaty.GetHeaderCtrl().SetItem(0, new HDITEM(item));

4. 添加属性和分组

4.1 添加属性

CMFCPropertyGridProperty pProp1 = new CMFCPropertyGridProperty(  
        _T("天朝适合生存吗?"),    
        _T("51CTO不谈政治"),    
        _T("这是描述部分"));     
   
m_propertyGrid.AddProperty(pProp1);   

4.2 添加下拉菜单

CMFCPropertyGridProperty* pProp2 = new CMFCPropertyGridProperty(  
    _T("我是不是帅哥?"),    
    _T("看选项"),   
    _T(""));   
  
pProp2->AddOption(_T("是"));   
pProp2->AddOption(_T("肯定是"));   
pProp2->AddOption(_T("绝对是"));   
pProp2->AllowEdit(FALSE);  //不允许对选项进行编辑  
  
m_propertyGrid.AddProperty(pProp2);

4.3 添加颜色、文件、字体

CMFCPropertyGridColorProperty * pProp3 = new CMFCPropertyGridColorProperty(   
    _T("颜色"), RGB(0, 111, 200));   
m_propertyGrid.AddProperty(pProp3);   
  
CMFCPropertyGridFileProperty * pProp4 = new CMFCPropertyGridFileProperty(  
    _T("打开文件"), TRUE, _T("D://test.txt"));   
m_propertyGrid.AddProperty(pProp4);   
  
LOGFONT font = {NULL};   
  
CMFCPropertyGridFontProperty * pProp5 = new CMFCPropertyGridFontProperty(  
    _T("选择字体"), font);   
  
m_propertyGrid.AddProperty(pProp5);

4.4 添加分组

CMFCPropertyGridProperty * group1 = new CMFCPropertyGridProperty(_T("分组1"));   
CMFCPropertyGridProperty * group2 = new CMFCPropertyGridProperty(_T("分组2"));   
  
group1->AddSubItem(pProp1);   
group1->AddSubItem(pProp2);   
group2->AddSubItem(pProp3);   
group2->AddSubItem(pProp4);   
group2->AddSubItem(pProp5);   
  
m_propertyGrid.AddProperty(group1);   
m_propertyGrid.AddProperty(group2);  

5. MFCPropertyGridCtrl控件的内建函数

5.1 控件的创建

CMFCPropertyGridCtrl * propertyGrid = new CMFCPropertyGridCtrl;   
propertyGrid->Create(WS_CHILD | WS_BORDER | WS_VISIBLE, CRect(400, 100, 600, 200), this, WM_USER + 100);   
propertyGrid->EnableHeaderCtrl(TRUE);  //使用表头   
propertyGrid->SetVSDotNetLook();  //使用样式   
propertyGrid->MarkModifiedProperties(); //着重显示更改过的部分

5.2 清除所有属性

相当与控件复位

m_properaty.RemoveAll();

5.3 删除指定属性

CMFCPropertyGridProperty *pDelete;
int iCount=m_propertyGrid.GetPropertyCount();
if (iCount>0)
{
    pDelete=m_propertyGrid.GetProperty(0);
    m_propertyGrid.DeleteProperty(pDelete);
}

5.4 依次删除属性

int iCount=m_propertyGrid.GetPropertyCount();
CMFCPropertyGridProperty *pDelete;
for (int i=iCount-1;i>=0;i--)
{
    pDelete=m_propertyGrid.GetProperty(i);
    m_propertyGrid.DeleteProperty(pDelete);
}

5.5 数据读写

//读:         
                CMFCPropertyGridProperty *pSelected;
		pSelected=m_propertyGrid.GetProperty(2)->GetSubItem(0);
		COleVariant var=pSelected->GetValue();
                float f1=var.fltVal;
//写:         
                pSelected->SetValue(var);

5.6 设置为初始值

pProp->ResetOriginalValue();

5.7 读取值、初值、名字、ID

GetData得到的值常常作为属性编号,用来区分控件

	CMFCPropertyGridProperty* pProp = (CMFCPropertyGridProperty*)lParam;
	int i = (int)pProp->GetData();
	CString s = pProp->GetName();
	COleVariant t = pProp->GetValue();
	t = pProp->GetOriginalValue();
	CString d;
	d = t.bstrVal;

5.8 选择设置值

调用对应的Sel和Set方法

6. MFCPropertyGridPropery子类

  • CCheckBoxProp
  • CPasswordProp
  • CSliderProp
  • CBoundedNumberPairProp
  • CBoundedNumberSubProp
  • CIconListProp
  • CComboBoxExProp
  • COwnerDrawDescrProp
  • CTwoButtonsProp
  • CCustomDlgProp

7. MFCPropertyGridCtrl获取用户输入值

CMFCPropertyGridProperty *pProperty;//定义一个指向子项的指针
//输入重定向   
pProperty=pGroup11->GetSubItem(0) ;//获得子项的指针
// pGroup11在对话框头文件中定义(公有成员变量)
const COleVariant &strValue=pProperty->GetValue();//获得子项值
CString strTmp =(CString)strValue;
MessageBox( strTmp);

8. MFCPropertyGridCtrl属性改变事件

.h中加入

afx_msg LRESULT OnPropertyChanged(WPARAM, LPARAM);

.cpp中加入ON_REGISTERED_MESSAGE

//注册消息, AFX_WM_PROPERTY_CHANGED:发送ctrl消息到父窗口
BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
 ON_WM_PAINT()
 ON_WM_CREATE()
 ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPropertyChanged)
END_MESSAGE_MAP()

然后添加函数 OnPropertyChanged

如果使用GetData的值作为空间ID来进行判断,则必须要在创建控件时手动SetData来设置ID,否则默认都是0

//用于区分Prop, 使用SetData, GetData方法
//CMFCPropertyGridProperty* pProp1 = new CMFCPropertyGridProperty(strTitle, (_variant_t)bVal, strDesc);
//pProp1->SetData(100);
//int nPropId = pProp1->GetData();

//消息处理, lParam是Property属性项, wParam是ctrl的id
LRESULT CWorkspaceBar::OnPropertyChanged (WPARAM,LPARAM lParam)
{
CMFCPropertyGridProperty* pProp = (CMFCPropertyGridProperty*) lParam;
BOOL bResetMDIChild = FALSE;
switch ((int) pProp->GetData ())
{
   case :pProp->GetValue(); break ;
   }

}

这里根据情况,还可以这样写:

LRESULT CCMFCPGCtrlDlg::OnPropertyChanged (WPARAM,LPARAM lParam) {   
    CMFCPropertyGridProperty* pProp = (CMFCPropertyGridProperty*) lParam; 
    int id = (int) pProp->GetData ();     
    CString s = pProp->GetName();  //被改变的参数名  
    COleVariant t = pProp->GetValue(); //改变之后的值  
    t = pProp->GetOriginalValue();  //改变之前的值  
    CString d;     
    d = t.bstrVal;      //从COleVariant到CString  
    return 0; 
}

还有就是可能需要做类型检查的情况

LRESULT CMyWnd::OnPropertyChanged( WPARAM wParam,LPARAM lParam )
{
 CMFCPropertyGridProperty* pProp = (CMFCPropertyGridProperty*) lParam;
 //is the property ctrl
 if ( (long)wParam == 2 )
 { 
 }
 pProp->SetValue((_variant_t)false);
 pProp->Redraw();
 int pID = pProp->GetData();
 CString str = pProp->GetName();
 if ( str == _T("abc") )
 {
  COleVariant var = pProp->GetValue();
  if ( var.boolVal == VARIANT_TRUE )
  {
   //AfxMessageBox(L"failed!");

   //pProp->SetValue(VARIANT_FALSE);
  }
 }
 if  (pID == 1)
 {
 }
 if  (pID > 1)
 {
 }
 return 0;
}

所有详细都会汇总到这个函数里,所以需要做手工判断

最后再贴一遍官方手册:–官方手册– 

 

 

发表评论

邮箱地址不会被公开。 必填项已用*标注