此例以list控件中添加edit和改变字体和项的背景色为例 1、添加自定义类CListCtrlWithCustomDraw继承与CListCtrl 2、在类面板中右键CListCtrlWithCustomDraw属性添加OnNMCustomdraw方法 3、开始绘制 void CListCtrlWithCustomDraw::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 switch ( lpLVCustomDraw->nmcd.dwDrawStage ) { case CDDS_PREPAINT: { *pResult = CDRF_NOTIFYITEMDRAW; } break; case CDDS_ITEMPREPAINT : { if ( lpLVCustomDraw->nmcd.dwItemSpec % 2 == 0) { lpLVCustomDraw->clrText = RGB(255,0 ,0); // 设置字体颜色 lpLVCustomDraw->clrTextBk = RGB(0,255,255); // 背景色 } else { lpLVCustomDraw->clrText = RGB(0,255, 0); lpLVCustomDraw->clrTextBk = RGB(255,0,255); } *pResult = CDRF_NOTIFYITEMDRAW/*CDRF_DODEFAULT*/; } break; } case CDDS_ITEMPREPAINT|CDDS_SUBITEM: { if ( lpLVCustomDraw->iSubItem == 2)// 在每行的第三列添加edit控件 { CreateCtrl(lpLVCustomDraw->nmcd.dwItemSpec, lpLVCustomDraw->iSubItem); } *pResult = CDRF_DODEFAULT; } break; } } 4、添加edit的接口 void CListCtrlWithCustomDraw::CreateCtrl(int nItem, int nSubItem) { CRect rect; int offset = 0; 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(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; // Get Column alignment LV_COLUMN lvcol; lvcol.mask = LVCF_FMT; GetColumn(nSubItem, &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; dwStyle |=WS_BORDER|WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL; CEdit *pEdit = NULL; CString strText = GetItemText(nItem, nSubItem); pEdit = new CEdit; pEdit->Create(dwStyle, rect, this, 0xff); pEdit->SetWindowText(strText); pEdit->SetFont(GetFont()); EDIT_LIST* edit_info = new EDIT_LIST; memset(edit_info, NULL, sizeof(EDIT_LIST)); edit_info->nItem = nItem; edit_info->nSubItem = nSubItem; edit_info->pEdit = pEdit; m_vecEditlist.push_back(edit_info); } 5、表头移动时要重新设置edit控件的位置, 在CDDS_ITEMPREPAINT|CDDS_SUBITEM中添加 CRect rect; GetSubItemRect(lpLVCustomDraw->nmcd.dwItemSpec, lpLVCustomDraw->iSubItem, LVIR_BOUNDS, rect); vector<EDIT_LIST*>::iterator it = m_vecEditlist.begin(); while ( it != m_vecEditlist.end()) { EDIT_LIST* pEDit = (*it); if ( pEDit != NULL && pEDit->nItem == lpLVCustomDraw->nmcd.dwItemSpec && pEDit->nSubItem == lpLVCustomDraw->iSubItem) { pEDit->pEdit->MoveWindow(rect); } ++it; } 6、拖动是可有能闪烁, 可以用双缓冲画背景来解决闪烁 void CListCtrlWithCustomDraw::OnPaint() { //双缓冲画背景 CPaintDC dc(this); // device context for painting CRect rect; CRect headerRect; CDC MenDC; //内存DC CBitmap MemMap; GetClientRect(&rect); GetDlgItem(0)->GetWindowRect(&headerRect); MenDC.CreateCompatibleDC(&dc); MemMap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); MenDC.SelectObject(&MemMap); MenDC.FillSolidRect(&rect,RGB(255,255,255)); //调用默认的OnPaint(),把图形画在内存DC表上 DefWindowProc(WM_PAINT,(WPARAM)MenDC.m_hDC,(LPARAM)0); //输出到显示设备 dc.BitBlt(0,headerRect.Height(), rect.Width(), rect.Height(), &MenDC, 0, headerRect.Height(), SRCCOPY); MenDC.DeleteDC(); MemMap.DeleteObject(); } 运行结果: 添加其他的控件也是一样的, 将edit替换就可以!!
|
|
来自: 3D建模仿真 > 《MFC 控件自绘》