#include "stdafx.h" #include "UIIListCtrl.h" #include "UIIInplaceEdit.h" #include "UIIInplaceComboBox.h" #include "EarThwormDef.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #ifndef WM_ITEMSELECTED #define WM_ITEMSELECTED (WM_USER+0x1235) #endif CUIIListCtrl::CUIIListCtrl() { } CUIIListCtrl::~CUIIListCtrl() { } BEGIN_MESSAGE_MAP(CUIIListCtrl, CListCtrl) //{{AFX_MSG_MAP(CUIIListCtrl) ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit) ON_NOTIFY_REFLECT(NM_CLICK, OnClick) ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown) ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_MOUSEWHEEL() //}}AFX_MSG_MAP END_MESSAGE_MAP() BOOL CUIIListCtrl::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ) { if( GetFocus() != this) SetFocus(); return CListCtrl::OnMouseWheel(nFlags, zDelta, pt); } void CUIIListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if( GetFocus() != this) SetFocus(); CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } void CUIIListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { if( GetFocus() != this) SetFocus(); CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CUIIListCtrl::SetColumnItemData(int nCol,void * pXData,EType eType) { CHeaderCtrl * pHead = GetHeaderCtrl(); int nCount = pHead->GetItemCount(); if(nCol > nCount) { return FALSE; } m_mapColEnum.SetAt(nCol,eType); if(pXData != NULL) { m_mapColXData.SetAt(nCol,pXData); } return TRUE; } void* CUIIListCtrl::GetColumnItemData(int nCol,EType& eType) { CHeaderCtrl * pHead = GetHeaderCtrl(); int nCount = pHead->GetItemCount(); if(nCol > nCount) { return NULL; } m_mapColEnum.Lookup(nCol,eType); void * pXData = NULL; m_mapColXData.Lookup(nCol,pXData); return pXData; } void CUIIListCtrl::DeleteXData(BOOL bDelete) { POSITION pos = NULL; void * pXData = NULL; int nCol = 0; for(pos = m_mapColXData.GetStartPosition();pos!= NULL;) { m_mapColXData.GetNextAssoc(pos,nCol,pXData); if(pXData != NULL && bDelete) { DELETE_PTR(pXData); } } m_mapColXData.RemoveAll(); } BOOL CUIIListCtrl::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_CHILD | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS; return CListCtrl::PreCreateWindow(cs); } void CUIIListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO *plvDispInfo = (LV_DISPINFO*)pNMHDR; LV_ITEM *plvItem = &plvDispInfo->item; if( plvItem->iItem != -1 && // valid item plvItem->pszText ) // valid text { SetItemText( plvItem->iItem, plvItem->iSubItem, plvItem->pszText); } *pResult = 0; } void CUIIListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; int nItem = pNMListView->iItem; int nCol = pNMListView->iSubItem ; EType eType; BOOL bFind = this->m_mapColEnum.Lookup(nCol,eType); if(bFind) { if(eType == ET_Edit) { EditItem(pNMListView->iItem, pNMListView->iSubItem); } else if(eType == ET_Combo) { ComboItem(pNMListView->iItem, pNMListView->iSubItem); } else if(eType == ET_Check) { CheckItem(pNMListView->iItem, pNMListView->iSubItem,-1); } } else { CWnd *pParent = GetParent(); if (pParent != NULL) { pParent->SendMessage(WM_ITEMSELECTED, 0, (LPARAM)pNMHDR); } } *pResult = 0; } void CUIIListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) { LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR; switch(pLVKeyDow->wVKey) { case VK_DELETE: { int nItem = GetSelectionMark(); if(nItem!=-1) { DeleteItem( nItem ); } } break; default :break; } *pResult = 0; } CComboBox * CUIIListCtrl::ComboItem( int nItem, int nSubItem) { CString strFind = GetItemText(nItem, nSubItem); //basic code start CRect rect; int offset = 0; // Make sure that the item is visible if( !EnsureVisible(nItem, TRUE)) return NULL; GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect); // Now scroll if we need to expose the column 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; rect.right = rect.left + GetColumnWidth(nSubItem); if(rect.right > rcClient.right) { rect.right = rcClient.right; } rect.bottom += 30 * rect.Height();//dropdown area DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST; #define IDC_COMBOBOXINLISTVIEW 0x1235 CStringList * pStrList = NULL; BOOL bFind = m_mapColXData.Lookup(nSubItem,(void *&)pStrList); if(bFind == FALSE) { return NULL; } CImageList * pImageList = GetImageList(LVSIL_SMALL); if(pImageList != NULL && nSubItem == 0) { rect.DeflateRect(16,0,3,1); } else { rect.DeflateRect(2,0,3,1); } CComboBox *pList = new CUIIInplaceComboBox(nItem, nSubItem,pStrList); pList->Create(dwStyle, rect, this, IDC_COMBOBOXINLISTVIEW); pList->ModifyStyleEx(0,WS_EX_CLIENTEDGE);//can we tell at all pList->ShowDropDown(); pList->SelectString(-1, strFind.GetBuffer(1)); return pList; } CEdit * CUIIListCtrl::EditItem( int nItem, int nSubItem) { CRect rect; int offset = 0; if(!EnsureVisible(nItem, TRUE)) { return NULL; } GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect); CRect rcClient; GetClientRect(rcClient); if( offset + rect.left < 0 || offset + rect.left > rcClient.right ) { CSize size(offset + rect.left,0); Scroll(size); rect.left -= size.cx; } rect.left += offset; rect.right = rect.left + GetColumnWidth(nSubItem); if(rect.right > rcClient.right) rect.right = rcClient.right; LV_COLUMN lvcol; lvcol.mask = LVCF_FMT; GetColumn(nSubItem, &lvcol); DWORD dwStyle = 0; 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; CImageList * pImageList = GetImageList(LVSIL_SMALL); if(pImageList != NULL && nSubItem == 0) { rect.DeflateRect(16,0,3,1); } else { rect.DeflateRect(2,0,3,1); } rect.bottom = rect.top + 16; rect.OffsetRect(3,0); dwStyle |= WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL|ES_LEFT; CString ss(GetItemText(nItem, nSubItem)); CEdit *pEdit = new CUIIInplaceEdit(nItem, nSubItem, ss); #define IDC_EDITCTRL 0x1234 pEdit->Create(dwStyle, rect, this, IDC_EDITCTRL); pEdit->SetSel(0,-1); return pEdit; } void CUIIListCtrl::CheckItem( int nItem, int nSubItem,BOOL bCheck) { EType eType; GetColumnItemData(nSubItem,eType); if (eType != ET_Check) return; CRect rect; int offset = 0; if(!EnsureVisible(nItem, TRUE)) { return; } GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect); CRect rcClient; GetClientRect(rcClient); if( offset + rect.left < 0 || offset + rect.left > rcClient.right ) { CSize size(offset + rect.left,0); Scroll(size); rect.left -= size.cx; } rect.left += offset; rect.right = rect.left + GetColumnWidth(nSubItem); if(rect.right > rcClient.right) rect.right = rcClient.right; LV_COLUMN lvcol; lvcol.mask = LVCF_FMT; GetColumn(nSubItem, &lvcol); CImageList * pImageList = GetImageList(LVSIL_SMALL); if(pImageList != NULL && nSubItem == 0) { rect.DeflateRect(16,0,3,1); } else { rect.DeflateRect(2,0,3,1); } rect.bottom = rect.top + 16; rect.OffsetRect(3,0); int nCheck = 0; CString sKey; sKey.Format(_T("%d%d"),nItem,nSubItem); if ( m_mapItemSubToCheck.Lookup(sKey,nCheck) ) { if (nCheck) { if (bCheck == -1) { //È¡·´ SetItemText(nItem,nSubItem,_T("X")); m_mapItemSubToCheck.SetAt(sKey,FALSE); } } else { if (bCheck == -1) { //È¡·´ SetItemText(nItem,nSubItem,_T("¡Ì")); m_mapItemSubToCheck.SetAt(sKey,TRUE); } } } else { if (bCheck) { SetItemText(nItem,nSubItem,_T("¡Ì")); m_mapItemSubToCheck.SetAt(sKey,TRUE); } else { SetItemText(nItem,nSubItem,_T("X")); m_mapItemSubToCheck.SetAt(sKey,0); } } } BOOL CUIIListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText) { CListCtrl::SetItemText(nItem,nSubItem,lpszText); return TRUE; } BOOL CUIIListCtrl::SetItemText(int nItem, int nSubItem, LPCTSTR lpszText,BOOL bCheck) { SetItemText(nItem,nSubItem,lpszText); CheckItem(nItem,nSubItem,bCheck); return TRUE; } BOOL CUIIListCtrl::GetCheck(int nItem,int nSubItem) { CString sKey; sKey.Format(_T("%d%d"),nItem,nSubItem); int nCheck = 0; m_mapItemSubToCheck.Lookup(sKey,nCheck); return nCheck; }