CDateTimeUI是duilib里选择日期的控件,继承于CLabelUI控件,用于记录已经选择的日期,选择控件则是调用win32的日期选择控件。

CDateTimeUI包含两个类,一个是CDateTimeUI,另一个是CDateTimeWnd。

CDateTimeWnd是创建win32日期控件的类,父类是CWindowWnd。

实现代码如下:

#define DT_NONE   0
#define DT_UPDATE 1
#define DT_DELETE 2
#define DT_KEEP   3class CDateTimeWnd : public CWindowWnd{public:CDateTimeWnd();void Init(CDateTimeUI* pOwner);RECT CalPos();LPCTSTR GetWindowClassName() const;LPCTSTR GetSuperClassName() const;void OnFinalMessage(HWND hWnd);LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);protected:CDateTimeUI* m_pOwner;HBRUSH m_hBkBrush;bool m_bInit;};CDateTimeWnd::CDateTimeWnd() : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false){}void CDateTimeWnd::Init(CDateTimeUI* pOwner){m_pOwner = pOwner;m_pOwner->m_nDTUpdateFlag = DT_NONE;if (m_hWnd == NULL){RECT rcPos = CalPos();UINT uStyle = WS_CHILD;Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);SetWindowFont(m_hWnd, m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->hFont, TRUE);}if (m_pOwner->GetText().IsEmpty())::GetLocalTime(&m_pOwner->m_sysTime);::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);::SetFocus(m_hWnd);m_bInit = true;    }//获取控件应该显示的位置,一般是父窗口的位置,如果父窗口不显示则当前win32日期控件也不显示
    RECT CDateTimeWnd::CalPos(){CDuiRect rcPos = m_pOwner->GetPos();CControlUI* pParent = m_pOwner;RECT rcParent;while( pParent = pParent->GetParent() ) {if( !pParent->IsVisible() ) {rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;break;}rcParent = pParent->GetPos();if( !::IntersectRect(&rcPos, &rcPos, &rcParent) ) {rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;break;}}return rcPos;}LPCTSTR CDateTimeWnd::GetWindowClassName() const{return _T("DateTimeWnd");}//设置控件类名LPCTSTR CDateTimeWnd::GetSuperClassName() const{return DATETIMEPICK_CLASS;}void CDateTimeWnd::OnFinalMessage(HWND /*hWnd*/){// Clear reference and dieif( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);m_pOwner->m_pWindow = NULL;delete this;}LRESULT CDateTimeWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam){LRESULT lRes = 0;BOOL bHandled = TRUE;if( uMsg == WM_NOTIFY){::SetFocus(m_hWnd);}if( uMsg == WM_KILLFOCUS ){        //失去焦点就关闭当前win32日期控件
            POINT pt;::GetCursorPos(&pt); RECT rcWnd;::GetWindowRect(m_hWnd,&rcWnd);if(    !( pt.x >= rcWnd.left && pt.x <= rcWnd.right )||!( pt.x >= rcWnd.top && pt.x <= rcWnd.bottom )){lRes= OnKillFocus(uMsg,wParam, lParam,bHandled);}}else if (uMsg == WM_KEYUP && (wParam == VK_ESCAPE)){//esc键按下则不保存当前已选择的日期LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);m_pOwner->m_nDTUpdateFlag = DT_KEEP;PostMessage(WM_CLOSE);return lRes;}else if (uMsg == WM_KEYUP && (wParam == VK_RETURN)){//回车键按下就当做失去焦点处理
            PostMessage(WM_KILLFOCUS);return 0;}else bHandled = FALSE;if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);return lRes;}LRESULT CDateTimeWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){LRESULT lRes = ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);if (m_pOwner->m_nDTUpdateFlag == DT_NONE){::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);m_pOwner->m_nDTUpdateFlag = DT_UPDATE;m_pOwner->UpdateText();}PostMessage(WM_CLOSE);return lRes;}

此类Init代码用来显示win32日期控件,创建一个大小和CDateTimeUI大小一样的控件显示在CDateTimeUI上面。当此控件失去焦点后将选择的日期显示在CDateTimeUI控件上。

CDateTimeUI控件继承于CLabelUI。

头文件:

