VC2010提供了属性控件CMFCPropertyGridProperty对文件、颜色、字体的支持,没有提供对日期选择的支持。
参考了以下两个帖子的内容,创建一个类CMFCPropertyGridDateTimeProperty,继承自CMFCPropertyGridProperty
使用月历控件CMonthCalCtrl让VC2010的CMFCPropertyGridProperty支持日期选择
主要解决了这两个帖子两个问题:
1、第一个帖子用new创建的东东,没有释放,会造成内存泄露。
2、用月历来实现日期选择,要比第二个帖子用对话框更简便、美观一些。
1、创建一个基于对话框的项目PropertyGridTest,去掉了关于对话框。
2、从控件工具栏拖放一个MFCPropertyGrid Control控件,修改属性值Notify为true
3、使用ClassWizard为该控件添加一个public控件变量m_propertyGrid
4、在PropertyGridTestDlg.h头文件增加:
class CPropertyGridTestDlg : public CDialogEx
{
public:
~CPropertyGridTestDlg();
CMFCPropertyGridProperty * pProp[10], *group1,* group2;
};
5、在PropertyGridTestDlg.cpp增加
CPropertyGridTestDlg::CPropertyGridTestDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CPropertyGridTestDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
for(int i=0;i<10;i++)
{
pProp[i]=NULL;
}
group1=group2=NULL;
}
CPropertyGridTestDlg::~CPropertyGridTestDlg()
{
for(int i=0;i<10;i++)
{
if(pProp[i]) delete pProp[i];
}
if(group1) delete group1;
if(group2) delete group2;
}
6、在CPropertyGridTestDlg::OnInitDialog()中插入下列测试代码:
//改变列宽以显示完整的文字
HDITEM item;
item.cxy=200;
item.mask=HDI_WIDTH;
m_propertyGrid.GetHeaderCtrl().SetItem(0, &item);
m_propertyGrid.ModifyStyle(0,WS_CLIPSIBLINGS );
pProp[0] = new CMFCPropertyGridProperty(
_T("普通文字"),
_T("显示正确"),
_T("这是描述部分"));
//m_propertyGrid.AddProperty(pProp[0]);
pProp[1] = new CMFCPropertyGridProperty(
_T("我是不是帅哥?"),
_T("看选项"),
_T(""));
pProp[1]->AddOption(_T("是"));
pProp[1]->AddOption(_T("肯定是"));
pProp[1]->AddOption(_T("绝对是"));
pProp[1]->AllowEdit(FALSE); //不允许对选项进行编辑
//m_propertyGrid.AddProperty(pProp[1]);
pProp[2] = new CMFCPropertyGridColorProperty(
_T("颜色"), RGB(0, 111, 200));
pProp[3] = new CMFCPropertyGridFileProperty(
_T("打开文件"), TRUE, _T("D:\\test.txt"));
LOGFONT font = {NULL};
pProp[4] = new CMFCPropertyGridFontProperty(
_T("选择字体"), font);
group1 = new CMFCPropertyGridProperty(_T("分组1"));
group2 = new CMFCPropertyGridProperty(_T("分组2"));
group1->AddSubItem(pProp[0]);
group1->AddSubItem(pProp[1]);
group2->AddSubItem(pProp[2]);
group2->AddSubItem(pProp[3]);
group2->AddSubItem(pProp[4]);
m_propertyGrid.AddProperty(group1);
m_propertyGrid.AddProperty(group2);
现在可以编译测试了。
接下来完成对日期选择的支持。
1、添加一个头文件MyPropertyGrid.h
//MyPropertyGrid.h
//创建一个类CMFCPropertyGridDateTimeProperty,继承自CMFCPropertyGridProperty
class CMFCPropertyGridDateTimeProperty : public CMFCPropertyGridProperty
{
DECLARE_DYNAMIC(CMFCPropertyGridDateTimeProperty)
// Construction
public:
CMFCPropertyGridDateTimeProperty(const CString& strName, const CString& dtDateTime, DWORD_PTR dwData = 0, LPCTSTR lpszDescr = NULL,BOOL isDate=TRUE);
virtual ~CMFCPropertyGridDateTimeProperty();
// Overrides
public:
virtual void OnClickButton(CPoint point);
CMonthCalCtrl *m_dtCtrl;
CRect rect;
// Attributes
protected:
BOOL m_bIsDate;
CString m_strDateTime;
};
2、添加一个源文件MyPropertyGrid.cpp
// MyPropertyGrid.cpp
//
#include "stdafx.h"
#include "MyPropertyGrid.h"
// CMFCPropertyGridDateTimeProperty object
#define AFX_PROP_HAS_LIST 0x0001
#define AFX_PROP_HAS_BUTTON 0x0002
#define AFX_PROP_HAS_SPIN 0x0004
IMPLEMENT_DYNAMIC(CMFCPropertyGridDateTimeProperty, CMFCPropertyGridProperty)
CMFCPropertyGridDateTimeProperty::CMFCPropertyGridDateTimeProperty(const CString& strName, const CString& strDateTime,
DWORD_PTR dwData, LPCTSTR lpszDescr,BOOL isDate) : CMFCPropertyGridProperty(strName, COleVariant(strDateTime), lpszDescr, dwData)
{
m_dwFlags = AFX_PROP_HAS_LIST;
AllowEdit(true);
m_bIsDate=isDate;
m_dtCtrl=NULL;
rect.left=0;
rect.right=0;
rect.bottom=0;
rect.top=0;
}
CMFCPropertyGridDateTimeProperty::~CMFCPropertyGridDateTimeProperty()
{
if(m_dtCtrl) delete m_dtCtrl;
}
void CMFCPropertyGridDateTimeProperty::OnClickButton(CPoint point)
{
ASSERT_VALID(this);
ASSERT_VALID(m_pWndList);
ASSERT_VALID(m_pWndInPlace);
ASSERT(::IsWindow(m_pWndInPlace->GetSafeHwnd()));
if( m_dtCtrl==NULL )
{
m_dtCtrl= new CMonthCalCtrl;
GetCursorPos(&point);
ScreenToClient(GetActiveWindow(),&point);
rect.left=point.x-265;
rect.right=point.x;
rect.bottom=point.y+260;
rect.top=point.y+16;
m_dtCtrl->Create ( WS_VISIBLE|WS_CHILD|WS_BORDER | MCS_DAYSTATE,
rect, (CWnd *)AfxGetApp()->m_pMainWnd, 200 );
m_dtCtrl->SetWindowPos(NULL,0,0,0,0 ,SWP_NOMOVE|SWP_NOSIZE);
}else
{
delete m_dtCtrl;
m_dtCtrl=NULL;
}
}
pProp[5] = new CMFCPropertyGridDateTimeProperty(_T("日期"),
"2015-01-01", 71 ,"请选择日期",true);
group2->AddSubItem(pProp[5]);
#include "MyPropertyGrid.h"
5、将MyPropertyGrid.h、MyPropertyGrid.cpp加入到项目中
6、为点击月历选择日期增加消息处理函数:
在PropertyGridTestDlg.h中增加函数声明:
public:
void OnSelectMonthcalendar1(NMHDR *pNMHDR, LRESULT *pResult);
BEGIN_MESSAGE_MAP(CPropertyGridTestDlg, CDialogEx)
ON_NOTIFY(MCN_SELECT, 200, &CPropertyGridTestDlg::OnSelectMonthcalendar1)
END_MESSAGE_MAP()
void CPropertyGridTestDlg::OnSelectMonthcalendar1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMSELCHANGE pSelChange = reinterpret_cast<LPNMSELCHANGE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
CString strDate("2016-08-08");
COleDateTime m_dtDateTime;
CMFCPropertyGridDateTimeProperty *p=(CMFCPropertyGridDateTimeProperty*)pProp[5];
p->m_dtCtrl->GetCurSel(m_dtDateTime);
strDate.Format("%s",m_dtDateTime.Format("%Y-%m-%d"));
if(p->m_dtCtrl)
{
delete p->m_dtCtrl;
p->m_dtCtrl=NULL;
}
p->SetValue(strDate);
}
7、编译、运行。。成功
测试环境:Win8.1+VC2010
代码下载:让VC2010的CMFCPropertyGridProperty支持日期选择
运行效果: