| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- #include "StdAfx.h"
- #include "PropertyGrid_Defines.h"
- #include "PropertyGridInplaceEdit.h"
- #include "PropertyGridInplaceButton.h"
- #include "PropertyGridInplaceList.h"
- #include "PropertyGridItem.h"
- #include "PropertyGrid.h"
- /////////////////////////////////////////////////////////////////////////////
- // CPropertyGridItem
- CPropertyGridItem::CPropertyGridItem(CString strCaption, LPCTSTR strValue, UINT nMaxLength)
- {
- Init();
- SetCaption(strCaption);
- m_nMaxLength = nMaxLength;
- m_strValue = AdjustValue(strValue);
- }
- CPropertyGridItem::CPropertyGridItem(UINT nID, LPCTSTR strValue, UINT nMaxLength)
- {
- Init();
- m_nID = nID;
-
- CString strText;
- if (strText.LoadString(nID))
- {
- int nIndex = strText.Find( _T('\n') );
- if (nIndex == -1)
- {
- m_strCaption = strText;
- } else
- {
- m_strCaption = strText.Left(nIndex);
- m_strDescription = strText.Mid(nIndex + 1);
- }
- }
- m_nMaxLength = nMaxLength;
- m_strValue = AdjustValue(strValue);
- }
- CPropertyGridItem::~CPropertyGridItem(void)
- {
- while (!m_lstChilds.IsEmpty())
- {
- delete m_lstChilds.RemoveTail();
- }
- if ( ::IsWindow( GetInplaceButton().m_hWnd ) )
- {
- GetInplaceButton().DestroyItem( );
- }
- if ( ::IsWindow( GetInplaceList().m_hWnd ) )
- {
- GetInplaceList().DestroyItem( );
- }
- if ( ::IsWindow( GetInplaceEdit().m_hWnd ) )
- {
- GetInplaceEdit().DestroyItem( );
- }
- }
- void CPropertyGridItem::Init()
- {
- m_bExpanded = FALSE;
- m_nIndex = -1;
- m_bVisible = FALSE;
- m_pParent = 0;
- m_pGrid = NULL;
- m_nIndent = 0;
- m_strValue = _T("");
- m_bReadOnly = FALSE;
- m_bCategory = FALSE;
- m_nID = 0;
- m_nFlags = pgitemHasEdit;
- m_dwItemData = 0;
- m_pBindString = NULL;
- }
- CString CPropertyGridItem::AdjustValue(CString strValue)
- {
- if (m_nMaxLength > 0 && strValue.GetLength() > (int)m_nMaxLength)
- return strValue.Left(m_nMaxLength);
- else
- return strValue;
- }
- CPropertyGridItem* CPropertyGridItem::AddChildItem(CPropertyGridItem* pItem)
- {
- m_lstChilds.AddTail(pItem);
- pItem->m_pGrid = m_pGrid;
- ASSERT(pItem->m_pParent == NULL);
- pItem->m_pParent = this;
- pItem->m_nIndent = m_nIndent + 1;
- pItem->OnAddChildItem();
- if (m_bVisible)
- {
- if (m_bExpanded)
- m_pGrid->SetPropertySort(m_pGrid->m_properetySort, TRUE);
- else if (m_pGrid->GetSafeHwnd() && m_lstChilds.GetCount() == 1)
- // 如果父项处于折叠状态,且添加的是第一个子项,则刷新窗口以显示父项左边的"+"
- m_pGrid->Invalidate(FALSE);
- }
- else
- {
- // 如果属性表按字母排序或者不排序,此时属性分类不可见,但为属性分类添加的子项要显示出来
- if (m_bCategory && m_pGrid->m_properetySort != pgsortCategorized)
- m_pGrid->SetPropertySort(m_pGrid->m_properetySort, TRUE);
- }
- return pItem;
- }
- void CPropertyGridItem::Collapse()
- {
- if (!m_bExpanded) return;
- if (m_bVisible)
- {
- m_pGrid->_DoCollapse(this);
- // 下面这4行代码是为了解决第30号Bug
- CPropertyGridItem* pItem = m_pGrid->GetSelectedItem();
- if (m_pGrid->m_pSelected) m_pGrid->m_pSelected->OnDeselect();
- if (pItem) pItem->OnSelect();
- m_pGrid->m_pSelected = pItem;
- }
- m_bExpanded = FALSE;
- }
- void CPropertyGridItem::Expand()
- {
- if (m_bExpanded) return;
- if (m_bVisible)
- {
- m_pGrid->_DoExpand(this, m_nIndex);
- m_pGrid->_RefreshIndexes();
- // 下面这4行代码是为了解决第30号Bug
- CPropertyGridItem* pItem = m_pGrid->GetSelectedItem();
- if (m_pGrid->m_pSelected) m_pGrid->m_pSelected->OnDeselect();
- if (pItem) pItem->OnSelect();
- m_pGrid->m_pSelected = pItem;
- }
- m_bExpanded = TRUE;
- }
- BOOL CPropertyGridItem::HasParent(CPropertyGridItem* pParent)
- {
- if (m_pParent == NULL) return FALSE;
- if (m_pParent == pParent) return TRUE;
- return m_pParent->HasParent(pParent);
- }
- void CPropertyGridItem::SetReadOnly(BOOL bReadOnly)
- {
- m_bReadOnly = bReadOnly;
- if (m_pGrid && m_pGrid->GetSafeHwnd())
- {
- // 判断属性项是否处于选中状态
- if (m_pGrid->GetSelectedItem() == this)
- {
- OnDeselect();
- OnSelect();
- }
- m_pGrid->Invalidate(FALSE);
- }
- }
- void CPropertyGridItem::Select()
- {
- ASSERT(m_pGrid);
- if (m_bVisible)
- {
- m_pGrid->SetCurSel(m_nIndex);
- m_pGrid->OnSelectionChanged();
- }
- }
- void CPropertyGridItem::OnDeselect()
- {
- GetInplaceButton().HideWindow();
- OnValidateEdit();
- }
- void CPropertyGridItem::OnValidateEdit()
- {
- GetInplaceEdit().HideWindow();
-
- if (GetInplaceEdit().GetSafeHwnd() && GetInplaceEdit().m_pItem == this)
- {
- CString strValue;
- GetInplaceEdit().GetWindowText(strValue);
- if (m_strValue != strValue)
- {
- OnValueChanged(strValue);
- m_pGrid->Invalidate(FALSE);
- }
- }
- }
- void CPropertyGridItem::SetEditText(CString str)
- {
- if (!m_pGrid) return;
- if (GetInplaceEdit().GetSafeHwnd() && GetInplaceEdit().m_pItem == this)
- {
- GetInplaceEdit().SetWindowText(str);
- }
- }
- void CPropertyGridItem::SetValue(CString strValue)
- {
- m_strValue = AdjustValue(strValue);
- SetEditText(m_strValue);
- // 更新绑定的字符串对象
- if (m_pBindString)
- *m_pBindString = m_strValue;
- // 在设置完属性值后,强制刷新窗口
- if (m_pGrid && m_pGrid->m_hWnd) m_pGrid->Invalidate(FALSE);
- }
- void CPropertyGridItem::OnValueChanged(CString strValue)
- {
- SetValue(strValue);
- // 发送属性值改变的通知消息
- int nID = m_pGrid->GetParent()->GetDlgCtrlID();
- WPARAM wParam = MAKEWPARAM(nID, PGN_ITEMVALUE_CHANGED);
- m_pGrid->GetParent()->GetOwner()->SendMessage(PGWM_PROPERTYGRID_NOTIFY, wParam, (LPARAM)this);
- }
- void CPropertyGridItem::OnSelect()
- {
- ASSERT(m_bVisible);
- if (!m_bReadOnly && (m_nFlags & (pgitemHasComboButton | pgitemHasExpandButton)))
- {
- GetInplaceButton().Create(this, GetItemRect());
- }
- if (m_nFlags & pgitemHasEdit)
- {
- GetInplaceEdit().SetValue(m_strValue);
- GetInplaceEdit().Create(this, GetValueRect(), m_nMaxLength);
- GetInplaceEdit().SetReadOnly(m_bReadOnly);
- }
- else
- {
- GetInplaceEdit().HideWindow();
- }
- }
- void CPropertyGridItem::OnInplaceButtonDown()
- {
- if ((m_nFlags & pgitemHasComboButton) && !m_lstContraints.IsEmpty())
- {
- GetInplaceList().Create(this, GetItemRect());
- m_pGrid->Invalidate(FALSE);
- }
- }
- CRect CPropertyGridItem::GetValueRect()
- {
- ASSERT(m_bVisible);
- CRect rc = GetItemRect();
- CRect rcValue(m_pGrid->GetDividerPos() + 1, rc.top + 1, rc.right, rc.bottom - 1);
- if (m_nFlags & (pgitemHasComboButton | pgitemHasExpandButton))
- {
- if (GetInplaceButton().m_pItem == this && GetInplaceButton().GetStyle() & WS_VISIBLE)
- {
- rcValue.right -= 15;
- }
- }
- return rcValue;
- }
- CRect CPropertyGridItem::GetItemRect()
- {
- CRect rc;
- m_pGrid->GetItemRect(m_nIndex, rc);
- return rc;
- }
- BOOL CPropertyGridItem::OnChar(UINT nChar)
- {
- if (m_nFlags & pgitemHasEdit)
- {
- OnSelect();
- GetInplaceEdit().SetFocus();
- GetInplaceEdit().SetSel(0, -1);
- if (nChar != VK_TAB) GetInplaceEdit().SendMessage(WM_CHAR, nChar);
- return TRUE;
- }
- return FALSE;
- }
- void CPropertyGridItem::OnLButtonDblClk()
- {
- if (HasChilds())
- {
- if(m_bExpanded) Collapse(); else Expand();
- }
- else
- {
- OnSelect();
- if (m_nFlags & pgitemHasEdit)
- {
- if (!GetReadOnly() && GetInplaceEdit().SelectConstraint(+1, TRUE))
- {
- OnValidateEdit();
- }
- else
- {
- GetInplaceEdit().SetFocus();
- GetInplaceEdit().SetSel(0, -1);
- }
- }
- 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));
- }
- }
- }
- BOOL CPropertyGridItem::OnLButtonDown(UINT, CPoint point)
- {
- ASSERT(GetItemRect().PtInRect(point));
- m_pGrid->SetFocus();
- Select();
- // if(point.x <= PGI_EXPAND_BORDER)
- // {
- // if(m_bExpanded) Collapse(); else Expand();
- // }
- // 原来的代码只考虑了列表项为根结点的情况,没有
- // 考虑为子节点的情况,新代码修正了这个问题
- int nOffset = 0;
- if (m_nIndent > 1)
- nOffset = (m_nIndent - 1) * PGI_EXPAND_BORDER;
- if(point.x >= nOffset && point.x <= PGI_EXPAND_BORDER + nOffset)
- {
- if(m_bExpanded) Collapse(); else Expand();
- }
- CRect rc = GetValueRect();
- if ((m_nFlags & pgitemHasEdit) && rc.PtInRect(point))
- {
- mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
- }
- return TRUE;
- }
- CPropertyGridInplaceEdit& CPropertyGridItem::GetInplaceEdit()
- {
- ASSERT(m_pGrid);
- return m_pGrid->m_wndEdit;
- }
- CPropertyGridInplaceButton& CPropertyGridItem::GetInplaceButton()
- {
- ASSERT(m_pGrid);
- return m_pGrid->m_wndButton;
- }
- CPropertyGridInplaceList& CPropertyGridItem::GetInplaceList()
- {
- ASSERT(m_pGrid);
- return m_pGrid->m_wndListBox;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CPGListItems
- void CPGListItems::Sort()
- {
- CPGListItems lstSorted;
- POSITION pos = GetHeadPosition();
- while (pos)
- {
- CPropertyGridItem* pItem = GetNext(pos);
- BOOL bFound = FALSE;
- POSITION posInsert = lstSorted.GetHeadPosition();
- while (posInsert)
- {
- if (lstSorted.GetNext(posInsert)->GetCaption() > pItem->GetCaption())
- {
- bFound = TRUE;
- break;
- }
- }
- if (bFound)
- {
- if (posInsert)
- lstSorted.GetPrev(posInsert);
- else
- posInsert = lstSorted.GetTailPosition();
- lstSorted.InsertBefore(posInsert, pItem);
- }
- else
- {
- lstSorted.AddTail(pItem);
- }
- }
- RemoveAll();
- AddTail(&lstSorted);
- }
- CPropertyGridItem* CPGListItems::FindItem(CString strCaption)
- {
- POSITION pos = GetHeadPosition();
- while (pos)
- {
- CPropertyGridItem* pItem = GetNext(pos);
- if (pItem->GetCaption() == strCaption)
- return pItem;
-
- CPropertyGridItem* pChild = pItem->m_lstChilds.FindItem(strCaption);
- if (pChild) return pChild;
- }
- return NULL;
- }
- CPropertyGridItem* CPGListItems::FindItem(UINT nID)
- {
- POSITION pos = GetHeadPosition();
- while (pos)
- {
- CPropertyGridItem* pItem = GetNext(pos);
- if (pItem->GetID() == nID)
- return pItem;
-
- CPropertyGridItem* pChild = pItem->m_lstChilds.FindItem(nID);
- if (pChild) return pChild;
- }
- return NULL;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CPGItemConstraints
- int CPGItemConstraints::FindConstraint(CString str)
- {
- POSITION pos = GetHeadPosition();
- int nIndex = 0;
- while (pos)
- {
- CString strNext = GetNext(pos);
- if (str == strNext)
- return nIndex;
- nIndex++;
- }
- return -1;
- }
|