此例以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); // 設(shè)置字體顏色 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、表頭移動時要重新設(shè)置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; //內(nèi)存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)); //調(diào)用默認(rèn)的OnPaint(),把圖形畫在內(nèi)存DC表上 DefWindowProc(WM_PAINT,(WPARAM)MenDC.m_hDC,(LPARAM)0); //輸出到顯示設(shè)備 dc.BitBlt(0,headerRect.Height(), rect.Width(), rect.Height(), &MenDC, 0, headerRect.Height(), SRCCOPY); MenDC.DeleteDC(); MemMap.DeleteObject(); } 運(yùn)行結(jié)果: 添加其他的控件也是一樣的, 將edit替換就可以??!
|
|
來自: 3D建模仿真 > 《MFC 控件自繪》