用Duilib界面库开发的一个日历控件

时间2013-03-04 17:04:00  博客园精华区 原文  http://www.cnblogs.com/sunsmile/archive/2013/03/04/ningmengxiu1.html

最近应领导要求,再搞一个基于安全的办公自动化系统,基于一些考虑,需要使用C/S架构实现,估考虑使用Duilib这一免费开源的利器,在业务功能实现上,办公自动化少不了日历控件的使用,在网上寻了半天,没有好的开源的日历控件,更多的是web版的日历控件,估决定参考web版的日历控件,使用duilib实现一个winform版的日历,在网上找到的比较炫的一个日历如下:

MFC加载duilib界面_第1张图片

做web开发的朋友可以在这里找到此控件:

http://www.open-open.com/ajax/ajax20091109225817.htm

下面我们使用Duilib实现winform版的日历控件:

a、将其web版的资源文件,主要是图片,下载到本地;

b、编写duilib需要使用到的xml文件,Calendar.xml;

 View Code

 1  2  3      4          5              6              7              8             9             10             11             12             13             14             15             16             17             18             19             20             21           22             23         24         25             26             27             28             29             30             31             32         33         34             35             36             37             38             39             40             41             42             43             44             45             46             47             48             49             50             51             52             53             54             55             56             57             58             59             60             61             62             63             64             65             66             67             68             69             70             71             72             73             74             75             76             77         78         79             80             81             82             83             84             85             86         87     88 

c、代码实现如下:

 View Code

  1 // App.cpp : Defines the entry point for the application.  2 //  3   4 #include "stdafx.h"  5 //#include "systdate.h"  6 #include   7   8 class CFrameWindowWnd : public CWindowWnd, public INotifyUI  9 { 10 public: 11     CFrameWindowWnd() { }; 12     LPCTSTR GetWindowClassName() const { return _T("UIMainFrame"); }; 13     //UINT GetClassStyle() const { return UI_CLASSSTYLE_FRAME | CS_DBLCLKS; }; 14     UINT GetClassStyle() const { return CS_DBLCLKS; }; 15     void OnFinalMessage(HWND /*hWnd*/) { delete this; }; 16  17     void Init() {} 18  19     void OnPrepare() 
 20     { 21         ::GetLocalTime(&m_sysTime); 22         DrawCalendar(m_sysTime); 23     } 24  25     void Notify(TNotifyUI& msg) 26     { 27         if( msg.sType == _T("windowinit") ) OnPrepare(); 28         else if( msg.sType == _T("return") ) 
 29         { 30             m_sysTime.wYear  = SetTxtYear(0); 31             m_sysTime.wMonth  = GetCmbMonth(); 32             DrawCalendar(m_sysTime); 33         } 34         else if( msg.sType == _T("click") ) 
 35         { 36             CControlUI* pOne = static_cast(m_pm.FindControl(msg.ptMouse)); 37             if (_tcsicmp(pOne->GetClass(), _T("ButtonUI")) == 0) 38             { 39                 //上一月 40                 if (_tcsicmp(pOne->GetName(), _T("BTN_UP_MONTH")) == 0)  
 41                 { 42                     m_sysTime.wMonth = m_sysTime.wMonth-1 == 0 ? 12 : m_sysTime.wMonth-1; 43                     DrawCalendar(m_sysTime); 44                 } 45                 //上一年 46                 else if (_tcsicmp(pOne->GetName(), _T("BTN_UP_YEAR")) == 0)  
 47                 { 48                     m_sysTime.wYear  = SetTxtYear(-1); 49                     m_sysTime.wMonth  = GetCmbMonth(); 50                     DrawCalendar(m_sysTime); 51                 } 52                 //下一年 53                 else if (_tcsicmp(pOne->GetName(), _T("BTN_DOWN_YEAR")) == 0)  
 54                 { 55                     m_sysTime.wYear  = SetTxtYear(1); 56                     m_sysTime.wMonth  = GetCmbMonth(); 57                     DrawCalendar(m_sysTime); 58                 } 59             } 60         } 61         else if( msg.sType == _T("itemselect") ) { 62             if (_tcsicmp(msg.pSender->GetName(), _T("CMB_MONTH")) == 0)  
 63             { 64                 m_sysTime.wMonth  = GetCmbMonth(); 65                 DrawCalendar(m_sysTime); 66             } 67         } 68     } 69  70     LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 71     { 72         if( uMsg == WM_CREATE ) { 73             m_pm.Init(m_hWnd); 74             CDialogBuilder builder; 75             CControlUI* pRoot = builder.Create(_T("Calendar1.xml"), (UINT)0, NULL, &m_pm); 76             ASSERT(pRoot && "Failed to parse XML"); 77             m_pm.AttachDialog(pRoot); 78             m_pm.AddNotifier(this); 79             Init(); 80             return 0; 81         } 82         else if( uMsg == WM_DESTROY ) { 83             ::PostQuitMessage(0L); 84         } 85         else if( uMsg == WM_ERASEBKGND ) { 86             return 1; 87         } 88         LRESULT lRes = 0; 89         if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes; 90         return CWindowWnd::HandleMessage(uMsg, wParam, lParam); 91     } 92  93     //绘制日历 94     void DrawCalendar(SYSTEMTIME m_sysTime) 95     { 96         int iDay = 0; 97         char cDay[3] = {0}; 98         //int iStartDay = m_sysTime.wDayOfWeek; 99         m_sysTime.wDay = 1;100         int iStartDay = GetDayOfWeek(m_sysTime);101         //上月天数102         int iLastMonthStartDays = 31 - iStartDay;103         if(m_sysTime.wMonth>1)104             iLastMonthStartDays = GetMonthDays(m_sysTime.wYear,m_sysTime.wMonth - 1) - iStartDay;105         //本月天数106         int iMonthDays = GetMonthDays(m_sysTime.wYear,m_sysTime.wMonth);107         //下月天数108         int iNextMonthDays = 0;109 110         CControlUI* pButtonUI;111         CContainerUI* pControl = static_cast(m_pm.FindControl(_T("ContainerUI3")));112         for(int i = 0;i < 42;i++)113         {114             pButtonUI = m_pm.FindSubControlByClass(pControl,_T("ButtonUI"),i);115             //上月116             if(iSetText(cDay);121                 DrawBtnBackImage(pButtonUI,false);122             }123             else if(i>iStartDay-1&&iDaySetText(cDay);128                 DrawBtnBackImage(pButtonUI,true);129             } 
