| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- #include "stdafx.h"
- #include "PropertyGridInplaceEdit.h"
- #include "PropertyGridInplaceButton.h"
- #include "PropertyGridInplaceList.h"
- #include "PropertyGridItem.h"
- #include "PropertyGridExtItemDate.h"
- #include "PropertyGrid.h"
- /////////////////////////////////////////////////////////////////////////////
- // CInplaceDateEdit
- /////////////////////////////////////////////////////////////////////////////
- CInplaceDateEdit::CInplaceDateEdit()
- : m_pItem(0)
- , m_pGrid(0)
- {
- }
- CInplaceDateEdit::~CInplaceDateEdit()
- {
- }
- BEGIN_MESSAGE_MAP(CInplaceDateEdit, CDateEdit)
- //{{AFX_MSG_MAP(CInplaceDateEdit)
- ON_WM_CTLCOLOR_REFLECT()
- ON_CONTROL_REFLECT(EN_KILLFOCUS, OnEnKillfocus)
- ON_CONTROL_REFLECT(EN_SETFOCUS, OnEnSetfocus)
- ON_WM_GETDLGCODE()
- ON_WM_KEYDOWN()
- ON_WM_CHAR()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- void CInplaceDateEdit::SetValue(CString strValue)
- {
- m_strValue = strValue;
- }
- void CInplaceDateEdit::Create(CPropertyGridExtItemDate* pItem, CRect rect)
- {
- ASSERT(pItem && pItem->GetGrid());
- m_pGrid = pItem->GetGrid();
- m_pItem = pItem;
- if (!m_hWnd)
- {
- CDateEdit::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 CInplaceDateEdit::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 CInplaceDateEdit::OnEnSetfocus()
- {
- ASSERT(m_pItem && m_pGrid);
- m_pGrid->Invalidate(FALSE);
- }
- void CInplaceDateEdit::OnEnKillfocus()
- {
- if (m_pItem)
- {
- m_pItem->OnValidateEdit();
- m_pGrid->Invalidate(FALSE);
- }
- }
- UINT CInplaceDateEdit::OnGetDlgCode()
- {
- return DLGC_WANTALLKEYS;
- }
- void CInplaceDateEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- if (nChar == VK_TAB) return;
- if (nChar == VK_ESCAPE || nChar == VK_RETURN)
- {
- m_pGrid->SetFocus();
- return;
- }
- CDateEdit::OnChar(nChar, nRepCnt, nFlags);
- }
- void CInplaceDateEdit::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;
- }
-
- CDateEdit::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- void CInplaceDateEdit::DestroyItem()
- {
- // reset variables to defaults.
- m_pItem = NULL;
- m_pGrid = NULL;
- m_strValue.Empty();
- m_brBack.DeleteObject();
- // destroy the window.
- DestroyWindow( );
- }
- /////////////////////////////////////////////////////////////////////////////
- // CInplaceMonthCal
- /////////////////////////////////////////////////////////////////////////////
- CInplaceMonthCal::CInplaceMonthCal()
- : m_pItem(0)
- {
- }
- CInplaceMonthCal::~CInplaceMonthCal()
- {
- }
- BEGIN_MESSAGE_MAP(CInplaceMonthCal, CMonthCalCtrl)
- //{{AFX_MSG_MAP(CInplaceMonthCal)
- ON_NOTIFY_REFLECT(MCN_SELECT, OnSelect)
- ON_WM_KEYDOWN()
- ON_WM_KILLFOCUS()
- ON_WM_MOUSEACTIVATE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- void CInplaceMonthCal::Create(CPropertyGridExtItemDate* pItem)
- {
- ASSERT(pItem && pItem->GetGrid());
- m_pItem = pItem;
- CWnd* pGrid = m_pItem->GetGrid();
- // 创建日历控件
- if (m_hWnd == NULL)
- {
- CreateEx(0, MONTHCAL_CLASS, NULL, WS_CHILD | WS_BORDER, CRect(0, 0, 1, 1), pGrid, 0);
- SetOwner(pGrid);
- }
- // 计算日历控件的位置
- CRect rcItem= m_pItem->GetItemRect();
- pGrid->ClientToScreen(&rcItem);
- CRect rect;
- GetMinReqRect(&rect);
- rect.SetRect(rcItem.right - rect.Width(), rcItem.bottom, rcItem.right, rcItem.bottom + rect.Height());
- CRect rcWork;
- ::SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcWork, 0);
- if (rect.bottom > rcWork.bottom) rect.OffsetRect(0, - rect.Height() - rcItem.Height() - 1);
- if (rect.top < rcWork.top) rect.OffsetRect(0, rcWork.top - rect.top);
- if (rect.left < rcWork.left) rect.OffsetRect(rcWork.left - rect.left, 0);
- if (rect.right > rcWork.right) rect.OffsetRect(rcWork.right - rect.right, 0);
- // 以子窗口方式创建内置日历控件,然后再执行下面这段代码,内置日历
- // 控件将以弹出窗口方式显示,并得到输入焦点,但当前窗口保持不变
- SetFocus();
- ::SetWindowLong(m_hWnd, GWL_HWNDPARENT, NULL);
- ModifyStyle(WS_CHILD, WS_POPUP);
- ::SetWindowLong(m_hWnd, GWL_HWNDPARENT, (LONG)pGrid->m_hWnd);
- SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
- // 要在显示日历控件后再选择日期,因为属性项处于编辑状态时,
- // 编辑控件在激活日历控件时失去焦点,从而更新属性值
- SetCurSel( m_pItem->GetDate() );
- CPGMouseMonitor::SetupHook(this);
- }
- void CInplaceMonthCal::OnSelect(NMHDR* pNMHDR, LRESULT* pResult)
- {
- // 更新属性项
- Apply();
- *pResult = 0;
- }
- void CInplaceMonthCal::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- switch (nChar)
- {
- case VK_RETURN:
- Apply();
- break;
- case VK_ESCAPE:
- Cancel();
- }
- CMonthCalCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- void CInplaceMonthCal::OnKillFocus(CWnd* pNewWnd)
- {
- CMonthCalCtrl::OnKillFocus(pNewWnd);
-
- // 如果不是内置控件导致的事件,则删除窗口
- if (!IsChild(pNewWnd))
- {
- CPGMouseMonitor::SetupHook(NULL);
- DestroyItem();
- }
- }
- int CInplaceMonthCal::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
- {
- // 用鼠标点击内置日历控件时,不改变当前窗口
- return MA_NOACTIVATE;
- }
- void CInplaceMonthCal::Apply()
- {
- SYSTEMTIME st;
- GetCurSel(&st);
- COleDateTime dt;
- dt.SetDate(st.wYear, st.wMonth, st.wDay);
- CString str = CDateEdit::DateToString(dt);
- if (str != m_pItem->GetValue())
- m_pItem->OnValueChanged(str);
- GetOwner()->SetFocus();
- }
- void CInplaceMonthCal::Cancel()
- {
- GetOwner()->SetFocus();
- }
- void CInplaceMonthCal::DestroyItem()
- {
- m_pItem = NULL;
- DestroyWindow( );
- }
- /////////////////////////////////////////////////////////////////////////////
- // CPropertyGridExtItemDate
- /////////////////////////////////////////////////////////////////////////////
- CPropertyGridExtItemDate::CPropertyGridExtItemDate(CString strCaption, COleDateTime dtDate /* = 当前日期 */ )
- : CPropertyGridItem(strCaption)
- {
- m_wndDateEdit.m_pItem = this;
- m_wndMonthCal.m_pItem = this;
- m_pBindDate = NULL;
- m_nFlags = pgitemHasEdit | pgitemHasComboButton;
- SetDate(dtDate);
- }
- CPropertyGridExtItemDate::CPropertyGridExtItemDate(UINT nID, COleDateTime dtDate /* = 当前日期 */ )
- : CPropertyGridItem(nID)
- {
- m_wndDateEdit.m_pItem = this;
- m_wndMonthCal.m_pItem = this;
- m_pBindDate = NULL;
- m_nFlags = pgitemHasEdit | pgitemHasComboButton;
- SetDate(dtDate);
- }
- CPropertyGridExtItemDate::~CPropertyGridExtItemDate()
- {
- m_wndDateEdit.DestroyItem();
- m_wndMonthCal.DestroyItem();
- }
- void CPropertyGridExtItemDate::SetDate(COleDateTime dtDate)
- {
- // 如果参数dtDate不合法,则使用缺省构造函数产生的日期做为属性值
- if (dtDate.GetStatus() == COleDateTime::valid)
- m_dtDate = dtDate;
- else
- m_dtDate = COleDateTime();
- CPropertyGridItem::SetValue( CDateEdit::DateToString(m_dtDate) );
- if (m_pBindDate)
- *m_pBindDate = m_dtDate;
- }
- COleDateTime CPropertyGridExtItemDate::GetDate()
- {
- return m_dtDate;
- }
- void CPropertyGridExtItemDate::SetValue(CString strValue)
- {
- SetDate(CDateEdit::StringToOleDateTime(strValue));
- }
- void CPropertyGridExtItemDate::OnValidateEdit()
- {
- if (m_wndDateEdit.GetSafeHwnd())
- {
- m_wndDateEdit.ShowWindow(SW_HIDE);
-
- CString strValue;
- m_wndDateEdit.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 CPropertyGridExtItemDate::SetEditText(CString str)
- {
- if (!m_pGrid) return;
- if (m_wndDateEdit.GetSafeHwnd())
- m_wndDateEdit.SetWindowText(str);
- }
- void CPropertyGridExtItemDate::OnSelect()
- {
- ASSERT(m_bVisible);
- if (!m_bReadOnly && (m_nFlags & (pgitemHasComboButton | pgitemHasExpandButton)))
- {
- GetInplaceButton().Create(this, GetItemRect());
- }
- if (m_nFlags & pgitemHasEdit)
- {
- m_wndDateEdit.SetValue(m_strValue);
- m_wndDateEdit.Create(this, GetValueRect());
- m_wndDateEdit.SetReadOnly(m_bReadOnly);
- m_wndDateEdit.SetFont(GetGrid()->GetFont());
- m_wndDateEdit.SetMargins(3, 0);
- }
- }
- BOOL CPropertyGridExtItemDate::OnChar(UINT nChar)
- {
- if (m_nFlags & pgitemHasEdit)
- {
- OnSelect();
- m_wndDateEdit.SetFocus();
- m_wndDateEdit.MaskSelectAll();
- if (nChar != VK_TAB) m_wndDateEdit.SendMessage(WM_CHAR, nChar);
- return TRUE;
- }
- return FALSE;
- }
- void CPropertyGridExtItemDate::OnLButtonDblClk()
- {
- if (HasChilds())
- {
- if(m_bExpanded) Collapse(); else Expand();
- }
- else
- {
- OnSelect();
- if (m_nFlags & pgitemHasEdit)
- {
- m_wndDateEdit.SetFocus();
- m_wndDateEdit.MaskSelectAll();
- }
- }
- }
- void CPropertyGridExtItemDate::BindToDate(COleDateTime* pBindDate)
- {
- m_pBindDate = pBindDate;
- if (m_pBindDate)
- SetDate(*m_pBindDate);
- }
- void CPropertyGridExtItemDate::OnInplaceButtonDown()
- {
- m_wndMonthCal.Create(this);
- }
|