// ListCtrlCl.cpp : 实现文件 // #include "stdafx.h" #include "ListCtrlCl.h" #include ".\listctrlcl.h" #define IDC_EDITB 4000 #define IDC_BTN 5000 #define IDC_COMB 6000 struct stColor { int nRow; int nCol; COLORREF rgb; }; // CListCtrlCl IMPLEMENT_DYNAMIC(CListCtrlCl, CListCtrl) CListCtrlCl::CListCtrlCl() : m_nRowHeight(0) , m_fontHeight(12) , m_fontWith(0) { m_color = RGB(0,0,0); InitializeCriticalSection(&m_SECTION); m_nRow=-1; m_nCol=-1; m_nRowOld=-1; m_nColOld=-1; m_nRowMin = 0; m_nRowMax = 99999; m_nColMin = 0; m_nColMax = 99999; memset( m_nItemType,0,100*4 ); } CListCtrlCl::~CListCtrlCl() { for (POSITION pos = m_ptrListCol.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListCol.GetNext(pos); delete pColor; pColor = NULL; } m_ptrListCol.RemoveAll(); for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); delete pColor; pColor = NULL; } m_ptrListItem.RemoveAll(); for (POSITION pos = m_colTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_colTextColor.GetNext(pos); delete pColor; pColor = NULL; } m_colTextColor.RemoveAll(); for (POSITION pos = m_ItemTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ItemTextColor.GetNext(pos); delete pColor; pColor = NULL; } m_ItemTextColor.RemoveAll(); DeleteCriticalSection( &m_SECTION ); } BEGIN_MESSAGE_MAP(CListCtrlCl, CListCtrl) ON_WM_MEASUREITEM() ON_WM_MEASUREITEM_REFLECT() ON_NOTIFY_REFLECT(LVN_DELETEALLITEMS, OnLvnDeleteallitems) ON_WM_LBUTTONDOWN() ON_WM_KILLFOCUS() // ON_WM_DELETEITEM() ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem) END_MESSAGE_MAP() // CListCtrlCl 消息处理程序 void CListCtrlCl::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 ModifyStyle(0,LVS_OWNERDRAWFIXED); CListCtrl::PreSubclassWindow(); CHeaderCtrl *pHeader = GetHeaderCtrl(); m_Header.SubclassWindow(pHeader->GetSafeHwnd()); } void CListCtrlCl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: 添加您的代码以绘制指定项 //EnterCriticalSection( &m_SECTION ); TCHAR lpBuffer[256]; LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM ; lvi.iItem = lpDrawItemStruct->itemID ; lvi.iSubItem = 0; lvi.pszText = lpBuffer ; lvi.cchTextMax = sizeof(lpBuffer); VERIFY(GetItem(&lvi)); LV_COLUMN lvc, lvcprev ; ::ZeroMemory(&lvc, sizeof(lvc)); ::ZeroMemory(&lvcprev, sizeof(lvcprev)); lvc.mask = LVCF_WIDTH | LVCF_FMT; lvcprev.mask = LVCF_WIDTH | LVCF_FMT; CDC* pDC; pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rtClient; GetClientRect(&rtClient); for ( int nCol=0; GetColumn(nCol, &lvc); nCol++) { if ( nCol > 0 ) { // Get Previous Column Width in order to move the next display item GetColumn(nCol-1, &lvcprev) ; lpDrawItemStruct->rcItem.left += lvcprev.cx ; lpDrawItemStruct->rcItem.right += lpDrawItemStruct->rcItem.left; } CRect rcItem; if (!GetSubItemRect(lpDrawItemStruct->itemID,nCol,LVIR_LABEL,rcItem)) continue; ::ZeroMemory(&lvi, sizeof(lvi)); lvi.iItem = lpDrawItemStruct->itemID; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.iSubItem = nCol; lvi.pszText = lpBuffer; lvi.cchTextMax = sizeof(lpBuffer); VERIFY(GetItem(&lvi)); CRect rcTemp; rcTemp = rcItem; if (nCol==0) { rcTemp.left -=2; } if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { pDC->FillSolidRect(&rcTemp, RGB(86,159,255));//GetSysColor(COLOR_HIGHLIGHT)) ; pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT)) ; } else { COLORREF color; color = GetBkColor(); pDC->FillSolidRect(rcTemp,color); if (FindColColor(nCol,color)) { pDC->FillSolidRect(rcTemp,color); } if (FindItemColor(nCol,lpDrawItemStruct->itemID,color)) { pDC->FillSolidRect(rcTemp,color); } //pDC->SetTextColor(m_color); } pDC->SelectObject(GetStockObject(DEFAULT_GUI_FONT)); UINT uFormat = DT_CENTER ; if (m_Header.m_Format[nCol]=='0') { uFormat = DT_LEFT; } else if (m_Header.m_Format[nCol]=='1') { uFormat = DT_CENTER; } else if (m_Header.m_Format[nCol]=='2') { uFormat = DT_RIGHT; } TEXTMETRIC metric; pDC->GetTextMetrics(&metric); int ofst; ofst = rcItem.Height() - metric.tmHeight; rcItem.OffsetRect(0,ofst/2); pDC->SetTextColor(m_color); COLORREF color; if (FindColTextColor(nCol,color)) { pDC->SetTextColor(color); } if (FindItemTextColor(nCol,lpDrawItemStruct->itemID,color)) { pDC->SetTextColor(color); } CFont nFont ,* nOldFont; nFont.CreateFont(m_fontHeight,m_fontWith,0,0,0,FALSE,FALSE,0,0,0,0,0,0,_TEXT("宋体"));//创建字体 nOldFont = pDC->SelectObject(&nFont); DrawText(lpDrawItemStruct->hDC, lpBuffer, strlen(lpBuffer), &rcItem, uFormat) ; pDC->SelectStockObject(SYSTEM_FONT) ; DeleteObject( nFont ); } //ReleaseDC( pDC ); //LeaveCriticalSection( &m_SECTION ); } void CListCtrlCl::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct); } void CListCtrlCl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { if (m_nRowHeight>0) { lpMeasureItemStruct->itemHeight = m_nRowHeight; } } int CListCtrlCl::InsertColumn(int nCol, LPCTSTR lpszColumnHeading, int nFormat /* = LVCFMT_LEFT */, int nWidth /* = -1 */, int nSubItem /* = -1 */) { m_Header.m_HChar.Add(lpszColumnHeading); if (nFormat==LVCFMT_LEFT) { m_Header.m_Format = m_Header.m_Format + "0"; } else if (nFormat==LVCFMT_CENTER) { m_Header.m_Format = m_Header.m_Format + "1"; } else if (nFormat==LVCFMT_RIGHT) { m_Header.m_Format = m_Header.m_Format + "2"; } else { m_Header.m_Format = m_Header.m_Format + "1"; } return CListCtrl::InsertColumn(nCol,lpszColumnHeading,nFormat,nWidth,nSubItem); } // Gradient - 渐变系数,立体背景用,不用渐变设为0 void CListCtrlCl::SetHeaderBKColor(int R, int G, int B, int Gradient) //设置表头背景色 { m_Header.m_R = R; m_Header.m_G = G; m_Header.m_B = B; m_Header.m_Gradient = Gradient; } // 设置表头高度 void CListCtrlCl::SetHeaderHeight(float Height) //设置表头高度 { m_Header.m_Height = Height; } bool CListCtrlCl::FindColColor(int col,COLORREF &color) //查找列颜色 { //EnterCriticalSection( &m_SECTION ); int flag = 0; for (POSITION pos = m_ptrListCol.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListCol.GetNext(pos); if (pColor->nCol==col) { flag = 1; color = pColor->rgb; break; } } //LeaveCriticalSection( &m_SECTION ); if (1==flag) { return true; } return false; } bool CListCtrlCl::FindItemColor(int col,int row,COLORREF &color) //查找颜色 { //EnterCriticalSection( &m_SECTION ); int flag = 0; for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); if (pColor->nCol==col&&pColor->nRow==row) { flag = 1; color = pColor->rgb; break; } } //LeaveCriticalSection( &m_SECTION ); if (1==flag) { return true; } return false; } void CListCtrlCl::SetColColor(int col,COLORREF color) //设置列颜色 { stColor *pColor = new stColor; pColor->nCol = col; pColor->rgb = color; m_ptrListCol.AddTail(pColor); } void CListCtrlCl::SetItemColor(int col,int row,COLORREF color) //设置格子颜色 { for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { POSITION pos1 = pos; stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); if (pColor->nCol==col&&pColor->nRow==row) { delete pColor; pColor = NULL; m_ptrListItem.RemoveAt( pos1 ); break; } } stColor *pColor = new stColor; pColor->nCol = col; pColor->nRow = row; pColor->rgb = color; m_ptrListItem.AddTail(pColor); } void CListCtrlCl::SetRowHeigt(int nHeight) //高置行高 { m_nRowHeight = nHeight; CRect rcWin; GetWindowRect(&rcWin); WINDOWPOS wp; wp.hwnd = m_hWnd; wp.cx = rcWin.Width(); wp.cy = rcWin.Height(); wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER; SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp); } void CListCtrlCl::SetHeaderFontHW(int nHeight,int nWith) //设置头部字体宽和高 { m_Header.m_fontHeight = nHeight; m_Header.m_fontWith = nWith; } void CListCtrlCl::SetHeaderTextColor(COLORREF color) //设置头部字体颜色 { m_Header.m_color = color; } BOOL CListCtrlCl::SetTextColor(COLORREF cr) //设置字体颜色 { m_color = cr; return TRUE; } void CListCtrlCl::SetFontHW(int nHeight,int nWith) //设置字体高和宽 { m_fontHeight = nHeight; m_fontWith = nWith; } void CListCtrlCl::SetColTextColor(int col,COLORREF color) { stColor *pColor = new stColor; pColor->nCol = col; pColor->rgb = color; m_colTextColor.AddTail(pColor); } bool CListCtrlCl::FindColTextColor(int col,COLORREF &color) { //EnterCriticalSection( &m_SECTION ); int flag = 0; for (POSITION pos = m_colTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_colTextColor.GetNext(pos); if (pColor->nCol==col) { flag = 1; color = pColor->rgb; break; } } //LeaveCriticalSection( &m_SECTION ); if (1==flag) { return true; } return false; } bool CListCtrlCl::FindItemTextColor(int col,int row,COLORREF &color) { //EnterCriticalSection( &m_SECTION ); int flag = 0; for (POSITION pos = m_ItemTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ItemTextColor.GetNext(pos); if (pColor->nCol==col&&pColor->nRow==row) { flag = 1; color = pColor->rgb; break; } } //LeaveCriticalSection( &m_SECTION ); if (1==flag) { return true; } return false; } void CListCtrlCl::SetItemTextColor(int col,int row,COLORREF color) { stColor *pColor = new stColor; pColor->nCol = col; pColor->nRow = row; pColor->rgb = color; m_ItemTextColor.AddTail(pColor); } void CListCtrlCl::OnLvnDeleteallitems(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // TODO: 在此添加控件通知处理程序代码 //EnterCriticalSection( &m_SECTION ); for (POSITION pos = m_ptrListCol.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListCol.GetNext(pos); delete pColor; pColor = NULL; } m_ptrListCol.RemoveAll(); for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); delete pColor; pColor = NULL; } m_ptrListItem.RemoveAll(); for (POSITION pos = m_colTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_colTextColor.GetNext(pos); delete pColor; pColor = NULL; } m_colTextColor.RemoveAll(); for (POSITION pos = m_ItemTextColor.GetHeadPosition();pos!=NULL;) { stColor *pColor = (stColor*)m_ItemTextColor.GetNext(pos); delete pColor; pColor = NULL; } m_ItemTextColor.RemoveAll(); //LeaveCriticalSection( &m_SECTION ); *pResult = 0; } void CListCtrlCl::Edit() { EndEdit(); CRect rect; if(GetSubItemRect(m_nRow,m_nCol,LVIR_LABEL,rect)==FALSE) return; int sty=WS_CHILD|WS_CLIPSIBLINGS|WS_EX_TOOLWINDOW|WS_BORDER; //int sty=WS_CHILD|WS_EX_TOOLWINDOW; //设置编辑框样式 //设置编辑框样式 if(m_edit.Create(sty,rect,this,IDC_EDITB)==FALSE) return; CString txt=GetItemText(m_nRow,m_nCol); m_edit.SetWindowText(txt);//设置编辑框的内容 m_edit.SetFocus(); m_edit.SetSel(0,-1); m_edit.ShowWindow(SW_SHOW);//显示编辑框 Sleep(100); } void CListCtrlCl::EndEdit() { if( m_edit )//if(m_nRowOld!=-1&&m_nColOld!=-1)//判断是否为初始时 { CString str; m_edit.GetWindowText(str); SetItemText(m_nRowOld,m_nColOld,str);//设置为编辑后的文件内容 m_edit.DestroyWindow(); } } void CListCtrlCl::Btn() { EndBtn(); CRect rect; if(GetSubItemRect(m_nRow,m_nCol,LVIR_LABEL,rect)==FALSE) return; int sty=WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON; //int sty=WS_CHILD|WS_EX_TOOLWINDOW; //设置编辑框样式 //设置编辑框样式 rect.left = rect.right-20; CString txt=GetItemText(m_nRow,m_nCol); if(m_Btn.Create("...",sty,rect,this,IDC_BTN)==FALSE) return; m_Btn.ShowWindow(SW_SHOW);//显示编辑框 //Sleep(100); } void CListCtrlCl::EndBtn() { if( m_Btn ) m_Btn.DestroyWindow(); } void CListCtrlCl::Comb() { EndComb(); CRect rect; if(GetSubItemRect(m_nRow,m_nCol,LVIR_LABEL,rect)==FALSE) return; int sty=WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST; //int sty=WS_CHILD|WS_EX_TOOLWINDOW; //设置编辑框样式 //设置编辑框样式 //rect.left = rect.right-20; if(m_Comb.Create(sty,rect,this,IDC_COMB)==FALSE) return; m_Comb.SetWindowPos(NULL, rect.left, rect.top, rect.Width(), 500, SWP_NOZORDER); m_Comb.ShowWindow(SW_SHOW);//显示编辑框 CString txt=GetItemText(m_nRow,m_nCol); int nSetCur=0; CString str; for( int i=0;im_nRowMax || m_nColm_nColMax ) return; if(m_nRow==m_nRowOld&&m_nCol==m_nColOld)//判断是否是前一点击的行列 return; else { EndAll(); switch( m_nItemType[m_nCol] ) { case 1: Edit(); break; case 2: Btn(); break; case 3: Comb(); break; } m_nRowOld=m_nRow; m_nColOld=m_nCol; } CListCtrl::OnLButtonDown(nFlags, point); } BOOL CListCtrlCl::OnCommand(WPARAM wParam, LPARAM lParam) { switch( HIWORD(wParam) ) { case BN_CLICKED: { //test only!! //sprintf( ss,"%d",LOWORD(wParam) ); //MessageBox(ss); //根据不同的 ID 做不同的处理... switch( LOWORD(wParam) ) { case IDC_BTN: ::SendMessage( this->GetParent()->GetSafeHwnd(),WM_MY_BTN,0,0 ); break; } } break; } return CListCtrl::OnCommand(wParam, lParam); } void CListCtrlCl::OnKillFocus(CWnd* pNewWnd) { CListCtrl::OnKillFocus(pNewWnd); // TODO: 在此处添加消息处理程序代码 //EndAll(); } void CListCtrlCl::OnLvnDeleteitem(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // TODO: 在此添加控件通知处理程序代码 //Item颜色 for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { POSITION pos1 = pos; stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); if( pColor->nRow==pNMLV->iItem ) { delete pColor; pColor = NULL; m_ptrListItem.RemoveAt( pos1 ); } } for (POSITION pos = m_ptrListItem.GetHeadPosition();pos!=NULL;) { POSITION pos1 = pos; stColor *pColor = (stColor*)m_ptrListItem.GetNext(pos); if( pColor->nRow>pNMLV->iItem ) { pColor->nRow--; } } //Item文本颜色 for (POSITION pos = m_ItemTextColor.GetHeadPosition();pos!=NULL;) { POSITION pos1 = pos; stColor *pColor = (stColor*)m_ItemTextColor.GetNext(pos); if( pColor->nRow==pNMLV->iItem ) { delete pColor; pColor = NULL; m_ItemTextColor.RemoveAt( pos1 ); } } for (POSITION pos = m_ItemTextColor.GetHeadPosition();pos!=NULL;) { POSITION pos1 = pos; stColor *pColor = (stColor*)m_ItemTextColor.GetNext(pos); if( pColor->nRow>pNMLV->iItem ) { pColor->nRow--; } } *pResult = 0; }