CDateTimeUI类源码分析
生活随笔
收集整理的這篇文章主要介紹了
CDateTimeUI类源码分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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类源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: *顺序表[数组法]
- 下一篇: C++:类模板与模板类