130             else 131             {132                 iNextMonthDays ++;133                 sprintf(cDay,"%d",iNextMonthDays);134                 pButtonUI->SetText(cDay);135                 DrawBtnBackImage(pButtonUI,false);136             }137         }138     }139 140     void DrawBtnBackImage(CControlUI* pButtonUI,bool isEnable)141     {142         if(isEnable)143         {144             pButtonUI->SetEnabled(true);145             pButtonUI->ApplyAttributeList(146                 _T("normalp_w_picpath=\"file='cells.png' source='0,0,81,81'\" ")\147                 _T("hotp_w_picpath=\"file='cells.png' source='0,81,81,162'\" "));148         }149         else150         {151             pButtonUI->SetBkImage(_T("calpad.jpg"));152             pButtonUI->ApplyAttributeList(153                 _T("normalp_w_picpath=\"file='calpad.jpg'\" ")\154                 _T("hotp_w_picpath=\"file='calpad.jpg'\" "));155         }156     }157 158     int GetMonthDays(int iY,int iM)159     {160         int iTotalDay = 31;        
161         if(iM == 2) 
162         {163             //闰年可以被4或者400整除 但是不能被100整除164             if(iY % 4 ==0 && iY % 100 !=0 || iY % 400 ==0) 
165                 iTotalDay= 29;166             else167                 iTotalDay=28;168         }169         else if(iM==4 || iM==6 || iM==9||iM==11)170             iTotalDay = 30;171         return iTotalDay;172     }173 174     int GetDayOfWeek(SYSTEMTIME m_sysTime)175     {176         cTime.SetDate(m_sysTime.wYear,m_sysTime.wMonth,m_sysTime.wDay);177         return cTime.GetDayOfWeek()-1;178     }179 180     int GetCmbMonth()181     {182         CComboUI* pCmb = static_cast(m_pm.FindControl(_T("CMB_MONTH")));183         CDuiString cCurMonth = pCmb->GetText();184         return atoi(cCurMonth.Left(cCurMonth.GetLength()-1));185     }186 187     int SetTxtYear(int iY)188     {189         CEditUI* pTxt = static_cast(m_pm.FindControl(_T("TXT_YEAR")));190         CDuiString cCurYear = pTxt->GetText();191         int iCurYear= 0;192         iCurYear = atoi(cCurYear) + iY;193         cCurYear.Format("%d",iCurYear);194         pTxt->SetText(cCurYear);195         return iCurYear;196     }197 198 199 public:200     CPaintManagerUI m_pm;201     SYSTEMTIME m_sysTime;202     COleDateTime cTime;203 };204 205 206 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int nCmdShow)207 {208     CPaintManagerUI::SetInstance(hInstance);209     CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());210 211     HRESULT Hr = ::CoInitialize(NULL);212     if( FAILED(Hr) ) return 0;213 214     CFrameWindowWnd* pFrame = new CFrameWindowWnd();215     if( pFrame == NULL ) return 0;216  //   pFrame->Create(NULL, _T("日历控件测试"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);217     pFrame->Create(NULL, _T("日历控件测试"), UI_WNDSTYLE_DIALOG, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 320);   //禁止双击放大218     pFrame->CenterWindow();219     pFrame->ShowWindow(true);220     CPaintManagerUI::MessageLoop();221 222     ::CoUninitialize();223     return 0;224 }

d、运行看一下效果吧!

 

MFC加载duilib界面_第2张图片

暂时没有实现阴历的显示,待项目开发完毕,有时间实现完给大家开源。