Knowledge Base Nr: 00307 treelist.cpp - http://www.swe-kaiser.de

Downloads: source sample project

MFC: VS2005 treecontrol/listcontrol handling (listcontrol editierbar mittels combobox, editbox und commondialog)

  
// CMyDialogBar-Dialogfeld

IMPLEMENT_DYNAMIC(CMyDialogBar, CDialogBar)

CMyDialogBar::CMyDialogBar(CWnd* pParent /*=NULL*/)
: CDialogBar()
{
m_iLastSel = -1;
m_wLastCtrl = NULL;
}

CMyDialogBar::~CMyDialogBar()
{
}

typedef struct tagPETINFO
{
TCHAR szKind[10];
TCHAR szBreed[50];
TCHAR szPrice[20];
}PETINFO;

PETINFO rgPetInfo[ ] =
{
{L"col", L"Poodle", L"$300.00"},
{L"edit", L"Siamese", L"$100.00"},
{L"combo", L"Angel Fish", L"$10.00"},
{L"col", L"DDDDDDD", L"$300.00"},
{L"edit", L"SSSSSSS", L"$100.00"},
{L"combo", L"FFFFFFF Fish", L"$10.00"},
{L"col", L"abc", L"$300.00"},
{L"edit", L"die", L"$100.00"},
{L"combo", L"katze liegt im...", L"$10.00"},
};

bool CMyDialogBar::InitDialog()
{
SetWindowText(L"meine tolle Dialogbar");
//todo: fensterkopf wie dialog oder frame (farben, close-button)

//inputcontrols
GetDlgItem(IDC_EDIT)->ShowWindow(SW_HIDE);
GetDlgItem(IDC_COMBO)->ShowWindow(SW_HIDE);

//tree füllen
CTreeCtrl* pTree = (CTreeCtrl*)GetDlgItem(IDC_TREE);

TVINSERTSTRUCT tvi;

tvi.hParent = NULL;
tvi.hInsertAfter = TVI_LAST;
tvi.item.mask = TVIF_TEXT;
tvi.item.hItem = NULL;
tvi.item.state = 0;
tvi.item.stateMask = 0;
tvi.item.cchTextMax = 50;
tvi.item.cChildren = 0;
tvi.item.lParam = 0;

tvi.item.pszText = L"lulli";
HTREEITEM hi1 = pTree->InsertItem(&tvi);
tvi.hParent = hi1;
tvi.item.pszText = L"jupp zupp";
HTREEITEM hi11 = pTree->InsertItem(&tvi);
tvi.item.pszText = L"karl napp";
HTREEITEM hi12 = pTree->InsertItem(&tvi);

tvi.hParent = NULL;
tvi.item.pszText = L"hugo";
HTREEITEM hi2 = pTree->InsertItem(&tvi);
tvi.hParent = hi2;
tvi.item.pszText = L"egon krenz";
HTREEITEM hi21 = pTree->InsertItem(&tvi);
tvi.item.pszText = L"hans fischi";
HTREEITEM hi22 = pTree->InsertItem(&tvi);

tvi.hParent = NULL;
tvi.item.pszText = L"fritz";
HTREEITEM hi3 = pTree->InsertItem(&tvi);

//listbox füllen
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
pList->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.cx = 80; // width of column in pixels

lvc.iSubItem = 0;
lvc.pszText = L"name";
lvc.fmt = LVCFMT_LEFT;
pList->InsertColumn(0, &lvc);

lvc.iSubItem = 1;
lvc.pszText = L"value";
lvc.fmt = LVCFMT_LEFT;
pList->InsertColumn(1, &lvc);

LVITEM lvI;
lvI.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
lvI.iImage = 0;
lvI.iSubItem = 0;
lvI.state = 0;
lvI.stateMask = 0;

int size = sizeof(rgPetInfo) / sizeof(rgPetInfo[0]);
for (int n=0; n<size; n++)
{
CString str;

str.Format(L"item%d", n);
lvI.iItem = n;
lvI.iSubItem = 0;
lvI.lParam = (LPARAM)&rgPetInfo[n];
lvI.pszText = str.GetBuffer(100); str.ReleaseBuffer();
lvI.pszText = LPSTR_TEXTCALLBACK; // sends an
pList->InsertItem(&lvI);
}

return true;
}

void CMyDialogBar::DoDataExchange(CDataExchange* pDX)
{
CDialogBar::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMyDialogBar, CDialogBar)
ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST, &CMyDialogBar::OnLvnGetdispinfoList)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, &CMyDialogBar::OnLvnItemchangedList)
ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, &CMyDialogBar::OnTvnSelchangedTree)
ON_EN_KILLFOCUS(IDC_EDIT, &CMyDialogBar::OnEnKillfocusEdit)
ON_CBN_KILLFOCUS(IDC_COMBO, &CMyDialogBar::OnCbnKillfocusCombo)
ON_BN_CLICKED(IDC_BUTTON1, &CMyDialogBar::OnBnClickedButton1)
END_MESSAGE_MAP()