/// 时间选择控件class UILIB_API CDateTimeUI : public CLabelUI{friend class CDateTimeWnd;public:CDateTimeUI();LPCTSTR GetClass() const;LPVOID GetInterface(LPCTSTR pstrName);SYSTEMTIME& GetTime();void SetTime(SYSTEMTIME* pst);void SetReadOnly(bool bReadOnly);bool IsReadOnly() const;void UpdateText();void DoEvent(TEventUI& event);protected:SYSTEMTIME m_sysTime;int        m_nDTUpdateFlag;bool       m_bReadOnly;CDateTimeWnd* m_pWindow;};

源文件:

////
    CDateTimeUI::CDateTimeUI(){::GetLocalTime(&m_sysTime);m_bReadOnly = false;m_pWindow = NULL;m_nDTUpdateFlag=DT_UPDATE;UpdateText();m_nDTUpdateFlag = DT_NONE;}LPCTSTR CDateTimeUI::GetClass() const{return _T("DateTimeUI");}LPVOID CDateTimeUI::GetInterface(LPCTSTR pstrName){if( _tcscmp(pstrName, DUI_CTR_DATETIME) == 0 ) return static_cast<CDateTimeUI*>(this);return CLabelUI::GetInterface(pstrName);}SYSTEMTIME& CDateTimeUI::GetTime(){return m_sysTime;}void CDateTimeUI::SetTime(SYSTEMTIME* pst){m_sysTime = *pst;Invalidate();}void CDateTimeUI::SetReadOnly(bool bReadOnly){m_bReadOnly = bReadOnly;Invalidate();}bool CDateTimeUI::IsReadOnly() const{return m_bReadOnly;}void CDateTimeUI::UpdateText(){if (m_nDTUpdateFlag == DT_DELETE)SetText(_T(""));else if (m_nDTUpdateFlag == DT_UPDATE){CDuiString sText;sText.SmallFormat(_T("%4d-%02d-%02d"),m_sysTime.wYear, m_sysTime.wMonth, m_sysTime.wDay, m_sysTime.wHour, m_sysTime.wMinute);SetText(sText);}}void CDateTimeUI::DoEvent(TEventUI& event){if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {if( m_pParent != NULL ) m_pParent->DoEvent(event);else CLabelUI::DoEvent(event);return;}if( event.Type == UIEVENT_SETCURSOR && IsEnabled() ){::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)));return;}if( event.Type == UIEVENT_WINDOWSIZE ){if( m_pWindow != NULL ) m_pManager->SetFocusNeeded(this);}if( event.Type == UIEVENT_SCROLLWHEEL ){if( m_pWindow != NULL ) return;}if( event.Type == UIEVENT_SETFOCUS && IsEnabled() ) {//有焦点了就显示日期选择窗口if( m_pWindow ) return;m_pWindow = new CDateTimeWnd();ASSERT(m_pWindow);m_pWindow->Init(this);m_pWindow->ShowWindow();}if( event.Type == UIEVENT_KILLFOCUS && IsEnabled() ) {Invalidate();}if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK || event.Type == UIEVENT_RBUTTONDOWN) {//鼠标按下就显示日期选择窗口if( IsEnabled() ) {GetManager()->ReleaseCapture();if( IsFocused() && m_pWindow == NULL ){m_pWindow = new CDateTimeWnd();ASSERT(m_pWindow);}if( m_pWindow != NULL ){m_pWindow->Init(this);m_pWindow->ShowWindow();}}return;}if( event.Type == UIEVENT_MOUSEMOVE ) {return;}if( event.Type == UIEVENT_BUTTONUP ) {return;}if( event.Type == UIEVENT_CONTEXTMENU ){return;}if( event.Type == UIEVENT_MOUSEENTER ){return;}if( event.Type == UIEVENT_MOUSELEAVE ){return;}CLabelUI::DoEvent(event);}

当控件获得焦点时则调用CDateTimeWnd类,然后显示出来,根据控件内的文字设置CDateTimeWnd的初始日期。

转载于:https://www.cnblogs.com/Reyzal/p/5137240.html

CDateTimeUI类源码分析相关推荐

  1. 02.并发编程(2)Thread类源码分析

    概述 在说线程之前先说下进程,进程和线程都是一个时间段的描述,是CPU工作时间段的描述. 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位.每一 ...

  2. java vector实现的接口_java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析...

    java面试中经常被问到list常用的类以及内部实现机制,平时开发也经常用到list集合类,因此做一个源码级别的分析和比较之间的差异. 首先看一下List接口的的继承关系: list接口继承Colle ...

  3. java.lang.object源码_第三篇:java.lang.Object 类源码分析

    Object所包含的方法如下: ① public Object(); 构造函数: 大部分情况下,类对象的声明,都是通过构造函数完成的(Java中规定:在类定义过程中,对于未定义构造函数的类,默认会有一 ...

  4. Java 8 中 GZIPInputStream 类源码分析

    这是<水煮 JDK 源码>系列 的第4篇文章,计划撰写100篇关于JDK源码相关的文章 GZIPInputStream 类位于 java.util.zip 包下,继承于 InflaterI ...

  5. [Python-Twisted] 协议基类源码分析。

    学习Twisted时,有时老感觉摸不着边际,虽然说要用什么twisted都给你实现了,但心里总有不踏实之感. 遂从twisted.internet.protocol.Protocol这个所有协议的基类 ...

  6. MapReduce框架Mapper和Reducer类源码分析

    一:Mapper类 在Hadoop的mapper类中,有4个主要的函数,分别是:setup,cleanup,map,run.代码如下: protected void setup(Context con ...

  7. java.lang中String类源码分析

    一.类 public final class String:final关键字说明String类不能被修改(不能被其他类继承和重写) public final class Stringimplement ...

  8. 深入理解Spark 2.1 Core (十四):securityManager 类源码分析

    securityManager主要用于权限设置,比如在使用yarn作为资源调度框架时,用于生成secret key进行登录.该类默认只用一个实例,所以的app使用同一个实例,下面是该类的所有源代码: ...

  9. 深入理解Spark 2.1 Core (十三):sparkEnv类源码分析

    sparkEnv为运行的Spark实例(master,worker,executor等)持有运行环境相关的对象,sparkenv管理serializer, Akka actor system, blo ...

最新文章

  1. 词向量, BERT, ALBERT, XLNet全面解析(ALBERT第一作者亲自讲解)
  2. android 动态设置padding,Android动态设置控件大小以及设定margin以及padding值
  3. ActiveMQ_3Java实现
  4. deepin v20.1折腾美化之Plank dock任务栏安装
  5. 利用lrz、lsz工具在linux与windows之间传输文件
  6. Verilog中fork...join 的用法
  7. 【转载】网易将军令工作原理
  8. 区域卫生数据用于临床疗效分析的可用性研究
  9. Dom4j解析Xml文件,Dom4j创建Xml文件
  10. 集成学习—Adaboost(论文研读)
  11. 退休后能领到4000元以上的养老保险金处于什么水平呢?
  12. asp.net mvc(九)
  13. 【NOIP2010】【codevs1069】关押罪犯(并查集补集,拆点)
  14. Go语言中正则表达式的使用
  15. WPF-创建超链接文本
  16. 中国地产商寻找下一个春天
  17. HtmlHelper、TagHelper、局部视图、视图组件
  18. 拿下 ACM 金牌!
  19. Python给定两个有序整数数组nums1和nums2,合并nums1和nums2为数组nums1
  20. CABasicAnimation,CAKeyframeAnimation,CATransition,CAAnimationGroup,UIBezierPath之间做动画的不同点和各自的使用范围。

热门文章

  1. ASP.net(C#)]用DataSet进入对数据源的插入数据、更新数据及刪除数据
  2. ueditor跨域上传图片文件(基于jsp框架、tomcat)
  3. [读书笔记] 敏捷软件开发:原则、模式与实践
  4. 图论算法(四)--最小生成树的Kruskal [ 加边 ] 、Prim [ 加点 ] 的解法(JAVA)
  5. 在java中对null的理解
  6. java 计算26个字母在一段文本中出现的频率(保留小数点后4位)
  7. php按id获取整条数据库,Ajax取得数据库的json值,想通过id获取对应信息,但是都默认获取第一条了...
  8. python调用numpy视频_Numpy的文件输入和输出使用
  9. cfree运行程序错误_C/C++程序调试和内存检测
  10. python实例化次数怎么算,我需要一个Python类来跟踪它被实例化的次数