Markus Grossmann
April 26th, 1999, 09:58 AM
How may I change a single row in a CListCtrl and a CTreeCtrl? SetTextColor changes all rows!
Thanks
Markus
Thanks
Markus
|
Click to See Complete Forum and Search --> : Change Color of single row in CListCtrl and CTreeCtrl Markus Grossmann April 26th, 1999, 09:58 AM How may I change a single row in a CListCtrl and a CTreeCtrl? SetTextColor changes all rows! Thanks Markus Jonathan May 23rd, 1999, 09:05 PM I have the same problem as your. Did you find out the solution? Will appreciate your help. Thanks. Jim Watters May 25th, 1999, 05:53 PM Do your own DrawItem and control the color from within there. I send a message back to the control's owner to config the color and another message to config the font. This is a farly lengthly function it comes from several locations mostly CodeGuru. void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // Get the display context for the control. CDC* pCDC = CDC::FromHandle(lpDrawItemStruct->hDC); RECT UpdateRect = lpDrawItemStruct->rcItem; RECT UpdateRect2; pCDC->GetClipBox(&UpdateRect2); // Use mask if there is one. UINT uiFlags(ILD_TRANSPARENT); COLORREF OldTextColor = pCDC->GetTextColor(); COLORREF OldBackColor; COLORREF TextColor, NewTextColor; // Check to see if this item is selected. if(lpDrawItemStruct->itemState & ODS_SELECTED) { TextColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT); OldBackColor = pCDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); uiFlags |= ILD_BLEND50; } else { TextColor = GetTextColor();// ::GetSysColor(COLOR_WINDOWTEXT); // OldBackColor = pCDC->SetBkColor(GetBkColor()); // ::GetSysColor(COLOR_WINDOW)); } CPen* penOld; // Create the pen used to draw the gridlines. CPen pen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNFACE));//COLOR_WINDOWTEXT 1999 05 18 bool bVert = m_dwFlag & fVertGrid ? true : false; bool bHorz = m_dwFlag & fHorizGrid ? true : false; if(bVert || bHorz) { penOld = pCDC->SelectObject(&pen); } // Now walk through columns and draw text. char szText[256]; // Increase this if you have longer text. char * pStr; int offset; LV_COLUMN lvc; memset(&lvc, 0, sizeof(lvc)); lvc.mask = LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT | LVCF_ORDER; // *** added LVCF_SUBITEM and LVCF_FMT to get the columne id and justification // Get the image list and draw. CImageList* plistImages = GetImageList(LVSIL_SMALL); LV_ITEM lvi; CFont * pOldFont = pCDC->GetCurrentFont(); LOGFONT defaultLF, curLF, newLF; memset(&defaultLF, 0, sizeof(defaultLF)); GetFont()->GetLogFont(&defaultLF); if(lpDrawItemStruct->itemState & ODS_FOCUS) defaultLF.lfWeight = FW_BOLD; // Create a font now and load it in HFONT hNewFont = ::CreateFontIndirect(&defaultLF); SelectObject(pCDC->m_hDC, hNewFont); curLF = defaultLF; // Calculate the start and end column from the rectangel that needs to be updated int nStartCol = 0; int nEndCol = -1; bool bDidColorChange = false; for (int nColumn = nStartCol; GetColumn(nColumn, &lvc); nColumn++) { CRect rTextClip; // First time. if (nStartCol == nColumn) { rTextClip.left = lpDrawItemStruct->rcItem.left + (plistImages ? 16 : 0); rTextClip.top = lpDrawItemStruct->rcItem.top; rTextClip.right = lpDrawItemStruct->rcItem.left + lvc.cx; rTextClip.bottom = lpDrawItemStruct->rcItem.bottom; } else { // Just "move" the rect to the right. rTextClip.left = rTextClip.right; rTextClip.right = rTextClip.left + lvc.cx; } // Second column selected and only selecting first column if( lpDrawItemStruct->itemState & ODS_SELECTED && false == bDidColorChange && 1 <= nColumn && fHighRowSelect != (m_dwFlag & fHighRowSelect) ) { bDidColorChange = true; TextColor = GetTextColor();//TextColor = ::GetSysColor(COLOR_WINDOWTEXT); pCDC->SetBkColor(GetBkColor()); //pCDC->SetBkColor(::GetSysColor(COLOR_WINDOW)); } // Check to see if this needs to be updated If not go to the next column if(UpdateRect2.right < rTextClip.left || UpdateRect2.left > rTextClip.right) continue; memset(&lvi, 0, sizeof(lvi)); lvi.mask = LVIF_IMAGE | LVIF_STATE; lvi.iItem = lpDrawItemStruct->itemData; lvi.iSubItem = lvc.iSubItem; if(m_fpGetItemText != NULL && m_pOwnerWnd != NULL) { GetItem(&lvi); pStr = (m_pOwnerWnd->*m_fpGetItemText)(lvc.iSubItem, lpDrawItemStruct->itemData);//itemID); } else { // Get the text. lvi.mask |= LVIF_TEXT; lvi.iItem = lpDrawItemStruct->itemID; lvi.iSubItem = lvc.iOrder; lvi.pszText = szText; lvi.cchTextMax = sizeof(szText); GetItem(&lvi); pStr = szText; } // If valid, draw. if (plistImages) { if(lvi.iImage) { //CPoint ptAt(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top); CPoint ptAt(rTextClip.left, rTextClip.top); plistImages->Draw(pCDC, lvi.iImage, ptAt, uiFlags); } } if(m_dwFlag & fCellFont) { newLF = defaultLF; GetParent()->SendMessage(UM_MLC_GETFONT, (WPARAM)&newLF, MAKELONG(lvi.iItem, lvi.iSubItem)); if(memcmp(&newLF, &curLF, sizeof(curLF)) != 0)// Something changed then change the DC { HFONT hOldFont = hNewFont; hNewFont = ::CreateFontIndirect(&newLF); SelectObject(pCDC->m_hDC, hNewFont); ::DeleteObject(hOldFont); curLF = newLF; } } NewTextColor = TextColor; if(m_dwFlag & fCellColor) GetParent()->SendMessage(UM_MLC_GETCOLOR, (WPARAM)&NewTextColor, MAKELONG(lvi.iItem, lvi.iSubItem)); pCDC->SetTextColor(NewTextColor); // Add ellipses if necessary. int nTextCount(lstrlen(pStr)); CSize sizText(pCDC->GetOutputTextExtent(pStr, nTextCount)); // Make the clipping rectangle a little smaller for a gap effect between columns. rTextClip.right -= 4; if (sizText.cx >= rTextClip.Width()) { // Make a shorter string, including "..." that fits. CSize sizEllipse = pCDC->GetOutputTextExtent("...", 3); // Now start dropping characters at the tail until width is correct. while (sizText.cx+sizEllipse.cx > (rTextClip.Width()) && nTextCount > 1) { pStr[--nTextCount] = 0; sizText = pCDC->GetOutputTextExtent(pStr, nTextCount); } // Ok, append "...". pStr[nTextCount] = '.'; pStr[nTextCount + 1] = '.'; pStr[nTextCount + 2] = '.'; pStr[nTextCount + 3] = 0; sizText = pCDC->GetOutputTextExtent(pStr, lstrlen(pStr)); } // Restore full rect. rTextClip.right += 4; // we know know it will fit know check the justification offset =0; //default if(lvc.fmt == LVCFMT_LEFT) if((lvc.fmt & LVCFMT_RIGHT) == LVCFMT_RIGHT) offset = max((rTextClip.Width() - sizText.cx) -8 , 0); else if((lvc.fmt &LVCFMT_CENTER) == LVCFMT_CENTER) offset = ((rTextClip.Width() - sizText.cx) -4)/2; // Print the text. pCDC->ExtTextOut(rTextClip.left + offset + 2, rTextClip.top + 1, ETO_CLIPPED | ETO_OPAQUE, &rTextClip, pStr, lstrlen(pStr), NULL); // Draw the gridlines. leave a gap iff both hor and vert if (bHorz) { pCDC->MoveTo(rTextClip.left + bVert*2, rTextClip.bottom - 1); pCDC->LineTo(rTextClip.right - bVert, rTextClip.bottom - 1); } if (bVert) { pCDC->MoveTo(rTextClip.right - 1, rTextClip.top + bHorz); pCDC->LineTo(rTextClip.right - 1, rTextClip.bottom - bHorz); } } // Reset Font pCDC->SelectObject(pOldFont); ::DeleteObject(hNewFont); // Reset colors pCDC->SetTextColor(OldTextColor); //::GetSysColor(COLOR_WINDOWTEXT)); pCDC->SetBkColor(OldBackColor); //::GetSysColor(COLOR_WINDOW)); // If focused draw focus rect. if (lpDrawItemStruct->itemState & ODS_FOCUS) { CRect rTextClip(lpDrawItemStruct->rcItem); // rTextClip.left += (plistImages ? 16 : 0); pCDC->DrawFocusRect(&rTextClip); } // We must leave the display context as we found it. if(bVert || bHorz) pCDC->SelectObject(penOld); } void CMyListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { TEXTMETRIC tm; HDC hDC = ::GetDC(NULL); CFont* pFont = GetFont(); HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle()); GetTextMetrics(hDC, &tm); lpMeasureItemStruct->itemHeight = tm.tmHeight + tm.tmExternalLeading + 1; SelectObject(hDC, hFontOld); ::ReleaseDC(NULL, hDC); } In the view I capture my UserMessages ON_MESSAGE(UM_MLC_GETFONT, OnGetFont) ON_MESSAGE(UM_MLC_GETCOLOR, OnGetColor) void CView_List::OnGetFont(WPARAM Wparm, LPARAM Lparm) { int row = LOWORD(Lparm); int col = HIWORD(Lparm); LOGFONT * pLF = (LOGFONT *)Wparm; if(pLF) { if(col == ID_DESCRIPTION) pLF->lfItalic = TRUE; } } void CView_List::OnGetColor(WPARAM Wparm, LPARAM Lparm) { int row = LOWORD(Lparm); int col = HIWORD(Lparm); COLORREF * pColor = (COLORREF *)Wparm; if(pColor) { BYTE Red = GetRValue(*pColor); BYTE Green = GetGValue(*pColor); BYTE Blue = GetBValue(*pColor); double top, bottom, depth; GetDocument()->GetTopBottom(&top, &bottom); depth = ((GetItemDouble(LDL_Depth, row) * 2) + GetItemDouble(LDL_Length, row))/2; Red = (BYTE)((depth + top) * (255.0 / max(1, top - bottom))); Blue = 255 - Red; COLORREF Color = RGB(Red, Green, Blue); *pColor = Color; } } codeguru.com
Copyright Internet.com Inc., All Rights Reserved. |