www.pudn.com > CListCtrlTest.rar > MyListCtrl.cpp
// MyListCtrl.cpp : implementation file // #include "stdafx.h" #include "CListCtrlTest.h" #include "MyListCtrl.h" #include#include using namespace std; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMyListCtrl CMyListCtrl::CMyListCtrl() { m_bkColor = RGB(255, 255, 255); //背景白色 m_TextColor = RGB(0, 0, 0); //默认文字颜色黑色 m_bGridPro = false; //默认无网格 m_ColumnCount = 3; //默认列数为0 m_GridColor = RGB(128, 128, 128); } CMyListCtrl::~CMyListCtrl() { } BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl) //{{AFX_MSG_MAP(CMyListCtrl) ON_WM_DESTROY() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyListCtrl message handlers //动态判断输出图片的位置,并输出 void * CMyListCtrl::ShowImage( const char * filepath, int nitem, int subitem, bool flag ) //flag = true 文字在图标前 //默认flag = true { CRect subitemrect = 0; //子列 CPoint point = 0; //图标输出坐标 //计算列宽 int columnwidth = 0; //列宽 columnwidth = GetColumnWidth(subitem); //算列字体宽 int length = 0; //文字宽 CString str = ""; str = GetItemText(nitem, subitem); CClientDC dc(this); CSize size = 0; size = dc.GetTextExtent(str); length = size.cx; //length = GetStringWidth(str); 测试出来宽度不准确 if(flag)//图片在文字后 { //判断字体宽度和列宽度,决定是否进行在指定位置化图 //栏宽度小于图标出现位置 if(columnwidth <= (length + 13 + 5 )) //+13图片宽度,+5为文字和图片间隔宽度 return 0; else { if(subitem == 0) //所要绘制为第一列时 { CPoint pointtemp = 0; if( GetItemPosition(nitem, &pointtemp) ) { point.x = pointtemp.x + length + 5 ; point.y = pointtemp.y; } else { AfxMessageBox("获得所绘坐标失败!"); return 0; } } else { if( GetSubItemRect(nitem, subitem, LVIR_BOUNDS, subitemrect) ) { point.x = subitemrect.left + length +5; point.y = subitemrect.top; } else { AfxMessageBox("获得所绘坐标失败!"); return 0; } } } } else//图标在文字前 { if(columnwidth <= 13 + 5) //+13图片宽度, +5为文字和图片间隔宽度 return 0; else { if(subitem == 0) //所要绘制为第一列时 { CPoint pointtemp = 0; if( GetItemPosition(nitem, &pointtemp) ) { point.x = pointtemp.x ; point.y = pointtemp.y; } else { AfxMessageBox("获得所绘坐标失败!"); return 0; } } else { if( GetSubItemRect(nitem, subitem, LVIR_BOUNDS, subitemrect) ) { point.x = subitemrect.left ; point.y = subitemrect.top; } else { AfxMessageBox("获得所绘坐标失败!"); return 0; } } } } //加载bmp CBitmap bmp; HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), filepath, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); if (hbmp != NULL) { bmp.Attach(hbmp); CDC dcMemory, *pDC; pDC = this->GetDC(); dcMemory.CreateCompatibleDC(pDC); CBitmap* pOldBitmap = dcMemory.SelectObject(&bmp); pDC->BitBlt(point.x, point.y, 13, 13, &dcMemory, 0, 0, SRCCOPY); dcMemory.SelectObject(pOldBitmap); this->ReleaseDC(pDC); this->ReleaseDC(&dcMemory); } else { TRACE0("ERROR: Where's IDB_BITMAP1?\n"); AfxMessageBox("bitmap loading fail!"); } return 0; /* DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL |CBS_DROPDOWNLIST|CBS_DISABLENOSCROLL; CComboBox *pList = new CComboBox(); pList->Create( dwStyle, CRect(point.x, point.y, 260, 30), this, IDC_IPEDIT ); pList->SetItemHeight( -1, 2); //pList->SetHorizontalExtent( GetColumnWidth( nCol )); pList->ShowWindow(SW_SHOW);*/ /* CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP2); CDC * cdc1; cdc1 = this->GetDC(); CBrush brush(&bitmap); cdc1->SelectObject(&brush); cdc1->Rectangle(point.x, point.y, 260, 30); this->ReleaseDC(cdc1); rect11 = CRect(point.x, point.y, 260, 30); this->ClientToScreen(&rect11); */ } int CMyListCtrl::AddImgInfo( char * filepath, const int & nitem, const int &subitem, bool flag) { CMyStorgeImg * data = new CMyStorgeImg; data->m_nitem = nitem; data->m_subitem = subitem; data->m_pfilepath = filepath; data->m_flag = flag; return m_pArrayImg.Add(data); } int CMyListCtrl::AddTextInfo(const CString &str, const int & nitem, const int &subitem, const CRect & textrect, bool flag, COLORREF rc, bool ImpView) { CMyStorgeText * data = new CMyStorgeText; data->m_nitem = nitem; data->m_subitem = subitem; data->m_textrect = CRect(textrect); data->m_str = str; data->m_flag = flag; data->m_ImpColor = rc; data->m_bImpView = ImpView; return m_pArrayText.Add(data); } bool CMyListCtrl::GetDrawTextRect(CRect * rect, const CString & str, int nitem, int subitem, bool flag )//默认flag = true { int width = 0; CRect temprect = 0; if (GetSubItemRect(nitem, subitem, LVIR_LABEL, temprect) != 0) { if(flag) //文字在图片前 { *rect = CRect(temprect); } else //文字在图片后 { *rect = CRect(temprect); rect->left += 13 + 5; //+13图片宽,+5图片和文字间隔 } return true; } else { *rect = 0; return false; } } bool CMyListCtrl::SetBkColorEx(COLORREF cr) { m_bkColor = cr; this->Invalidate(); return true; } bool CMyListCtrl::SetTextColorEx(COLORREF cr) { m_TextColor = cr; this->Invalidate(); //this->UpdateData(); //this->PostMessage(WM_PAINT); return true; } bool CMyListCtrl::SetGridColorEx(COLORREF cr) { m_GridColor = cr; this->Invalidate(); return true; } void CMyListCtrl::SetGridPro(bool GridPro) { m_bGridPro = GridPro; //网格属性 this->Invalidate(); } void CMyListCtrl::SetColumnCount(int count) { m_ColumnCount = count; } void CMyListCtrl::OnDestroy() { CListCtrl::OnDestroy(); // TODO: Add your message handler code here for(int i = 0; i < m_pArrayText.GetSize(); i++) { delete ((CMyStorgeText*)m_pArrayText.GetAt(i)); } for(int j = 0; j < m_pArrayImg.GetSize(); j++) { delete ((CMyStorgeImg*)m_pArrayImg.GetAt(j)); } } void CMyListCtrl::OnPaint() { CPaintDC dc(this); // device context for painting COLORREF syscolor = dc.GetBkColor(); DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_STYLE); ::SetWindowLong(m_hWnd, GWL_STYLE, dwStyle|LVS_REPORT ); /* //字体改变后输出后图形显示错乱 CFont font; VERIFY(font.CreatePointFont(200, "Arial", &dc)); dc.SelectObject(&font); */ CFont * DefFont = dc.SelectObject(this->GetFont()); //设置虚拟图片,目的是调整栏高度 /* static int flag=2; if(flag==2) {//只调用一次SetImageList,否则出错 m_ImageList.Create(0, 20, ILC_COLORDDB|ILC_MASK, 1, 1); //20图片高度,所以拦高度也为20 this->SetImageList(&m_ImageList,LVSIL_SMALL); } flag=1; */ //DWORD style = GetExtendedStyle(); // this->SetExtendedStyle(style | LVS_EX_GRIDLINES); //设置背景色 CBrush brush(m_bkColor); CBrush * DefBrush; CPen pen(PS_SOLID , 1, m_bkColor); CPen * DefPen; dc.SetBkColor(m_bkColor); //设置字体背景色和CListCtrl背景色相同,保证字体不显示背景 DefBrush = dc.SelectObject(&brush); DefPen = (CPen *)dc.SelectObject(&pen); CRect ClientRect; this->GetClientRect(&ClientRect); dc.Rectangle(&ClientRect); dc.SelectObject(DefPen); dc.SelectObject(DefBrush); // dc.SetBkColor(syscolor); //设置字体颜色 dc.SetTextColor(m_TextColor); //数据变化后从新定位并绘制 for(int k = 0; k < m_pArrayText.GetSize(); k++) { CString str; str = ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_str; CRect *rect = new CRect; GetDrawTextRect( rect, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_str, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_nitem, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_subitem, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_flag ); //设置字体突出显示的背景色 if( ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_bImpView ) //文字需要突出显示时 { CRect rect22; this->GetSubItemRect(((CMyStorgeText*)m_pArrayText.GetAt(k))->m_nitem, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_subitem , LVIR_BOUNDS, rect22 ); if(0 == ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_subitem ) //第一列时GetSubItemRect测出是整行的矩形区域 { int length; length = this->GetColumnWidth(((CMyStorgeText*)m_pArrayText.GetAt(k))->m_subitem); rect22.right = length; } CBrush brush22( ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_ImpColor ); CPen pen22(PS_SOLID, 1, ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_ImpColor); CBrush * DefBrush22 = dc.SelectObject(&brush22); CPen * DefPen22 = dc.SelectObject(&pen22); dc.Rectangle(&rect22); dc.SetBkColor(((CMyStorgeText*)m_pArrayText.GetAt(k))->m_ImpColor); dc.DrawText( ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_str, rect, DT_LEFT | DT_END_ELLIPSIS //显示省略号 ); dc.SelectObject(DefBrush22); dc.SelectObject(DefPen22); } else { // CBrush brusha(m_bkColor); // CBrush * defbrush = dc.SelectObject(&brusha); dc.SetBkColor(m_bkColor); //ListCtrl背景色 dc.DrawText( ((CMyStorgeText*)m_pArrayText.GetAt(k))->m_str, rect, DT_LEFT | DT_END_ELLIPSIS //显示省略号 ); // dc.SelectObject(defbrush); } delete rect; } //显示图片 for(int j = 0; j < m_pArrayImg.GetSize(); j++) { //ShowImage(const char * filepath, int nitem, int subitem, bool flag ) ShowImage( ((CMyStorgeImg*)m_pArrayImg.GetAt(j))->m_pfilepath, ((CMyStorgeImg*)m_pArrayImg.GetAt(j))->m_nitem, ((CMyStorgeImg*)m_pArrayImg.GetAt(j))->m_subitem, ((CMyStorgeImg*)m_pArrayImg.GetAt(j))->m_flag ); } //绘制网格线 if(m_bGridPro && (m_ColumnCount != 0)) { CRect rect; CPen pen(PS_SOLID, 1, m_GridColor); CPen * DefPen = dc.SelectObject(&pen); //绘制行 for(int p = 0; p < this->GetItemCount(); p++) { this->GetItemRect(p, &rect, LVIR_BOUNDS); dc.MoveTo(rect.left, rect.top); dc.LineTo(rect.right, rect.top); dc.MoveTo(rect.left, rect.bottom); //绘制最后一行底 dc.LineTo(rect.right, rect.bottom); } //绘制列 for(int column = 0; column < m_ColumnCount; column++) { this->GetSubItemRect(0, column, LVIR_BOUNDS, rect); CRect temprect; this->GetItemRect(GetItemCount() - 1, &temprect, LVIR_BOUNDS); //最后一行的矩形区域坐标 //绘制左边线 dc.MoveTo(rect.left, rect.top); dc.LineTo(rect.left, temprect.bottom ); //绘制右边线 dc.MoveTo(rect.right, rect.top); dc.LineTo(rect.right, temprect.bottom); } dc.SelectObject(DefPen); } //dc.SetBkColor(syscolor); //设置子栏背景色 //CListCtrl一创建起来就绘制网格 if(m_ColumnCount != 0) { CRect rect; CRect rect1; CRect rect2; CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); CPen * DefPen = dc.SelectObject(&pen); //绘制行 if(this->m_pArrayText.GetSize() != 0) //避免画行时每栏高度和字体背景色不一致,精确的画 { this->GetClientRect(&rect); this->GetItemRect(0, &rect2, LVIR_BOUNDS); this->GetHeaderCtrl()->GetClientRect(&rect1); rect.top = rect.top + (rect1.bottom - rect1.top); rect.right = rect1.right - rect1.left; for(int row = 0; row < (rect.bottom - rect.top) / (rect2.bottom - rect2.top) + 1; row++) { dc.MoveTo(rect.left, rect.top + (rect2.bottom - rect2.top) * row); dc.LineTo(rect.right, rect.top +(rect2.bottom - rect2.top) * row); } } else //粗略的绘制行 原因是没加数据之前,算不出每行的高 { this->GetClientRect(&rect); this->GetHeaderCtrl()->GetClientRect(&rect1); //rect.left = rect.left; rect.top = rect.top + (rect1.bottom - rect1.top); rect.right = rect1.right - rect1.left; //rect.bottom = rect.bottom; for(int row = 0; row < rect.bottom - rect.top/20 + 1; row++) { dc.MoveTo(rect.left, rect.top + 20 * row); dc.LineTo(rect.right, rect.top + 20 * row); } } //绘制列 CRect temprect; for(int column = 0; column < m_ColumnCount; column++) { this->GetSubItemRect(0, column, LVIR_BOUNDS, rect); this->GetClientRect(&temprect); //绘制左边线 dc.MoveTo(rect.left, rect.top); dc.LineTo(rect.left, temprect.bottom ); //绘制右边线 dc.MoveTo(rect.right , rect.top); dc.LineTo(rect.right , temprect.bottom); } dc.SelectObject(DefPen); } dc.SelectObject(DefFont); dc.SetBkColor(syscolor); /* CBrush brush(m_bkColor); CBrush * DefBrush; CPen pen(PS_SOLID , 1, m_bkColor); CPen * DefPen; dc.SetBkColor(m_bkColor); //设置字体背景色和CListCtrl背景色相同,保证字体不显示背景 DefBrush = dc.SelectObject(&brush); DefPen = (CPen *)dc.SelectObject(&pen); CRect ClientRect; this->GetClientRect(&ClientRect); dc.Rectangle(&ClientRect); dc.SelectObject(DefPen); dc.SelectObject(DefBrush); */ // Do not call CListCtrl::OnPaint() for painting messages }