#include "stdafx.h" #include "PropertyGridInplaceEdit.h" #include "PropertyGridInplaceButton.h" #include "PropertyGridInplaceList.h" #include "PropertyGridItem.h" #include "PropertyGridExtItemTime.h" #include "PropertyGrid.h" ///////////////////////////////////////////////////////////////////////////// // CInplaceTimeEdit ///////////////////////////////////////////////////////////////////////////// CInplaceTimeEdit::CInplaceTimeEdit(BOOL bHasSecond) : CTimeEdit(bHasSecond) , m_pItem(0) , m_pGrid(0) { } CInplaceTimeEdit::~CInplaceTimeEdit() { } BEGIN_MESSAGE_MAP(CInplaceTimeEdit, CTimeEdit) //{{AFX_MSG_MAP(CInplaceTimeEdit) ON_WM_CTLCOLOR_REFLECT() ON_CONTROL_REFLECT(EN_KILLFOCUS, OnEnKillfocus) ON_CONTROL_REFLECT(EN_SETFOCUS, OnEnSetfocus) ON_WM_LBUTTONDBLCLK() ON_WM_GETDLGCODE() ON_WM_KEYDOWN() ON_WM_CHAR() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CInplaceTimeEdit::SetValue(CString strValue) { m_strValue = strValue; } void CInplaceTimeEdit::Create(CPropertyGridExtItemTime* pItem, CRect rect) { ASSERT(pItem && pItem->GetGrid()); m_pGrid = pItem->GetGrid(); m_pItem = pItem; if (!m_hWnd) { CTimeEdit::Create(WS_CHILD|ES_AUTOHSCROLL, rect, m_pGrid, 0); } SetWindowText(m_strValue); SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); } HBRUSH CInplaceTimeEdit::CtlColor(CDC* pDC, UINT /*nCtlColor*/) { pDC->SetTextColor(GetStyle() & ES_READONLY ? GetSysColor(COLOR_GRAYTEXT): ((CPropertyGridView*)m_pGrid)->m_clrFore); COLORREF clr = ((CPropertyGridView*)m_pGrid)->m_clrBack; if (clr != m_clrBack || !m_brBack.GetSafeHandle()) { m_brBack.DeleteObject(); m_brBack.CreateSolidBrush(clr); m_clrBack = clr; } pDC->SetBkColor(m_clrBack); return m_brBack; } void CInplaceTimeEdit::OnEnSetfocus() { ASSERT(m_pItem && m_pGrid); m_pGrid->Invalidate(FALSE); } void CInplaceTimeEdit::OnEnKillfocus() { if (m_pItem) { m_pItem->OnValidateEdit(); m_pGrid->Invalidate(FALSE); } } UINT CInplaceTimeEdit::OnGetDlgCode() { return DLGC_WANTALLKEYS; } void CInplaceTimeEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if (nChar == VK_TAB) return; if (nChar == VK_ESCAPE || nChar == VK_RETURN) { m_pGrid->SetFocus(); return; } CTimeEdit::OnChar(nChar, nRepCnt, nFlags); } void CInplaceTimeEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if (nChar == VK_TAB) { CWnd* pParent = m_pGrid->GetParent(); if (!pParent || !pParent->GetParent()) { ASSERT(FALSE); return; } CWnd* pWndNext = pParent->GetParent()->GetNextDlgTabItem( pParent, ::GetKeyState(VK_SHIFT) < 0 ); if (pWndNext != NULL) { pWndNext->SetFocus(); } return; } else if (nChar == VK_ESCAPE) { SetWindowText(m_strValue); return; } else if (nChar == VK_RETURN) { return; } else if (nChar == VK_DOWN || nChar == VK_UP) { if (SelectConstraint(nChar == VK_DOWN? +1: -1, FALSE)) { MaskSelectAll(); return; } } CTimeEdit::OnKeyDown(nChar, nRepCnt, nFlags); } BOOL CInplaceTimeEdit::SelectConstraint(int nDirection, BOOL bCircle) { CPGItemConstraints* pList = m_pItem->GetConstraints(); if (pList->IsEmpty()) return FALSE; CString str; GetWindowText(str); int nIndex = pList->FindConstraint( str ); nIndex+= nDirection; if (nIndex >= pList->GetCount()) nIndex = bCircle ? 0 : (ULONG)pList->GetCount() - 1; if (nIndex < 0) nIndex = bCircle ? (ULONG)pList->GetCount() - 1 : 0; POSITION pos = pList->FindIndex(nIndex); SetWindowText( pList->GetAt(pos) ); return TRUE; } void CInplaceTimeEdit::OnLButtonDblClk(UINT nFlags, CPoint point) { if (m_pItem != NULL && !m_pItem->GetReadOnly() && SelectConstraint(+1, TRUE)) { m_pGrid->SetFocus(); return; } CTimeEdit::OnLButtonDblClk(nFlags, point); } void CInplaceTimeEdit::DestroyItem() { // reset variables to defaults. m_pItem = NULL; m_pGrid = NULL; m_strValue.Empty(); m_brBack.DeleteObject(); // destroy the window. DestroyWindow( ); } ///////////////////////////////////////////////////////////////////////////// // CPropertyGridExtItemTime ///////////////////////////////////////////////////////////////////////////// CPropertyGridExtItemTime::CPropertyGridExtItemTime(CString strCaption, COleDateTime dtTime /* = 当前时间 */, BOOL bHasSecond /* = FALSE */ ) : CPropertyGridItem(strCaption) , m_wndTimeEdit(bHasSecond) { m_wndTimeEdit.m_pItem = this; m_pBindTime = NULL; m_nFlags = pgitemHasEdit; m_bHasSecond = bHasSecond; SetTime(dtTime); } CPropertyGridExtItemTime::CPropertyGridExtItemTime(UINT nID, COleDateTime dtTime /* = 当前时间 */, BOOL bHasSecond /* = FALSE */ ) : CPropertyGridItem(nID) , m_wndTimeEdit(bHasSecond) { m_wndTimeEdit.m_pItem = this; m_pBindTime = NULL; m_nFlags = pgitemHasEdit; m_bHasSecond = bHasSecond; SetTime(dtTime); } CPropertyGridExtItemTime::~CPropertyGridExtItemTime() { m_wndTimeEdit.DestroyItem(); } void CPropertyGridExtItemTime::SetTime(COleDateTime dtTime) { // 如果参数dtTime不合法,则使用缺省构造函数产生的时间做为属性值 if (dtTime.GetStatus() == COleDateTime::valid) m_dtTime = dtTime; else m_dtTime = COleDateTime(); CPropertyGridItem::SetValue( CTimeEdit::TimeToString(m_dtTime, m_bHasSecond) ); if (m_pBindTime) *m_pBindTime = m_dtTime; } COleDateTime CPropertyGridExtItemTime::GetTime() { return m_dtTime; } void CPropertyGridExtItemTime::SetValue(CString strValue) { SetTime(CTimeEdit::StringToOleDateTime(strValue)); } void CPropertyGridExtItemTime::OnValidateEdit() { if (m_wndTimeEdit.GetSafeHwnd()) { m_wndTimeEdit.ShowWindow(SW_HIDE); CString strValue; m_wndTimeEdit.GetWindowText(strValue); if (m_strValue != strValue) { // 如果输入的时间合法,则更新属性值,否则发出错误提示音 COleDateTime dt= CDateEdit::StringToOleDateTime(strValue); if (dt.GetStatus() == COleDateTime::valid) { OnValueChanged(strValue); m_pGrid->Invalidate(FALSE); } else { ::MessageBeep( (UINT)-1 ); // 内置编辑控件恢复原来的属性值 SetEditText(m_strValue); } } } } void CPropertyGridExtItemTime::SetEditText(CString str) { if (!m_pGrid) return; if (m_wndTimeEdit.GetSafeHwnd()) m_wndTimeEdit.SetWindowText(str); } void CPropertyGridExtItemTime::OnSelect() { ASSERT(m_bVisible); if (!m_bReadOnly && (m_nFlags & (pgitemHasComboButton | pgitemHasExpandButton))) { GetInplaceButton().Create(this, GetItemRect()); } if (m_nFlags & pgitemHasEdit) { m_wndTimeEdit.SetValue(m_strValue); m_wndTimeEdit.Create(this, GetValueRect()); m_wndTimeEdit.SetReadOnly(m_bReadOnly); m_wndTimeEdit.SetFont(GetGrid()->GetFont()); m_wndTimeEdit.SetMargins(3, 0); } } BOOL CPropertyGridExtItemTime::OnChar(UINT nChar) { if (m_nFlags & pgitemHasEdit) { OnSelect(); m_wndTimeEdit.SetFocus(); m_wndTimeEdit.MaskSelectAll(); if (nChar != VK_TAB) m_wndTimeEdit.SendMessage(WM_CHAR, nChar); return TRUE; } return FALSE; } void CPropertyGridExtItemTime::OnLButtonDblClk() { if (HasChilds()) { if(m_bExpanded) Collapse(); else Expand(); } else { OnSelect(); if (m_nFlags & pgitemHasEdit) { if (!GetReadOnly() && m_wndTimeEdit.SelectConstraint(+1, TRUE)) { OnValidateEdit(); } else { m_wndTimeEdit.SetFocus(); m_wndTimeEdit.MaskSelectAll(); } } else if (!GetReadOnly()) { CPGItemConstraints* pList = GetConstraints(); if (pList->IsEmpty()) return ; int nIndex = pList->FindConstraint(m_strValue); nIndex += +1; if (nIndex >= pList->GetCount()) nIndex = 0; POSITION pos = pList->FindIndex(nIndex); OnValueChanged(pList->GetAt(pos)); } } } void CPropertyGridExtItemTime::BindToTime(COleDateTime* pBindTime) { m_pBindTime = pBindTime; if (m_pBindTime) SetTime(*m_pBindTime); }