VS2012下实现CMFCPropertyGridCtrl 内添加日期时间控件

来源:互联网 发布:植物生长算法程序 编辑:程序博客网 时间:2024/06/05 08:19

         上图为实现的效果图。


         首先自定义一个类CMFCPropertyGridDateTimeProperty,基类是CMFCPropertyGridProperty。

class CMFCPropertyGridDateTimeProperty :public CMFCPropertyGridProperty{DECLARE_DYNAMIC(CMFCPropertyGridDateTimeProperty)public:CMFCPropertyGridDateTimeProperty(const CString& strName, const CString& dtDateTime, LPCTSTR lpszDescr = _T(""), BOOL isDate=TRUE);  virtual ~CMFCPropertyGridDateTimeProperty();// Overrides  public:  virtual BOOL OnClickValue(UINT uiMsg, CPoint point);//鼠标点击属性列表“值”的区域触发此函数CInnerDateTimeCtrl *m_dtCtrl;//自定义CDateTimeCtrl类// Attributes  protected:  BOOL    m_bIsDate;//TRUE: 日期类型; FALSE: 时间类型};

       cpp文件

IMPLEMENT_DYNAMIC(CMFCPropertyGridDateTimeProperty, CMFCPropertyGridProperty)CMFCPropertyGridDateTimeProperty::CMFCPropertyGridDateTimeProperty(const CString& strName, const CString& strDateTime,   LPCTSTR lpszDescr, BOOL isDate) : CMFCPropertyGridProperty(strName, COleVariant(strDateTime), lpszDescr)  {  m_bIsDate=isDate;  m_dtCtrl=NULL;  }CMFCPropertyGridDateTimeProperty::~CMFCPropertyGridDateTimeProperty(void){}BOOL CMFCPropertyGridDateTimeProperty::OnClickValue(UINT uiMsg, CPoint point){ASSERT_VALID(this);// m_pWndInPlace是浮动在属性列表上的编辑框ASSERT_VALID(m_pWndInPlace);  ASSERT(::IsWindow(m_pWndInPlace->GetSafeHwnd()));CString str;m_pWndInPlace->GetWindowText(str);COleDateTime oleTime;CString timeStr;if (!m_bIsDate)timeStr.Format(_T("2016-1-1 %s"), str);elsetimeStr.Format(_T("%s 0:0:0"), str);oleTime.ParseDateTime(timeStr);// m_pWndInPlace的父窗口是CMFCPropertyGridCtrlCWnd *pPropertyCtl = (CWnd*)(m_pWndInPlace->GetParent());// 需要将本CMFCPropertyGridProperty的指针传递给DateTimeCtrl控件m_dtCtrl= new CInnerDateTimeCtrl(this, m_bIsDate);  CRect rect;m_pWndInPlace->GetWindowRect(rect);pPropertyCtl->ScreenToClient(rect);// 将原编辑框隐藏,否则m_dtCtrl不能正确显示m_pWndInPlace->ShowWindow(SW_HIDE);// 调整m_dtCtrl的显示位置rect.top -= 3;rect.bottom += 5;rect.left -= 4;// 设置CDateTimeCtrl的显示类型DWORD dtsStyle = WS_VISIBLE|WS_CHILD|WS_BORDER;if ( !m_bIsDate )dtsStyle |= DTS_TIMEFORMAT;//时间类型elsedtsStyle |= DTS_SHORTDATEFORMAT|DTS_UPDOWN;//日期类型m_dtCtrl->Create (  dtsStyle, rect, pPropertyCtl, 1001 );  ::SetWindowPos(m_dtCtrl->m_hWnd, HWND_TOPMOST, 0,0,0,0 ,SWP_NOMOVE|SWP_NOSIZE);m_dtCtrl->SetTime(oleTime);// 让日期控件获得焦点m_dtCtrl->SetFocus();return TRUE;}

        这里需要注意的是,日期类型在动态创建的时候需要带DTS_UPDOWN参数,原因我后面再说。

下面是自定义的CInnerDateTimeCtrl类,其基类是CDateTimeCtrl。

class CInnerDateTimeCtrl:public CDateTimeCtrl{DECLARE_DYNAMIC(CInnerDateTimeCtrl)public:CInnerDateTimeCtrl(CMFCPropertyGridProperty *editWnd, BOOL isDate=FALSE);virtual ~CInnerDateTimeCtrl();private:CMFCPropertyGridProperty *m_editWnd;BOOL m_isDate;public:DECLARE_MESSAGE_MAP()afx_msg void OnKillFocus(CWnd* pNewWnd);afx_msg void OnNcDestroy();};
cpp文件
// InnerDateTimeCtrlIMPLEMENT_DYNAMIC(CInnerDateTimeCtrl, CDateTimeCtrl)CInnerDateTimeCtrl::CInnerDateTimeCtrl(CMFCPropertyGridProperty *editWnd, BOOL isDate){m_editWnd = editWnd;m_isDate = isDate;}CInnerDateTimeCtrl::~CInnerDateTimeCtrl(){}BEGIN_MESSAGE_MAP(CInnerDateTimeCtrl, CDateTimeCtrl)ON_WM_KILLFOCUS()ON_WM_NCDESTROY()END_MESSAGE_MAP()void CInnerDateTimeCtrl::OnKillFocus(CWnd* pNewWnd){CDateTimeCtrl::OnKillFocus(pNewWnd);// TODO: Add your message handler code hereCOleDateTime oleTime;GetTime(oleTime);CString str = _T("");if ( m_isDate )str = oleTime.Format(_T("%Y-%m-%d"));elsestr = oleTime.Format(_T("%H:%M:%S"));// 修改属性列表的值m_editWnd->SetValue(str);// 自我销毁DestroyWindow();}void CInnerDateTimeCtrl::OnNcDestroy(){CDateTimeCtrl::OnNcDestroy();// TODO: Add your message handler code hereCDateTimeCtrl::OnNcDestroy();// 释放内存delete this;}
这里可以看到日期控件在失去焦点后就自我销毁了,如果是日期类型显示的话,如果不使用DTS_UPDOWN类型,那么创建后控件右侧是一个倒三角的button,点击此button会弹出日历,在日历上选择日期会导致日期控件失去焦点自我销毁,从而导致出错。因此本人为了规避此错误,采用了DTS_UPDOWN类型。


使用此类的方法很简单,头文件中为你的CMFCPropertyGridCtrl声明一个变量m_property。

#include "afxpropertygridctrl.h"

CMFCPropertyGridCtrl m_property;


可以在cpp文件的OnInitDialog函数中加上如下代码:
// 初始化属性列表HDITEM item; item.cxy=100; item.mask = HDI_WIDTH; m_property.GetHeaderCtrl().SetItem(0, &item);CMFCPropertyGridProperty* pGroup1 = new CMFCPropertyGridProperty(_T("属性"));CMFCPropertyGridProperty *item1 = new CMFCPropertyGridDateTimeProperty(_T("日期"),  _T("2016-12-23"), _T("请选择日期"),true);  pGroup1->AddSubItem(item1);CMFCPropertyGridProperty *item2 = new CMFCPropertyGridDateTimeProperty(_T("时间"),  _T("09:00:00"), _T("请选择时间"),false);  pGroup1->AddSubItem(item2);m_property.AddProperty(pGroup1);
好了,实现完毕!
0 0
原创粉丝点击