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

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.     }