/////////////////////////////////////////////////////////////////////////////////////////////// // // CListViewControl // ////////////////////////////////////////////////////////////////////////////////////////////// #include "ListViewControl.h" CListViewControl::CListViewControl() { ZeroMemory(m_ColType, sizeof(unsigned int) * 100); } CListViewControl::~CListViewControl() { } BEGIN_MESSAGE_MAP(CListViewControl, CListCtrl) //{{AFX_MSG_MAP(CListViewControl) ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndLableEdit) ON_WM_LBUTTONDBLCLK() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CListViewControl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR; switch(lplvcd->nmcd.dwDrawStage) { case CDDS_PREPAINT: *pResult = CDRF_NOTIFYITEMDRAW; break; case CDDS_ITEMPREPAINT: if(lplvcd->nmcd.dwItemSpec % 2) lplvcd->clrTextBk = RGB(200, 228, 248); *pResult = CDRF_DODEFAULT; break; } } void CListViewControl::OnEndLableEdit(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR; LV_ITEM *plvItem = &pDispInfo->item; if(plvItem->pszText != NULL) { SetItemText(plvItem->iItem, plvItem->iSubItem, plvItem->pszText); } *pResult = 0; } void CListViewControl::OnLButtonDblClk(UINT nFlags, CPoint point) { CListCtrl::OnLButtonDblClk(nFlags, point); int index, colnum; if((index = HitTestEx(point, &colnum)) != -1) { if(m_ColType[colnum] == CT_EDIT) { if(GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS) EditSubLabel(index, colnum); } if(m_ColType[colnum] == CT_COMBO) { if(GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS) ShowInPlaceList(index, colnum, m_ColumnStringList[colnum], 0); } } } void CListViewControl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if(GetFocus() != this) SetFocus(); CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } void CListViewControl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if(GetFocus() != this) SetFocus(); CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar); } bool CListViewControl::SetColumnType(int ColNum, unsigned int Type) { if(ColNum < 0) return false; m_ColType[ColNum] = Type; return true; } bool CListViewControl::SetColumnStringList(int ColNum, CStringList &StringList) { if(ColNum < 0) return false; m_ColumnStringList[ColNum].RemoveAll(); POSITION Pos = StringList.GetHeadPosition(); while(Pos) m_ColumnStringList[ColNum].AddTail(StringList.GetNext(Pos)); return true; } int CListViewControl::HitTestEx(CPoint &point, int *col) const { int colnum = 0; int row = HitTest(point, NULL); if(col) *col = 0; if((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT) return row; row = GetTopIndex(); int bottom = row + GetCountPerPage(); if(bottom > GetItemCount()) bottom = GetItemCount(); CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0); int nColumnCount = pHeader->GetItemCount(); INT* piColumnArray = new INT[nColumnCount]; ((CListCtrl*)this)->GetColumnOrderArray(piColumnArray); for(;row <=bottom; row++) { CRect rect; GetItemRect(row, &rect, LVIR_BOUNDS); if(rect.PtInRect(point)) { for(colnum = 0; colnum < nColumnCount; colnum++) { int colwidth = GetColumnWidth(piColumnArray[colnum]); if(point.x >= rect.left && point.x <= (rect.left + colwidth)) { *col = piColumnArray[colnum]; delete [] piColumnArray; return row; } rect.left += colwidth; } } } delete [] piColumnArray; return -1; } CEdit* CListViewControl::EditSubLabel(int nItem, int nCol) { if(!EnsureVisible(nItem, TRUE)) return NULL; CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0); int nColumnCount = pHeader->GetItemCount(); if(nCol >= nColumnCount || GetColumnWidth(nCol) < 5) return NULL; int offset = 0; INT *piColumnArray = new INT[nColumnCount]; ((CListCtrl*)this)->GetColumnOrderArray(piColumnArray); for(int i = 0; nCol != piColumnArray[i]; i++) offset += GetColumnWidth( piColumnArray[i]); delete [] piColumnArray; CRect rect; GetItemRect(nItem, &rect, LVIR_BOUNDS); CRect rcClient; GetClientRect(&rcClient); if(offset + rect.left < 0 || offset + rect.left > rcClient.right) { CSize size; if(offset + rect.left < 0) size.cx = -(offset - rect.left); else size.cx = offset - rect.left; size.cy = 0; Scroll(size); GetItemRect(nItem, &rect, LVIR_BOUNDS); } LV_COLUMN lvcol; lvcol.mask = LVCF_FMT; GetColumn(nCol, &lvcol); DWORD dwStyle ; if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT) dwStyle = ES_LEFT; else if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT) dwStyle = ES_RIGHT; else dwStyle = ES_CENTER; rect.left += offset+4; rect.right = rect.left + GetColumnWidth(nCol) - 3 ; if(rect.right > rcClient.right) rect.right = rcClient.right; dwStyle |= WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL; CEdit *pEdit = new CInPlaceEdit(nItem, nCol, GetItemText(nItem, nCol)); pEdit->Create(dwStyle, rect, this, IDC_IPEDIT); return pEdit; } CComboBox* CListViewControl::ShowInPlaceList(int nItem, int nCol, CStringList &lstItems, int nSel) { if(!EnsureVisible(nItem, TRUE)) return NULL; CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0); int nColumnCount = pHeader->GetItemCount(); if(nCol >= nColumnCount || GetColumnWidth(nCol) < 10) return NULL; int offset = 0; for(int i = 0; i < nCol; i++) offset += GetColumnWidth(i); CRect rect; GetItemRect(nItem, &rect, LVIR_BOUNDS); CRect rcClient; GetClientRect(&rcClient); if(offset + rect.left < 0 || offset + rect.left > rcClient.right) { CSize size; size.cx = offset + rect.left; size.cy = 0; Scroll( size ); rect.left -= size.cx; } rect.left += offset+4; rect.right = rect.left + GetColumnWidth(nCol) - 3 ; int height = rect.bottom-rect.top; rect.bottom += 5*height; if(rect.right > rcClient.right) rect.right = rcClient.right; DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST|CBS_DISABLENOSCROLL; CComboBox *pList = new CInPlaceList(nItem, nCol, &lstItems, nSel); pList->Create(dwStyle, rect, this, IDC_IPEDIT); pList->SetItemHeight(-1, height); pList->SetHorizontalExtent(GetColumnWidth(nCol)); return pList; }