使用月历控件CMonthCalCtrl让VC2010的CMFCPropertyGridProperty支持日期选择

VC2010提供了属性控件CMFCPropertyGridProperty对文件、颜色、字体的支持,没有提供对日期选择的支持。

参考了以下两个帖子的内容,创建一个类CMFCPropertyGridDateTimeProperty,继承自CMFCPropertyGridProperty

使用月历控件CMonthCalCtrl让VC2010的CMFCPropertyGridProperty支持日期选择

主要解决了这两个帖子两个问题:

1、第一个帖子用new创建的东东,没有释放,会造成内存泄露。

2、用月历来实现日期选择,要比第二个帖子用对话框更简便、美观一些。


CMFCPropertyGridCtrl的简单教程

让VC2010的PropertyGrid支持日期下拉选择


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;
	}
}
3、在CPropertyGridTestDlg::OnInitDialog()中添加:
	pProp[5] = new CMFCPropertyGridDateTimeProperty(_T("日期"),
		"2015-01-01", 71 ,"请选择日期",true);
	group2->AddSubItem(pProp[5]); 
4、在PropertyGridTestDlg.cpp文件开头加入

#include "MyPropertyGrid.h"

5、将MyPropertyGrid.h、MyPropertyGrid.cpp加入到项目中

6、为点击月历选择日期增加消息处理函数:

PropertyGridTestDlg.h中增加函数声明:

public:
	void OnSelectMonthcalendar1(NMHDR *pNMHDR, LRESULT *pResult);


PropertyGridTestDlg.cpp中增加消息映射及函数定义:
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支持日期选择

运行效果:









评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值