void CMyDialogBar::DoResize(int cx, int cy)
{
CWnd* pTree = GetDlgItem(IDC_TREE);
CWnd* pList = GetDlgItem(IDC_LIST);

if (m_wLastCtrl)
::ShowWindow(m_wLastCtrl, SW_HIDE);

if (pTree && pList)
{
this->MoveWindow (0, 0, cx, cy);

pTree->MoveWindow (3, 23, cx-6, cy/2-38);


m_nListX = 3;
m_nListY = cy/2+3;
pList->MoveWindow (m_nListX, m_nListY, cx-6, cy/2-68);
}
}

void CMyDialogBar::OnLvnGetdispinfoList(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);

switch (pDispInfo->item.iSubItem)
{
case 0:
pDispInfo->item.pszText =
rgPetInfo[pDispInfo->item.iItem].szKind;
break;

case 1:
pDispInfo->item.pszText =
rgPetInfo[pDispInfo->item.iItem].szBreed;
break;

case 2:
pDispInfo->item.pszText =
rgPetInfo[pDispInfo->item.iItem].szPrice;
break;
}

*pResult = 0;
}

void CPropDialogBar::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
int iSel = pNMLV->iItem;
if (iSel >= 0)
{
m_iLastSel = iSel;

CWnd* pWnd = NULL;

CPropertyInfo* prop = (CPropertyInfo*)pList->GetItemData(iSel);
ASSERT(prop);

switch (prop->eEditMode)
{
case M_NONE:
break;
case M_USER:
theApp.DoUserDialog(false);
break;
case M_COLOR:
DoColorDialog();
break;
case M_EDIT:
pWnd = GetDlgItem(IDC_EDIT);
break;
case M_COMBO:
pWnd = GetDlgItem(IDC_COMBO);
break;
default:
ASSERT(FALSE);
}

if (pWnd) //handling für überblendete controls
{
if (m_wLastCtrl)
::ShowWindow(m_wLastCtrl, SW_HIDE);
m_wLastCtrl = NULL;

CString sOrgText = pList->GetItemText(iSel, 1);

if (prop->eEditMode == M_COMBO)
CHelperFunc::FillComboBox((CComboBox*)pWnd, sOrgText, prop->sEnumValue);
else if (prop->eEditMode == M_EDIT)
pWnd->SetWindowText(sOrgText);
else
ASSERT(FALSE);

int iSelX1 = pList->GetColumnWidth(0);
int iSelX2 = pList->GetColumnWidth(1);
iSel -= pList->GetTopIndex();
pWnd->SetWindowPos(&wndTop, iSelX1+m_nListX+2, m_nListY+iSel*14+16, iSelX2, 18, SWP_SHOWWINDOW);
pWnd->SetFocus();

m_wLastCtrl = pWnd->GetSafeHwnd();
}
}

*pResult = 0;
}

void CMyDialogBar::OnTvnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

CTreeCtrl* pTree = (CTreeCtrl*)GetDlgItem(IDC_TREE);
HTREEITEM hSel = pNMTreeView->itemNew.hItem;
if (hSel)
{
TCHAR szText[50] = {0};
TVITEM ti;
ti.mask = TVIF_HANDLE | TVIF_TEXT;
ti.hItem = hSel;
ti.pszText = szText;
ti.cchTextMax = sizeof(szText);

pTree->GetItem(&ti);
TRACE(L"sel->%ws\n", ti.pszText);

CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
pList->SetItemText(0, 1, ti.pszText);
pList->SetItemText(1, 1, ti.pszText);
pList->SetItemText(2, 1, ti.pszText);
}

*pResult = 0;
}

void CMyDialogBar::DoColorDialog()
{
CColorDialog dlg;

if (dlg.DoModal() == IDOK)
{
CString sText;

COLORREF color = dlg.GetColor();
sText.Format(L"RGB(%u,%u,%u)", GetRValue(color), GetGValue(color), GetBValue(color));

CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
pList->SetItemText(m_iLastSel, 1, sText);
}
}

void CMyDialogBar::OnEnKillfocusEdit()
{
if (m_iLastSel >=0)
{
CString sText;

GetDlgItem(IDC_EDIT)->GetWindowText(sText);

CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
pList->SetItemText(m_iLastSel, 1, sText);
}
}

void CMyDialogBar::OnCbnKillfocusCombo()
{
if (m_iLastSel >=0)
{
CString sText;

GetDlgItem(IDC_COMBO)->GetWindowText(sText);

CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
pList->SetItemText(m_iLastSel, 1, sText);
}
}

void CMyDialogBar::OnBnClickedButton1()
{
CMainFrame* pMainWnd = (CMainFrame*)AfxGetMainWnd();

pMainWnd->ShowControlBar(this, FALSE, FALSE);
}