首页 » 开源 » Duilib » 正文

优化duilib中的CDateTimeUI控件-修正XP下无法使用的问题

编辑:qdtroy 2017年4月17日 0评论 1,529浏览

duilib没有自己实现日期时间选择控件,转而封装了系统原生控件来代替,虽不能完美解决界面美观问题,暂时解决了有无的问题。但是使用过程中,很多朋友反应在Win7以上系统是没问题的,但是在XP系统上出现无法选择日期的问题,今天抽空修复了一下,核心代码如下:

  1. class CDateTimeWnd : public CWindowWnd  

  2.     {  

  3.     public:  

  4.         CDateTimeWnd();  

  5.   

  6.   

  7.         void Init(CDateTimeUI* pOwner);  

  8.         RECT CalPos();  

  9.   

  10.   

  11.         LPCTSTR GetWindowClassName() const;  

  12.         LPCTSTR GetSuperClassName() const;  

  13.         void OnFinalMessage(HWND hWnd);  

  14.   

  15.   

  16.         LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);  

  17.     protected:  

  18.         CDateTimeUI* m_pOwner;  

  19.         HBRUSH m_hBkBrush;  

  20.         bool m_bInit;  

  21.         bool m_bDropOpen;  

  22.         SYSTEMTIME m_oldSysTime;  

  23.     };  

  24.   

  25.   

  26.     CDateTimeWnd::CDateTimeWnd() : m_pOwner(NULL), m_hBkBrush(NULL), m_bInit(false), m_bDropOpen(false)  

  27.     {  

  28.     }  

  29.   

  30.   

  31.     void CDateTimeWnd::Init(CDateTimeUI* pOwner)  

  32.     {  

  33.         m_pOwner = pOwner;  

  34.         m_pOwner->m_nDTUpdateFlag = DT_NONE;  

  35.   

  36.   

  37.         if (m_hWnd == NULL)  

  38.         {  

  39.             RECT rcPos = CalPos();  

  40.             UINT uStyle = WS_CHILD;  

  41.             Create(m_pOwner->GetManager()->GetPaintWindow(), NULL, uStyle, 0, rcPos);  

  42.             SetWindowFont(m_hWnd, m_pOwner->GetManager()->GetFontInfo(m_pOwner->GetFont())->hFont, TRUE);  

  43.         }  

  44.   

  45.   

  46.         if (m_pOwner->GetText().IsEmpty()) {  

  47.             ::GetLocalTime(&m_pOwner->m_sysTime);  

  48.         }  

  49.         memcpy(&m_oldSysTime, &m_pOwner->m_sysTime, sizeof(SYSTEMTIME));  

  50.         ::SendMessage(m_hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);  

  51.         ::ShowWindow(m_hWnd, SW_SHOWNOACTIVATE);  

  52.         ::SetFocus(m_hWnd);  

  53.   

  54.   

  55.         m_bInit = true;      

  56.     }  

  57.   

  58.   

  59.     RECT CDateTimeWnd::CalPos()  

  60.     {  

  61.         CDuiRect rcPos = m_pOwner->GetPos();  

  62.   

  63.   

  64.         CControlUI* pParent = m_pOwner;  

  65.         RECT rcParent;  

  66.         while( pParent = pParent->GetParent() ) {  

  67.             if( !pParent->IsVisible() ) {  

  68.                 rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;  

  69.                 break;  

  70.             }  

  71.             rcParent = pParent->GetClientPos();  

  72.             if( !::IntersectRect(&rcPos, &rcPos, &rcParent) ) {  

  73.                 rcPos.left = rcPos.top = rcPos.right = rcPos.bottom = 0;  

  74.                 break;  

  75.             }  

  76.         }  

  77.   

  78.   

  79.         return rcPos;  

  80.     }  

  81.   

  82.   

  83.     LPCTSTR CDateTimeWnd::GetWindowClassName() const  

  84.     {  

  85.         return _T("DateTimeWnd");  

  86.     }  

  87.   

  88.   

  89.     LPCTSTR CDateTimeWnd::GetSuperClassName() const  

  90.     {  

  91.         return DATETIMEPICK_CLASS;  

  92.     }  

  93.   

  94.   

  95.     void CDateTimeWnd::OnFinalMessage(HWND hWnd)  

  96.     {  

  97.         if( m_hBkBrush != NULL ) ::DeleteObject(m_hBkBrush);  

  98.         if( m_pOwner->GetManager()->IsLayered() ) {  

  99.             m_pOwner->GetManager()->RemovePaintChildWnd(hWnd);  

  100.         }   

  101.         m_pOwner->m_pWindow = NULL;  

  102.         delete this;  

  103.     }  

  104.   

  105.   

  106.     LRESULT CDateTimeWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)  

  107.     {  

  108.         LRESULT lRes = 0;  

  109.         BOOL bHandled = TRUE;  

  110.         if (uMsg == WM_KEYDOWN && wParam == VK_ESCAPE)  

  111.         {  

  112.             memcpy(&m_pOwner->m_sysTime, &m_oldSysTime, sizeof(SYSTEMTIME));  

  113.             m_pOwner->m_nDTUpdateFlag = DT_UPDATE;  

  114.             m_pOwner->UpdateText();  

  115.             PostMessage(WM_CLOSE);  

  116.             return lRes;  

  117.         }  

  118.         else if(uMsg == OCM_NOTIFY)  

  119.         {  

  120.             NMHDR* pHeader=(NMHDR*)lParam;  

  121.             if(pHeader != NULL && pHeader->hwndFrom == m_hWnd) {  

  122.                 if(pHeader->code == DTN_DATETIMECHANGE) {  

  123.                     LPNMDATETIMECHANGE lpChage=(LPNMDATETIMECHANGE)lParam;  

  124.                     ::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);  

  125.                     m_pOwner->m_nDTUpdateFlag = DT_UPDATE;  

  126.                     m_pOwner->UpdateText();  

  127.                 }  

  128.                 else if(pHeader->code == DTN_DROPDOWN) {  

  129.                     m_bDropOpen = true;  

  130.   

  131.   

  132.                 }  

  133.                 else if(pHeader->code == DTN_CLOSEUP) {  

  134.                     ::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&m_pOwner->m_sysTime);  

  135.                     m_pOwner->m_nDTUpdateFlag = DT_UPDATE;  

  136.                     m_pOwner->UpdateText();  

  137.                     PostMessage(WM_CLOSE);  

  138.                     m_bDropOpen = false;  

  139.                 }  

  140.             }  

  141.             bHandled = FALSE;  

  142.         }  

  143.         else if(uMsg == WM_KILLFOCUS)  

  144.         {  

  145.             if(!m_bDropOpen) {  

  146.                 PostMessage(WM_CLOSE);  

  147.             }  

  148.             bHandled = FALSE;  

  149.         }  

  150.         else if( uMsg == WM_PAINT) {  

  151.             if (m_pOwner->GetManager()->IsLayered()) {  

  152.                 m_pOwner->GetManager()->AddPaintChildWnd(m_hWnd);  

  153.             }  

  154.             bHandled = FALSE;  

  155.         }  

  156.         else bHandled = FALSE;  

  157.         if( !bHandled ) return CWindowWnd::HandleMessage(uMsg, wParam, lParam);  

  158.         return lRes;  

  159.     }  

把UIDateTime.cpp中的CDateTimeWnd类替换成以上代码即可解决。

好了,需要的小伙伴赶紧试试吧!

duilib开源项目圈QQ群:261675375 \ 261851826
最新代码托管地址:https://github.com/qdtroy/DuiLib_Ultimate

By Troy (QQ:656067418)

标签: