Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1898 lines
48 KiB
C++

#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);
}