#include "stdafx.h" #include "PropertyListBox.h" #include "InPlaceCtrls.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static unsigned int const CT_IPCEndMsg = RegisterWindowMessage( IPCMSGSTRING ); IMPLEMENT_DYNAMIC(CPropertyItem, CObject) CPropertyItem::~CPropertyItem() { } CPropertyItem::CPropertyItem() { m_bNameEditable = FALSE; m_bValueEditable= TRUE; m_eNameStyle = EDT_NONE; m_eValueStyle = EDT_NONE; m_sName = _T(""); m_sValue = _T(""); m_sFileFilter = _T(""); m_pNameStrList = NULL; m_pValueStrList = NULL; m_dwUserData = 0; m_dwUserDataEx = 0; } CPropertyItem::CPropertyItem(CString sName, CString sValue, ItemStyle nStyle, BOOL bNameEditable, BOOL bValueEditable, CStringList* pStrList, CString sFileFilter) { m_bNameEditable = bNameEditable; m_bValueEditable= bValueEditable; m_eNameStyle = EDT_NONE; m_eValueStyle = nStyle; m_sName = sName; m_sValue = sValue; m_sFileFilter = sFileFilter; m_pNameStrList = NULL; m_pValueStrList = pStrList; m_dwUserData = 0; m_dwUserDataEx = 0; } CPropertyItem& CPropertyItem::operator = (const CPropertyItem& item) { m_bNameEditable = item.m_bNameEditable; m_bValueEditable= item.m_bValueEditable; m_eNameStyle = item.m_eNameStyle; m_eValueStyle = item.m_eValueStyle; m_sName = item.m_sName; m_sValue = item.m_sValue; m_sFileFilter = item.m_sFileFilter; m_pNameStrList = item.m_pNameStrList; m_pValueStrList = item.m_pValueStrList; m_dwUserData = item.m_dwUserData; m_dwUserDataEx = item.m_dwUserDataEx; return *this; } ///////////////////////////////////////////////////////////////////////////// // CPropertyItemTab IMPLEMENT_DYNAMIC(CPropertyItemTab, CObject) CPropertyItemTab::~CPropertyItemTab() { while(m_listItem.GetCount() > 0) delete m_listItem.RemoveHead(); } CPropertyItemTab::CPropertyItemTab() { m_bNameEditable = FALSE; m_bValueEditable= FALSE; m_eNameStyle = EDT_NONE; m_eValueStyle = EDT_NONE; m_sName = _T(""); m_sValue = _T(""); m_sFileFilter = _T(""); m_pNameStrList = NULL; m_pValueStrList = NULL; m_bExpand = FALSE; m_listItem.RemoveAll(); m_dwUserParam = 0; } CPropertyItemTab::CPropertyItemTab(CString sName, BOOL bExpand, CString sValue, ItemStyle nStyle, BOOL bNameEditable, BOOL bValueEditable, CStringList* pStrList, CString sFileFilter) { m_bNameEditable = bNameEditable; m_bValueEditable= bValueEditable; m_eNameStyle = EDT_NONE; m_eValueStyle = nStyle; m_sName = sName; m_sValue = sValue; m_sFileFilter = sFileFilter; m_pNameStrList = NULL; m_pValueStrList = pStrList; m_bExpand = bExpand; m_listItem.RemoveAll(); m_dwUserParam = 0; } CPropertyItemTab::CPropertyItemTab(CPropertyItem& item, BOOL bExpand) { m_bNameEditable = item.m_bNameEditable; m_bValueEditable= item.m_bValueEditable; m_eNameStyle = item.m_eNameStyle; m_eValueStyle = item.m_eValueStyle; m_sName = item.m_sName; m_sValue = item.m_sValue; m_sFileFilter = item.m_sFileFilter; m_pNameStrList = item.m_pNameStrList; m_pValueStrList = item.m_pValueStrList; m_bExpand = bExpand; m_listItem.RemoveAll(); m_dwUserParam = 0; } CPropertyItemTab& CPropertyItemTab::operator = (const CPropertyItemTab& tab) { m_bNameEditable = tab.m_bNameEditable; m_bValueEditable= tab.m_bValueEditable; m_eNameStyle = tab.m_eNameStyle; m_eValueStyle = tab.m_eValueStyle; m_sName = tab.m_sName; m_sValue = tab.m_sValue; m_sFileFilter = tab.m_sFileFilter; m_pNameStrList = tab.m_pNameStrList; m_pValueStrList = tab.m_pValueStrList; m_bExpand = tab.m_bExpand; while(m_listItem.GetCount() > 0) delete m_listItem.RemoveHead(); POSITION pos = tab.m_listItem.GetHeadPosition(); CPropertyItem *pItem, *pNewItem; while(pos != NULL) { pItem = (CPropertyItem*)tab.m_listItem.GetNext(pos); pNewItem = new CPropertyItem(); (*pNewItem) = (*pItem); m_listItem.AddTail(pNewItem); } m_dwUserParam = tab.m_dwUserParam; return *this; } ///////////////////////////////////////////////////////////////////////////// // CPropertyListBox IMPLEMENT_DYNAMIC(CPropertyListBox, CListBox) CPropertyListBox::CPropertyListBox() { m_bEditName = FALSE; m_bSeperate = FALSE; m_nLeftBorder = 16; m_nNameWidth = 60; m_iCurSel = -1; m_pWndCtrl = NULL; m_pWndButton = NULL; m_pWndSpin = NULL; m_listItemTab.RemoveAll(); } CPropertyListBox::~CPropertyListBox() { if(m_pWndCtrl != NULL) delete m_pWndCtrl; if(m_pWndButton != NULL) delete m_pWndButton; if(m_pWndSpin != NULL) delete m_pWndSpin; while(m_listItemTab.GetCount() > 0) delete m_listItemTab.RemoveHead(); } BEGIN_MESSAGE_MAP(CPropertyListBox, CListBox) //{{AFX_MSG_MAP(CPropertyListBox) ON_WM_LBUTTONDBLCLK() ON_WM_SIZE() ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelchange) ON_WM_LBUTTONDOWN() ON_WM_KEYDOWN() ON_WM_MOUSEMOVE() ON_REGISTERED_MESSAGE( CT_IPCEndMsg, OnChildKillFoucs ) ON_WM_VSCROLL() ON_WM_SETCURSOR() ON_WM_LBUTTONUP() ON_WM_CAPTURECHANGED() ON_WM_NCLBUTTONDOWN() ON_WM_MOUSEWHEEL() //}}AFX_MSG_MAP ON_MESSAGE(WM_USER_CHILDVALUECHANGED, OnChildCtrlValueChanged) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPropertyListBox virtual function handlers void CPropertyListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if(GetCount() <= 0) return; CDC dc; dc.Attach(lpDrawItemStruct->hDC); CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_BTNFACE)); CPen* pOldPen = dc.SelectObject(&pen); CRect rect; if(m_nLeftBorder > 0) { GetClientRect(rect); rect.left += m_nLeftBorder; dc.MoveTo(rect.TopLeft()); dc.LineTo(rect.left, rect.bottom); } rect = lpDrawItemStruct->rcItem; rect.left += m_nLeftBorder; rect.bottom--; dc.MoveTo(rect.left, rect.bottom); dc.LineTo(rect.BottomRight()); int iRight = rect.left + m_nNameWidth; dc.MoveTo(iRight, rect.top); dc.LineTo(iRight, rect.bottom); int iIndex = lpDrawItemStruct->itemID; if(iIndex < 0) return; // 判断当前pItem数据是否有效 CPropertyItem* pItem = (CPropertyItem*)lpDrawItemStruct->itemData; BOOL bCategory = pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab)); dc.SelectStockObject(BLACK_PEN); if(m_nLeftBorder > 0 && bCategory) { CPoint ptCenter(m_nLeftBorder / 2, (rect.top + rect.bottom) / 2); CRect rcSign(CPoint(ptCenter.x - 4, ptCenter.y -4), CSize(9, 9)); dc.FillRect(rcSign, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); dc.FrameRect(rcSign, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); // minus dc.MoveTo(ptCenter.x - 2, ptCenter.y); dc.LineTo(ptCenter.x + 3, ptCenter.y); // plus if(!((CPropertyItemTab*)pItem)->m_bExpand) { dc.MoveTo(ptCenter.x, ptCenter.y - 2); dc.LineTo(ptCenter.x, ptCenter.y + 3); } } dc.SelectObject(pOldPen); COLORREF crOldTextColor = dc.GetTextColor(); COLORREF crOldBkColor = dc.GetBkColor(); CRect rcValue = GetItemValueRect(rect); BOOL bSelected = (lpDrawItemStruct->itemState & ODS_SELECTED); if(!bSelected || m_bEditName || m_pWndCtrl != NULL && !m_pWndCtrl->IsWindowVisible() || !pItem->m_bValueEditable || pItem->m_eValueStyle == CPropertyItem::BTN_NONE) { rcValue.DeflateRect(3, 1, 2, 0); if(!pItem->m_bValueEditable) { dc.SetTextColor(::GetSysColor(COLOR_GRAYTEXT)); dc.DrawText(pItem->m_sValue, rcValue, DT_SINGLELINE|DT_VCENTER); dc.SetTextColor(crOldTextColor); } else dc.DrawText(pItem->m_sValue, rcValue, DT_SINGLELINE|DT_VCENTER); } if(bSelected && !m_bEditName) { dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); CWnd* pWnd = GetFocus(); if(pWnd == this || IsChild(pWnd)) dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); else dc.SetBkColor(::GetSysColor(COLOR_GRAYTEXT)); } dc.ExtTextOut(rect.left, rect.top, ETO_OPAQUE, rect, _T(""), 0, NULL); if (m_bEditName && NULL != m_pWndCtrl) m_pWndCtrl->Invalidate(); if (!bSelected || !m_bEditName || pItem->m_eValueStyle == CPropertyItem::BTN_NONE) { rect.DeflateRect(3, 1, 2, 0); CFont fontLabel; CFont* pOldFont = NULL; if(bCategory) { LOGFONT logFont; CFont* pFont = GetFont(); pFont->GetLogFont(&logFont); logFont.lfWeight = FW_BOLD; fontLabel.CreateFontIndirect(&logFont); pOldFont = dc.SelectObject(&fontLabel); } dc.DrawText(pItem->m_sName, rect, DT_SINGLELINE|DT_VCENTER); if(pOldFont != NULL) dc.SelectObject(pOldFont); } dc.SetTextColor(crOldTextColor); dc.SetBkColor(crOldBkColor); dc.Detach(); } ///////////////////////////////////////////////////////////////////////////// // CPropertyListBox private function handlers CRect CPropertyListBox::GetItemValueRect(CRect& rect) { CRect rcValue = rect; rect.right -= rect.Width() - m_nNameWidth; rect.left++; rcValue.left += m_nNameWidth; return rcValue; } void CPropertyListBox::CreatSpinCtrl(CRect rect) { if (rect.Width() > rect.Height() + 4) rect.left = rect.right - rect.Height(); else { rect.left += 4; rect.right = rect.left + rect.Height(); } rect.InflateRect(0, 1, 0, 1); if(m_pWndSpin != NULL) { m_pWndSpin->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); return; } if(m_pWndSpin != NULL) delete m_pWndSpin; m_pWndSpin = new CSpinButtonCtrl(); m_pWndSpin->Create(WS_VISIBLE|WS_CHILD|UDS_SETBUDDYINT|UDS_ARROWKEYS|UDS_NOTHOUSANDS, rect, this, 0); m_pWndSpin->SetRange32(UD_MINVAL, UD_MAXVAL); } void CPropertyListBox::MoveCtrl(CPropertyItem*& pItem, CRect rect) { if(m_pWndSpin != NULL) m_pWndSpin->SetBuddy(NULL); if(m_bEditName) { MoveCtrl(pItem, rect, TRUE); m_pWndCtrl->SetFocus(); return; } if(!pItem->m_bValueEditable) {HideCtrl(); return;} MoveCtrl(pItem, rect, FALSE); m_pWndCtrl->SetFocus(); } void CPropertyListBox::MoveCtrl(CPropertyItem*& pItem, CRect& rect, BOOL bName) { CString sText = pItem->m_sValue; CStringList*& pStrList = pItem->m_pValueStrList; CPropertyItem::ItemStyle eStyle = pItem->m_eValueStyle; if (bName) { sText = pItem->m_sName; pStrList = pItem->m_pNameStrList; eStyle = pItem->m_eNameStyle; } switch(eStyle) { case CPropertyItem::EDT_NONE: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceEdit::CreateCtrl1(m_pWndCtrl, rect, this, sText, FALSE); break; case CPropertyItem::EDT_NUM: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceEdit::CreateCtrl1(m_pWndCtrl, rect, this, sText, TRUE); break; case CPropertyItem::EDT_REAL: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceEdit::CreateCtrl1(m_pWndCtrl, rect, this, sText, FALSE, TRUE); break; case CPropertyItem::EDT_SPIN: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); CreatSpinCtrl(rect); rect.right -= rect.Height(); CInPlaceEdit::CreateCtrl1(m_pWndCtrl, rect, this, sText, TRUE); m_pWndSpin->SetBuddy(m_pWndCtrl); break; case CPropertyItem::CMB_LIST_YESNO: { CStringList list; list.AddTail(_T("是")); list.AddTail(_T("否")); if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceComboBox::CreateCtrl1(m_pWndCtrl, rect, this, sText, &list, 100, TRUE); } break; case CPropertyItem::CMB_LIST: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); if(pStrList == NULL) pStrList = pItem->OnComboAskStringList(bName); CInPlaceComboBox::CreateCtrl1(m_pWndCtrl, rect, this, sText, pStrList, 300, TRUE); break; case CPropertyItem::CMB_DOWN: if(m_pWndButton != NULL) m_pWndButton->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); if(pStrList == NULL) pStrList = pItem->OnComboAskStringList(bName); CInPlaceComboBox::CreateCtrl1(m_pWndCtrl, rect, this, sText, pStrList, 300, FALSE); break; case CPropertyItem::BTN_EDIT: case CPropertyItem::BTN_EDIT_SELFILE: case CPropertyItem::BTN_EDIT_SELPATH: if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceButton::CreateCtrl1(m_pWndButton, rect, this); rect.right -= (rect.Height()+1); CInPlaceEdit::CreateCtrl1(m_pWndCtrl, rect, this, sText, FALSE); break; case CPropertyItem::BTN_NONE: if(m_pWndCtrl != NULL) m_pWndCtrl->ShowWindow(SW_HIDE); if(m_pWndSpin != NULL) m_pWndSpin->ShowWindow(SW_HIDE); CInPlaceButton::CreateCtrl1(m_pWndButton, rect, this); break; default: HideCtrl(); return; } } ///////////////////////////////////////////////////////////////////////////// // CPropertyListBox message handlers void CPropertyListBox::OnSelchange() { int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CRect rect, rcValue; GetItemRect(iCurSel, rect); rect.left += m_nLeftBorder; rect.bottom--; rcValue = GetItemValueRect(rect); CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); if(m_iCurSel == iCurSel && !m_bEditName && pItem->m_bNameEditable && (!pItem->m_bValueEditable || m_pWndCtrl != NULL && m_pWndCtrl->IsWindowVisible())) { m_bEditName = TRUE; MoveCtrl(pItem, rect); } else { if(m_bEditName) { m_bEditName = FALSE; InvalidateRect(rect); GetParent()->SendMessage(WM_USER_CHILDVALUECHANGED, MAKEWPARAM(3, MAKEWORD(0, m_bEditName)), (LPARAM)m_hWnd); } m_iCurSel = iCurSel; MoveCtrl(pItem, rcValue); } GetParent()->SendMessage(WM_USER_CHILDVALUECHANGED, MAKEWPARAM(4, MAKEWORD(0, m_bEditName)), (LPARAM)m_hWnd); } void CPropertyListBox::OnNcLButtonDown(UINT nHitTest, CPoint point) { HideCtrl(); CListBox::OnNcLButtonDown(nHitTest, point); } BOOL CPropertyListBox::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { HideCtrl(); return CListBox::OnMouseWheel(nFlags, zDelta, pt); } void CPropertyListBox::OnLButtonDown(UINT nFlags, CPoint point) { if (IsHitOnSeperator(&m_rcSeperator)) { StartTracking(); return; } CListBox::OnLButtonDown(nFlags, point); int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CRect rect; GetItemRect(iCurSel, rect); rect.right = rect.left + m_nLeftBorder; if(rect.PtInRect(point)) { CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); DoCollapseExpand(pItem); InvalidateRect(rect); } } void CPropertyListBox::OnLButtonDblClk(UINT nFlags, CPoint point) { CListBox::OnLButtonDblClk(nFlags, point); int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CRect rect; GetItemRect(iCurSel, rect); if(rect.PtInRect(point)) { CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); DoCollapseExpand(pItem); rect.right = rect.left + m_nLeftBorder; InvalidateRect(rect); } if(m_pWndCtrl != NULL && m_pWndCtrl->IsWindowVisible()) m_pWndCtrl->SetFocus(); } void CPropertyListBox::OnSize(UINT nType, int cx, int cy) { CListBox::OnSize(nType, cx, cy); UpdateCtrl(); } void CPropertyListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CRect rect; GetItemRect(iCurSel, rect); rect.right = rect.left + m_nLeftBorder; CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { CPropertyItemTab* pTab = (CPropertyItemTab*)pItem; switch(nChar) { case VK_RIGHT: case VK_ADD: if(pTab->m_bExpand) break; ExpandTab(pTab); InvalidateRect(rect); return; case VK_LEFT: case VK_SUBTRACT: if(!pTab->m_bExpand) break; CollapseTab(pTab); InvalidateRect(rect); return; } } if(nChar == VK_RIGHT && m_pWndCtrl != NULL && m_pWndCtrl->IsWindowVisible()) { m_pWndCtrl->SetFocus(); return; } CListBox::OnKeyDown(nChar, nRepCnt, nFlags); } LRESULT CPropertyListBox::OnChildCtrlValueChanged(WPARAM wParam, LPARAM lParam) { int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return 0l; CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); CString sText; switch(wParam) { case 0: //Edit action if( !m_pWndCtrl || !IsWindow(m_pWndCtrl->m_hWnd)) return 0l; if (lParam == 1) break; m_pWndCtrl->GetWindowText(sText); if(m_bEditName) { if (pItem->m_sName == sText) return 0l; pItem->m_sName = sText; } else if(pItem->m_bValueEditable) { if (pItem->m_sValue == sText) return 0l; pItem->m_sValue = sText; } pItem->OnEditCtrlChange(); break; case 1: //Combo box action m_pWndCtrl->GetWindowText(sText); if(m_bEditName) { if (pItem->m_sName == sText) return 0l; pItem->m_sName = sText; } else if(pItem->m_bValueEditable) { if (pItem->m_sValue == sText) return 0l; pItem->m_sValue = sText; } if(lParam == 1) pItem->OnComboSelectChange(); else pItem->OnComboEditChange(); break; case 2: //Button action switch(pItem->m_eValueStyle) { case CPropertyItem::BTN_EDIT: case CPropertyItem::BTN_NONE: pItem->OnButtonClicked(); break; case CPropertyItem::BTN_EDIT_SELFILE: { CString sFilter = pItem->m_sFileFilter; if(sFilter.IsEmpty()) sFilter = _T("All files (*.*)|*.*|"); if(sFilter.Find('|') < 0) sFilter.Format(_T("File type(*.%s)|*.%s|"), sFilter, sFilter); CFileDialog dlg(TRUE, NULL, pItem->m_sValue, OFN_HIDEREADONLY, sFilter); if(dlg.DoModal() == IDOK) { if (pItem->m_sValue == dlg.GetPathName()) return 0l; pItem->m_sValue = dlg.GetPathName(); if(m_pWndCtrl != NULL) m_pWndCtrl->SetWindowText(pItem->m_sValue); } } break; case CPropertyItem::BTN_EDIT_SELPATH: { LPMALLOC pMalloc; if(SHGetMalloc(&pMalloc) != NOERROR) return 0l; BROWSEINFO bInfo; LPITEMIDLIST pidl; bInfo.hwndOwner = m_hWnd; bInfo.pidlRoot = NULL; bInfo.pszDisplayName = pItem->m_sValue.GetBuffer(MAX_PATH); bInfo.lpszTitle = _T(""); bInfo.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; bInfo.lpfn = NULL; pidl = SHBrowseForFolder(&bInfo); pItem->m_sValue.ReleaseBuffer(); if(pidl == NULL) return 0l; SHGetPathFromIDList(pidl, sText.GetBuffer(MAX_PATH)); sText.ReleaseBuffer(); pMalloc->Free(pidl); pMalloc->Release(); if (pItem->m_sValue == sText) return 0l; pItem->m_sValue = sText; if(m_pWndCtrl != NULL) m_pWndCtrl->SetWindowText(pItem->m_sValue); } break; } } GetParent()->SendMessage(WM_USER_CHILDVALUECHANGED, MAKEWPARAM(wParam, MAKEWORD(lParam, m_bEditName)), (LPARAM)m_hWnd); return 0l; } ///////////////////////////////////////////////////////////////////////////// // CPropertyListBox user interface function handlers void CPropertyListBox::EditName() { int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CRect rect; GetItemRect(iCurSel, rect); rect.left += m_nLeftBorder; rect.bottom--; GetItemValueRect(rect); CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->m_bNameEditable) { m_bEditName = TRUE; InvalidateRect(rect); MoveCtrl(pItem, rect); } } void CPropertyListBox::ResetContent() { CListBox::ResetContent(); HideCtrl(); m_iCurSel = -1; while(m_listItemTab.GetCount() > 0) delete m_listItemTab.RemoveHead(); } void CPropertyListBox::Reflash() { CListBox::ResetContent(); HideCtrl(); CPropertyItemTab* pTab; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { pTab = (CPropertyItemTab*)m_listItemTab.GetNext(pos); CListBox::AddString((LPCTSTR)pTab); if(pTab->m_bExpand) { pTab->m_bExpand = FALSE; ExpandTab(pTab); } } } void CPropertyListBox::UpdateCtrl() { HideCtrl(); int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; if(m_pWndCtrl != NULL) { delete m_pWndCtrl; m_pWndCtrl = NULL; } CRect rect; GetItemRect(iCurSel, rect); rect.left += m_nLeftBorder; rect.bottom--; m_bEditName = FALSE; CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); MoveCtrl(pItem, GetItemValueRect(rect)); } CWnd* CPropertyListBox::GetSubCtrl() { return m_pWndCtrl; } UINT CPropertyListBox::SetLeftBorder(UINT nSize) { m_nLeftBorder = nSize; if(m_nLeftBorder < 10) m_nLeftBorder = 10; return m_nLeftBorder; } UINT CPropertyListBox::GetLeftBorder() { return m_nLeftBorder; } UINT CPropertyListBox::SetNameWidth(UINT nWidth) { m_nNameWidth = nWidth; if(m_nNameWidth < 10) m_nNameWidth = 10; return m_nNameWidth; } UINT CPropertyListBox::GetNameWidth() { return m_nNameWidth; } UINT CPropertyListBox::GetTabCount() { return m_listItemTab.GetCount(); } UINT CPropertyListBox::GetTotalItemCount() { UINT nCount = 0; CPropertyItemTab* pTab; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { pTab = (CPropertyItemTab*)m_listItemTab.GetNext(pos); nCount += pTab->m_listItem.GetCount(); } return nCount; } UINT CPropertyListBox::GetItemCount(UINT nTabIndex) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return 0; else return pTab->m_listItem.GetCount(); } UINT CPropertyListBox::GetItemCount(CString sTabName) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return 0; else return pTab->m_listItem.GetCount(); } UINT CPropertyListBox::GetItemCount(CPropertyItemTab*& pTab) { return pTab->m_listItem.GetCount(); } CPropertyItemTab* CPropertyListBox::AddTab(CString sName, BOOL bExpand, BOOL bNameEditable, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable) { CPropertyItemTab* pTab = new CPropertyItemTab(sName, bExpand, sValue, nStyle, bNameEditable, bValueEditable); CListBox::AddString(LPCTSTR(pTab)); m_listItemTab.AddTail(pTab); return pTab; } CPropertyItemTab* CPropertyListBox::AddTab(CPropertyItem& item, BOOL bExpand) { CPropertyItemTab* pTab = new CPropertyItemTab(item, bExpand); CListBox::AddString(LPCTSTR(pTab)); m_listItemTab.AddTail(pTab); return pTab; } CPropertyItemTab* CPropertyListBox::AddTab(CPropertyItemTab& tab) { CPropertyItemTab* pTab = new CPropertyItemTab(); *pTab = tab; CListBox::AddString(LPCTSTR(pTab)); m_listItemTab.AddTail(pTab); if(pTab->m_bExpand) ExpandTab(pTab); return pTab; } BOOL CPropertyListBox::DeleteTab(UINT nTabIndex) { CPropertyItemTab* pTab; POSITION pos = FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; m_listItemTab.RemoveAt(pos); int iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex >= 0) { CollapseTab(pTab); CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pTab; pTab = NULL; UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::DeleteTab(CString sTabName) { CPropertyItemTab* pTab; POSITION pos = FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; m_listItemTab.RemoveAt(pos); int iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex >= 0) { CollapseTab(pTab); CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pTab; pTab = NULL; UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::DeleteTab(CPropertyItemTab*& pTab) { POSITION pos = m_listItemTab.Find(pTab); if(pos == NULL) return FALSE; m_listItemTab.RemoveAt(pos); int iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex >= 0) { CollapseTab(pTab); CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pTab; pTab = NULL; UpdateCtrl(); return TRUE; } CPropertyItemTab* CPropertyListBox::InsertTab(int iTabIndex, CString sName, BOOL bExpand, BOOL bNameEditable, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable) { CPropertyItemTab* pTab = NULL; POSITION pos = NULL; if(iTabIndex >= 0) pos = FindTab(pTab, iTabIndex); CPropertyItemTab* pNewTab = new CPropertyItemTab(sName, bExpand, sValue, nStyle, bNameEditable, bValueEditable); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CString sTabName, CString sName, BOOL bExpand, BOOL bNameEditable, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable) { CPropertyItemTab* pTab; POSITION pos = FindTab(pTab, sTabName); CPropertyItemTab* pNewTab = new CPropertyItemTab(sName, bExpand, sValue, nStyle, bNameEditable, bValueEditable); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CPropertyItemTab*& pTab, CString sName, BOOL bExpand, BOOL bNameEditable, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable) { POSITION pos = m_listItemTab.Find(pTab); CPropertyItemTab* pNewTab = new CPropertyItemTab(sName, bExpand, sValue, nStyle, bNameEditable, bValueEditable); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(int iTabIndex, CPropertyItem& item, BOOL bExpand) { CPropertyItemTab* pTab = NULL; POSITION pos = NULL; if(iTabIndex >= 0) pos = FindTab(pTab, iTabIndex); CPropertyItemTab* pNewTab = new CPropertyItemTab(item, bExpand); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CString sTabName, CPropertyItem& item, BOOL bExpand) { CPropertyItemTab* pTab; POSITION pos = FindTab(pTab, sTabName); CPropertyItemTab* pNewTab = new CPropertyItemTab(item, bExpand); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CPropertyItemTab*& pTab, CPropertyItem& item, BOOL bExpand) { POSITION pos = m_listItemTab.Find(pTab); CPropertyItemTab* pNewTab = new CPropertyItemTab(item, bExpand); if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(int iTabIndex, CPropertyItemTab& tab) { CPropertyItemTab* pTab = NULL; POSITION pos = NULL; if(iTabIndex >= 0) pos = FindTab(pTab, iTabIndex); CPropertyItemTab* pNewTab = new CPropertyItemTab(); *pNewTab = tab; if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); if(pNewTab->m_bExpand) { pNewTab->m_bExpand = FALSE; ExpandTab(pNewTab); } UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CString sTabName, CPropertyItemTab& tab) { CPropertyItemTab* pTab; POSITION pos = FindTab(pTab, sTabName); CPropertyItemTab* pNewTab = new CPropertyItemTab(); *pNewTab = tab; if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); if(pNewTab->m_bExpand) { pNewTab->m_bExpand = FALSE; ExpandTab(pNewTab); } UpdateCtrl(); return pNewTab; } CPropertyItemTab* CPropertyListBox::InsertTab(CPropertyItemTab*& pTab, CPropertyItemTab& tab) { POSITION pos = m_listItemTab.Find(pTab); CPropertyItemTab* pNewTab = new CPropertyItemTab(); *pNewTab = tab; if(pos != NULL) m_listItemTab.InsertBefore(pos, pNewTab); else m_listItemTab.AddTail(pNewTab); int iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) CListBox::InsertString(iIndex, LPCTSTR(pNewTab)); else CListBox::AddString(LPCTSTR(pNewTab)); if(pNewTab->m_bExpand) { pNewTab->m_bExpand = FALSE; ExpandTab(pNewTab); } UpdateCtrl(); return pNewTab; } BOOL CPropertyListBox::AddItem(CString sTabName, CString sName, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable, BOOL bNameEditable, CStringList* pStrList, CString sFileFilter) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; return AddItem(pTab, sName, sValue, nStyle, bValueEditable, bNameEditable, pStrList, sFileFilter); } BOOL CPropertyListBox::AddItem(UINT nTabIndex, CString sName, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable, BOOL bNameEditable, CStringList* pStrList, CString sFileFilter) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return AddItem(pTab, sName, sValue, nStyle, bValueEditable, bNameEditable, pStrList, sFileFilter); } BOOL CPropertyListBox::AddItem(CPropertyItemTab*& pTab, CString sName, CString sValue, CPropertyItem::ItemStyle nStyle, BOOL bValueEditable, BOOL bNameEditable, CStringList* pStrList, CString sFileFilter) { int iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex < 0) return FALSE; CPropertyItem* pItem = new CPropertyItem(sName, sValue, nStyle, bNameEditable, bValueEditable, pStrList, sFileFilter); pTab->m_listItem.AddTail(pItem); if(pTab->m_bExpand) { iIndex += pTab->m_listItem.GetCount(); CListBox::InsertString(iIndex, LPCTSTR(pItem)); } UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::AddItem(UINT nTabIndex, CPropertyItem& item) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return AddItem(pTab, item); } BOOL CPropertyListBox::AddItem(CString sTabName, CPropertyItem& item) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; return AddItem(pTab, item); } BOOL CPropertyListBox::AddItem(CPropertyItemTab*& pTab, CPropertyItem& item) { int iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex < 0) return FALSE; CPropertyItem* pItem = new CPropertyItem(); *pItem = item; pTab->m_listItem.AddTail(pItem); if(pTab->m_bExpand) { iIndex += pTab->m_listItem.GetCount(); CListBox::InsertString(iIndex, LPCTSTR(pItem)); } UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::DeleteItem(UINT nTabIndex, UINT nItemIndex) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return DeleteItem(pTab, nItemIndex); } BOOL CPropertyListBox::DeleteItem(UINT nTabIndex, CString sItemName) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return DeleteItem(pTab, sItemName); } BOOL CPropertyListBox::DeleteItem(UINT nTabIndex, CPropertyItem*& pItem) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return DeleteItem(pTab, pItem); } BOOL CPropertyListBox::DeleteItem(CString sTabName, UINT nItemIndex) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; return DeleteItem(pTab, nItemIndex); } BOOL CPropertyListBox::DeleteItem(CString sTabName, CString sItemName) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; return DeleteItem(pTab, sItemName); } BOOL CPropertyListBox::DeleteItem(CString sTabName, CPropertyItem*& pItem) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab == NULL) return FALSE; return DeleteItem(pTab, pItem); } BOOL CPropertyListBox::DeleteItem(CPropertyItemTab*& pTab, UINT nItemIndex) { CPropertyItem* pItem; POSITION pos = FindItem(pItem, pTab, nItemIndex); if(pItem == NULL) return FALSE; pTab->m_listItem.RemoveAt(pos); if(pTab->m_bExpand) { int iIndex = FindString(-1, (LPCTSTR)pItem); if(iIndex >= 0) CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pItem; pItem = NULL; UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::DeleteItem(CPropertyItemTab*& pTab, CString sItemName) { CPropertyItem* pItem; POSITION pos = FindItem(pItem, pTab, sItemName); if(pItem == NULL) return FALSE; pTab->m_listItem.RemoveAt(pos); if(pTab->m_bExpand) { int iIndex = FindString(-1, (LPCTSTR)pItem); if(iIndex >= 0) CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pItem; pItem = NULL; UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::DeleteItem(CPropertyItemTab*& pTab, CPropertyItem*& pItem) { POSITION pos = pTab->m_listItem.Find(pItem); if(pos == NULL) return FALSE; pTab->m_listItem.RemoveAt(pos); if(pTab->m_bExpand) { int iIndex = FindString(-1, (LPCTSTR)pItem); if(iIndex >= 0) CListBox::DeleteString(iIndex); CListBox::SetCurSel(iIndex); } delete pItem; pItem = NULL; UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::InsertItem(UINT nTabIndex, int iItemIndex, CPropertyItem& item) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return InsertItem(pTab, iItemIndex, item); } BOOL CPropertyListBox::InsertItem(CPropertyItemTab*& pTab, int iItemIndex, CPropertyItem& item) { CPropertyItem* pNewItem = new CPropertyItem(); *pNewItem = item; POSITION pos = NULL; CPropertyItem* pItem; if(iItemIndex >= 0) pos = FindItem(pItem, pTab, iItemIndex); if(pos != NULL) pTab->m_listItem.InsertBefore(pos, pNewItem); else pTab->m_listItem.AddHead(pNewItem); if(pTab->m_bExpand) { int iIndex = FindString(-1, (LPCTSTR)pItem); if(iIndex < 0) { iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex >= 0) iIndex++; } if(iIndex >= 0) CListBox::InsertString(iIndex, (LPCTSTR)pNewItem); } UpdateCtrl(); return TRUE; } BOOL CPropertyListBox::InsertItem(UINT nTabIndex, CPropertyItem*& pItem, CPropertyItem& item) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab == NULL) return FALSE; return InsertItem(pTab, pItem, item); } BOOL CPropertyListBox::InsertItem(CPropertyItemTab*& pTab, CPropertyItem*& pItem, CPropertyItem& item) { CPropertyItem* pNewItem = new CPropertyItem(); *pNewItem = item; POSITION pos = pTab->m_listItem.Find(pItem); if(pos != NULL) pTab->m_listItem.InsertBefore(pos, pNewItem); else pTab->m_listItem.AddHead(pNewItem); if(pTab->m_bExpand) { int iIndex = FindString(-1, (LPCTSTR)pItem); if(iIndex < 0) { iIndex = FindString(-1, (LPCTSTR)pTab); if(iIndex >= 0) iIndex++; } if(iIndex >= 0) CListBox::InsertString(iIndex, (LPCTSTR)pNewItem); } UpdateCtrl(); return TRUE; } POSITION CPropertyListBox::GetFirstTabPositon() { return m_listItemTab.GetHeadPosition(); } POSITION CPropertyListBox::GetLastTabPositon() { return m_listItemTab.GetTailPosition(); } CPropertyItemTab* CPropertyListBox::GetNextTab(POSITION& pos) { return m_listItemTab.GetNext(pos); } CPropertyItemTab* CPropertyListBox::GetPrevTab(POSITION& pos) { return m_listItemTab.GetPrev(pos); } POSITION CPropertyListBox::GetTabPosition(CPropertyItemTab* pTab) { return m_listItemTab.Find(pTab); } POSITION CPropertyListBox::FindTab(CPropertyItemTab*& pTab, CString sTabName) { pTab = NULL; CPropertyItemTab* pTabTemp; POSITION pos = m_listItemTab.GetHeadPosition(); POSITION posBak = NULL; while(pos != NULL) { posBak = pos; pTabTemp = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTabTemp->m_sName == sTabName) { pTab = pTabTemp; return posBak; } } return NULL; } POSITION CPropertyListBox::FindTab(CPropertyItemTab*& pTab, UINT nTabIndex) { pTab = NULL; POSITION pos = m_listItemTab.FindIndex(nTabIndex); if(pos != NULL) pTab = (CPropertyItemTab*)m_listItemTab.GetAt(pos); return pos; } POSITION CPropertyListBox::FindItem(CPropertyItem*& pItem, CPropertyItemTab*& pTab, UINT nItemIndex) { pItem = NULL; POSITION pos = pTab->m_listItem.FindIndex(nItemIndex); if(pos != NULL) pItem = (CPropertyItem*)pTab->m_listItem.GetAt(pos); return pos; } POSITION CPropertyListBox::FindItem(CPropertyItem*& pItem, CPropertyItemTab*& pTab, CString sItemName) { pItem = NULL; CPropertyItem* pItemTemp; POSITION pos = pTab->m_listItem.GetHeadPosition(); POSITION posBak = NULL; while(pos != NULL) { posBak = pos; pItemTemp = (CPropertyItem*)pTab->m_listItem.GetNext(pos); if(pItemTemp->m_sName == sItemName) { pItem = pItemTemp; return posBak; } } return NULL; } int CPropertyListBox::FindTabIndex(CString sTabName, UINT nStart/* = 0*/) { CPropertyItemTab* pTab; POSITION pos = m_listItemTab.FindIndex(nStart); while(pos != NULL) { pTab = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTab->m_sName == sTabName) return nStart; nStart++; } return -1; } int CPropertyListBox::FindTabIndex(CPropertyItemTab* pTab, UINT nStart) { CPropertyItemTab* pTab1; POSITION pos = m_listItemTab.FindIndex(nStart); while(pos != NULL) { pTab1 = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTab == pTab1) return nStart; nStart++; } return -1; } int CPropertyListBox::FindItemIndex(CString sItemName, UINT nTabIndex, UINT nStart/* = 0*/) { POSITION pos = m_listItemTab.FindIndex(nTabIndex); if(pos == NULL) return -1; CPropertyItemTab* pTab = (CPropertyItemTab*)m_listItemTab.GetAt(pos); CPropertyItem* pItem; pos = pTab->m_listItem.FindIndex(nStart); while(pos != NULL) { pItem = (CPropertyItem*)pTab->m_listItem.GetNext(pos); if(pItem->m_sName == sItemName) return nStart; nStart++; } return -1; } int CPropertyListBox::FindIndex(CPropertyItem* pItem) { return CListBox::FindString(-1, (LPCTSTR)pItem); } int CPropertyListBox::GetCurSel() { return CListBox::GetCurSel(); } void CPropertyListBox::GetCurSel(int& iTabIndex, int& iItemIndex) { iTabIndex = -1; iItemIndex = -1; int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { CPropertyItemTab* pTab = (CPropertyItemTab*)pItem; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iTabIndex++; if(pTab == (CPropertyItemTab*)m_listItemTab.GetNext(pos)) break; } return; } int iIndex = -1; CPropertyItemTab* pTab; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iTabIndex++; iIndex++; pTab = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTab->m_bExpand) iIndex += pTab->m_listItem.GetCount(); if(iCurSel <= iIndex) { iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) iItemIndex = iCurSel - iIndex - 1; break; } } } void CPropertyListBox::GetCurSel(int& iTabIndex, CPropertyItem*& pItem) { iTabIndex = -1; pItem = NULL; int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { CPropertyItemTab* pTab = (CPropertyItemTab*)pItem; pItem = NULL; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iTabIndex++; if(pTab == (CPropertyItemTab*)m_listItemTab.GetNext(pos)) break; } return; } int iIndex = -1; CPropertyItemTab* pTab; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iTabIndex++; iIndex++; pTab = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTab->m_bExpand) iIndex += pTab->m_listItem.GetCount(); if(iCurSel <= iIndex) break; } } void CPropertyListBox::GetCurSel(CPropertyItemTab*& pTab, int& iItemIndex) { pTab = NULL; iItemIndex = -1; int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; CPropertyItem* pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { pTab = (CPropertyItemTab*)pItem; return; } int iIndex = -1; CPropertyItemTab* pTabTemp; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iIndex++; pTabTemp = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTabTemp->m_bExpand) iIndex += pTabTemp->m_listItem.GetCount(); if(iCurSel <= iIndex) { pTab = pTabTemp; iIndex = FindString(-1, LPCTSTR(pTab)); if(iIndex >= 0) iItemIndex = iCurSel - iIndex - 1; break; } } } void CPropertyListBox::GetCurSel(CPropertyItemTab*& pTab, CPropertyItem*& pItem) { pTab = NULL; pItem = NULL; int iCurSel = CListBox::GetCurSel(); if(iCurSel < 0) return; pItem = (CPropertyItem*)GetItemData(iCurSel); if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { pTab = (CPropertyItemTab*)pItem; pItem = NULL; return; } int iIndex = -1; CPropertyItemTab* pTabTemp; POSITION pos = m_listItemTab.GetHeadPosition(); while(pos != NULL) { iIndex++; pTabTemp = (CPropertyItemTab*)m_listItemTab.GetNext(pos); if(pTabTemp->m_bExpand) iIndex += pTabTemp->m_listItem.GetCount(); if(iCurSel <= iIndex) {pTab = pTabTemp; break;} } } void CPropertyListBox::SetCurSel(int iTabIndex, int iItemIndex) { if(iTabIndex < 0) { CListBox::SetCurSel(-1); return; } CPropertyItemTab* pTab; if(FindTab(pTab, iTabIndex) == NULL) return; if(!pTab->m_bExpand || iItemIndex < 0) { CListBox::SetCurSel(FindString(-1, (LPCTSTR)pTab)); UpdateCtrl(); return; } CPropertyItem* pItem; if(FindItem(pItem, pTab, iItemIndex) == NULL) return; CListBox::SetCurSel(FindString(-1, (LPCTSTR)pItem)); UpdateCtrl(); } void CPropertyListBox::SetCurSel(int iTabIndex, CPropertyItem*& pItem) { if(iTabIndex < 0) { CListBox::SetCurSel(-1); return; } CPropertyItemTab* pTab; if(FindTab(pTab, iTabIndex) == NULL) return; if(!pTab->m_bExpand || pItem == NULL) { CListBox::SetCurSel(FindString(-1, (LPCTSTR)pTab)); UpdateCtrl(); return; } CListBox::SetCurSel(FindString(-1, (LPCTSTR)pItem)); UpdateCtrl(); } void CPropertyListBox::SetCurSel(CPropertyItemTab*& pTab, int iItemIndex) { if(pTab == NULL) { CListBox::SetCurSel(-1); return; } if(!pTab->m_bExpand || iItemIndex < 0) { CListBox::SetCurSel(FindString(-1, (LPCTSTR)pTab)); UpdateCtrl(); return; } CPropertyItem* pItem; if(FindItem(pItem, pTab, iItemIndex) == NULL) return; CListBox::SetCurSel(FindString(-1, (LPCTSTR)pItem)); UpdateCtrl(); } void CPropertyListBox::SetCurSel(CPropertyItemTab*& pTab, CPropertyItem*& pItem) { if(pTab == NULL) { CListBox::SetCurSel(-1); return; } if(!pTab->m_bExpand || pItem == NULL) { CListBox::SetCurSel(FindString(-1, (LPCTSTR)pTab)); UpdateCtrl(); return; } CListBox::SetCurSel(FindString(-1, (LPCTSTR)pItem)); UpdateCtrl(); } void CPropertyListBox::CollapseTab(CString sTabName) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab != NULL) CollapseTab(pTab); } void CPropertyListBox::CollapseTab(UINT nTabIndex) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab != NULL) CollapseTab(pTab); } void CPropertyListBox::CollapseTab(CPropertyItemTab *&pTab) { int iIndex = FindString(-1, (LPCTSTR)pTab); if(!pTab->m_bExpand || iIndex < 0) return; pTab->m_bExpand = FALSE; for(int i = iIndex + pTab->m_listItem.GetCount(); i > iIndex; i--) CListBox::DeleteString(i); } void CPropertyListBox::ExpandTab(CString sTabName) { CPropertyItemTab* pTab; FindTab(pTab, sTabName); if(pTab != NULL) ExpandTab(pTab); } void CPropertyListBox::ExpandTab(UINT nTabIndex) { CPropertyItemTab* pTab; FindTab(pTab, nTabIndex); if(pTab != NULL) ExpandTab(pTab); } void CPropertyListBox::ExpandTab(CPropertyItemTab *&pTab) { int iIndex = FindString(-1, (LPCTSTR)pTab); if(pTab->m_bExpand || iIndex < 0) return; int iBackIndex = iIndex; pTab->m_bExpand = TRUE; CPropertyItem* pItem; POSITION pos = pTab->m_listItem.GetHeadPosition(); while(pos != NULL) { iIndex++; pItem = (CPropertyItem*)pTab->m_listItem.GetNext(pos); CListBox::InsertString(iIndex, LPCTSTR(pItem)); } // 展开后设置可见 CRect rcClient; CListBox::GetClientRect(rcClient); int iCount = rcClient.Height() / CListBox::GetItemHeight(iIndex); int iTop = CListBox::GetTopIndex(); int iScroll = (iBackIndex + pTab->m_listItem.GetCount()) - (iTop + iCount); if (iScroll > 0) { iTop += (iScroll + 1); if (iTop > iBackIndex) iTop = iBackIndex; CListBox::SetTopIndex(iTop); } } void CPropertyListBox::DoCollapseExpand(CPropertyItem*& pItem) { if(pItem->IsKindOf(RUNTIME_CLASS(CPropertyItemTab))) { CPropertyItemTab* pTab = (CPropertyItemTab*)pItem; if(pTab->m_bExpand) CollapseTab(pTab); else ExpandTab(pTab); } } /////////////////////////////////////////////////////////////////////////// // Avoid the origin function int CPropertyListBox::AddString(LPCTSTR lpszItem) { return -1; } int CPropertyListBox::InsertString(int nIndex, LPCTSTR lpszItem) { return -1; } int CPropertyListBox::DeleteString(UINT nIndex) { return -1; } int CPropertyListBox::SetItemData(int nIndex, DWORD dwItemData) { return -1; } void CPropertyListBox::OnMouseMove(UINT nFlags, CPoint point) { if (m_bSeperate) { DrawSeperator(); int iOffset = point.x - m_rcTrack.CenterPoint().x; m_rcTrack.OffsetRect(iOffset, 0); DrawSeperator(); return; } CListBox::OnMouseMove(nFlags, point); BOOL bOutSide; int iItem = CListBox::ItemFromPoint(point, bOutSide); if(bOutSide || iItem < 0) return; CRect rect, rcValue; CListBox::GetItemRect(iItem, rect); rect.left += m_nLeftBorder; rect.OffsetRect(2, 1); rcValue = GetItemValueRect(rect); CPropertyItem* pItem = (CPropertyItem*)CListBox::GetItemData(iItem); if(rect.PtInRect(point)) { m_titletip.Show(rect, pItem->m_sName, 0); } else if(rcValue.PtInRect(point)) { m_titletip.Show(rcValue, pItem->m_sValue, 0); } } void CPropertyListBox::PreSubclassWindow() { m_titletip.Create(this); CListBox::PreSubclassWindow(); } LRESULT CPropertyListBox::OnChildKillFoucs(WPARAM wParam, LPARAM lParam) { UNUSED_ALWAYS( wParam ); LPIPCENDINFO lpEndInfo = (LPIPCENDINFO)lParam; if( lpEndInfo->uKind == IPEK_KILLFOUCE ) { if( m_pWndCtrl != NULL && m_pWndCtrl->IsWindowVisible() && lpEndInfo->hNewWnd != m_pWndCtrl-> m_hWnd ) { if( m_bEditName && m_pWndCtrl->IsKindOf(RUNTIME_CLASS(CInPlaceEdit)) ) { GetParent()->SendMessage(WM_USER_CHILDVALUECHANGED, MAKEWPARAM(3, MAKEWORD(1, m_bEditName)), (LPARAM)m_hWnd); } } } return 0l; } void CPropertyListBox::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if(pScrollBar && pScrollBar->m_hWnd == m_pWndSpin->m_hWnd) return; CListBox::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CPropertyListBox::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (IsHitOnSeperator()) { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE)); return TRUE; } return CListBox::OnSetCursor(pWnd, nHitTest, message); } BOOL CPropertyListBox::IsHitOnSeperator(CRect* pRect/* = NULL*/) { CPoint pt; GetCursorPos(&pt); CListBox::ScreenToClient(&pt); CRect rc; CListBox::GetItemRect(0, rc); rc.left += m_nLeftBorder + m_nNameWidth - 1; rc.right = rc.left + 3; rc.bottom = rc.top + rc.Height() * CListBox::GetCount(); if (pRect) pRect->SetRect(rc.left, rc.top, rc.right, rc.bottom); return rc.PtInRect(pt); } void CPropertyListBox::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bSeperate) { StopTracking(); return; } CListBox::OnLButtonUp(nFlags, point); } void CPropertyListBox::OnCaptureChanged(CWnd *pWnd) { if (m_bSeperate) StopTracking(TRUE); CListBox::OnCaptureChanged(pWnd); } void CPropertyListBox::StartTracking() { SetCapture(); RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW); LockWindowUpdate(); m_bSeperate = TRUE; m_rcTrack = m_rcSeperator; DrawSeperator(); } void CPropertyListBox::StopTracking(BOOL bCancel/* = FALSE*/) { DrawSeperator(); UnlockWindowUpdate(); ReleaseCapture(); m_bSeperate = FALSE; if (bCancel) return; int iOffset = m_rcTrack.left - m_rcSeperator.left; if (iOffset == 0) { DrawSeperator(); return; } CRect rc; CListBox::GetItemRect(0, rc); UINT nMaxWidth = rc.Width() - m_nLeftBorder - 2; m_nNameWidth += iOffset; if (int(m_nNameWidth) < 1) m_nNameWidth = 1; else if (m_nNameWidth > nMaxWidth) m_nNameWidth = nMaxWidth; UpdateCtrl(); CListBox::Invalidate(); } void CPropertyListBox::DrawSeperator() { CRect rc; CListBox::GetClientRect(&rc); rc.OffsetRect(0, 2); CRgn rg; rg.CreateRectRgnIndirect(&rc); CDC *pDC = GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE); pDC->SelectClipRgn(&rg); CBrush* pBrush = pDC->SelectObject(CDC::GetHalftoneBrush()); pDC->PatBlt(m_rcTrack.left, m_rcTrack.top, m_rcTrack.Width(), m_rcTrack.Height(), PATINVERT); pDC->SelectObject(pBrush); ReleaseDC(pDC); }