ListCtrl Custom Draw
-
I have been reading Michael Dunn's article about Custom Draw and the List Control to figure out how to change the background and text color to change on a selected item. I have tried the code below in both the pre and post paint stages. Also in both stages I have tryed returning both CDRF_DODEFAULT and CDRF_SKIPDEFAULT, either nothing happens.. or no selection highlight is drawn. Anybody have any ideas? I'm lost with Custom Draw.. I don't understand why I can change the text/bk color for every item.. but if I test for a selected item, and then try and change the text/bk color.. nadda.. nothing .. zip..
void CPlayListWindow::OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult ) { NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR ); // tell windows to draw the control its self // unless we change it *pResult = 0; // Now we need to check the draw stage // if the stage is at the pre paint stage // we need to tell windows that we want // messages for every item if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage) *pResult = CDRF_NOTIFYITEMDRAW; else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) { // This is the prepaint stage for each // individual item. *pResult = CDRF_NOTIFYPOSTPAINT; } else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage) { // first we are going to check to see if the // item is selected. If it is we are going // to tell it the background color // is transparent (black) and the text color is blue LVITEM rItem; int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec ); ZeroMemory ( &rItem, sizeof(LVITEM) ); rItem.mask = LVIF_IMAGE | LVIF_STATE; rItem.iItem = nItem; rItem.stateMask = LVIS_SELECTED; GetListCtrl().GetItem(&rItem); if(rItem.state == LVIS_SELECTED) { // now lets change the items color pLVCD->clrTextBk = RGB(0,0,255); pLVCD->clrText = RGB(0,0,255); // Tell windows to draw it for us now //*pResult = CDRF_DODEFAULT *pResult = CDRF_SKIPDEFAULT; } } }
C# a poor attempt at bringing C++ to the VB masses
-
I have been reading Michael Dunn's article about Custom Draw and the List Control to figure out how to change the background and text color to change on a selected item. I have tried the code below in both the pre and post paint stages. Also in both stages I have tryed returning both CDRF_DODEFAULT and CDRF_SKIPDEFAULT, either nothing happens.. or no selection highlight is drawn. Anybody have any ideas? I'm lost with Custom Draw.. I don't understand why I can change the text/bk color for every item.. but if I test for a selected item, and then try and change the text/bk color.. nadda.. nothing .. zip..
void CPlayListWindow::OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult ) { NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR ); // tell windows to draw the control its self // unless we change it *pResult = 0; // Now we need to check the draw stage // if the stage is at the pre paint stage // we need to tell windows that we want // messages for every item if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage) *pResult = CDRF_NOTIFYITEMDRAW; else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) { // This is the prepaint stage for each // individual item. *pResult = CDRF_NOTIFYPOSTPAINT; } else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage) { // first we are going to check to see if the // item is selected. If it is we are going // to tell it the background color // is transparent (black) and the text color is blue LVITEM rItem; int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec ); ZeroMemory ( &rItem, sizeof(LVITEM) ); rItem.mask = LVIF_IMAGE | LVIF_STATE; rItem.iItem = nItem; rItem.stateMask = LVIS_SELECTED; GetListCtrl().GetItem(&rItem); if(rItem.state == LVIS_SELECTED) { // now lets change the items color pLVCD->clrTextBk = RGB(0,0,255); pLVCD->clrText = RGB(0,0,255); // Tell windows to draw it for us now //*pResult = CDRF_DODEFAULT *pResult = CDRF_SKIPDEFAULT; } } }
C# a poor attempt at bringing C++ to the VB masses
I have been working from the same article just yesterday. Hers a copy of mu OnCustom draw...
void CCommunicationView::OnCustomDrawLog(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW *pLVCD = reinterpret_cast(pNMHDR);\*pResult = CDRF\_DODEFAULT; // assume normal windows drawn control if (CDDS\_PREPAINT == pLVCD->nmcd.dwDrawStage) { \*pResult = CDRF\_NOTIFYITEMDRAW; } else if (CDDS\_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) { // this is the prepaint stage, we need each sub-item pre-paint \*pResult = CDRF\_NOTIFYSUBITEMDRAW; } else if ((CDDS\_ITEMPREPAINT | CDDS\_SUBITEM) == pLVCD->nmcd.dwDrawStage) { // now render the image if it has one int item = pLVCD->nmcd.dwItemSpec; LVITEM rItem; ZeroMemory(&rItem, sizeof(LVITEM)); rItem.mask = LVIF\_IMAGE | LVIF\_STATE; rItem.iItem = item; rItem.stateMask = LVIS\_SELECTED; m\_Log.GetItem(&rItem ); // we render the text ourselves in the right colour and take tabs into account int value = m\_Log.GetItemData(item); CDC\* pDC = CDC::FromHandle ( pLVCD->nmcd.hdc ); CRect rcText; CRect rcIcon; CString text; m\_Log.GetItemRect(item, &rcIcon, LVIR\_ICON); m\_Log.GetItemRect(item, &rcText, LVIR\_BOUNDS); rcText.left += rcIcon.Width(); text = m\_Log.GetItemText(item, 0); if (rItem.state & LVIS\_SELECTED) { pDC->SetTextColor(GetSysColor(COLOR\_HIGHLIGHTTEXT)); CBrush brush(GetSysColor(COLOR\_HIGHLIGHT)); pDC->FillRect(rcText, &brush); } else { pDC->SetTextColor(value); CBrush brush(GetSysColor(COLOR\_HIGHLIGHTTEXT)); pDC->FillRect(rcText, &brush); } pDC->DrawText(text, rcText, DT\_END\_ELLIPSIS | DT\_EXPANDTABS | DT\_SINGLELINE | DT\_VCENTER); pLVCD->clrText = value; m\_ilLog.Draw(pDC, rItem.iImage, rcIcon.TopLeft(), ILD\_TRANSPARENT); \*pResult = CDRF\_SKIPDEFAULT; }
}
Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
I have been working from the same article just yesterday. Hers a copy of mu OnCustom draw...
void CCommunicationView::OnCustomDrawLog(NMHDR* pNMHDR, LRESULT* pResult)
{
NMLVCUSTOMDRAW *pLVCD = reinterpret_cast(pNMHDR);\*pResult = CDRF\_DODEFAULT; // assume normal windows drawn control if (CDDS\_PREPAINT == pLVCD->nmcd.dwDrawStage) { \*pResult = CDRF\_NOTIFYITEMDRAW; } else if (CDDS\_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) { // this is the prepaint stage, we need each sub-item pre-paint \*pResult = CDRF\_NOTIFYSUBITEMDRAW; } else if ((CDDS\_ITEMPREPAINT | CDDS\_SUBITEM) == pLVCD->nmcd.dwDrawStage) { // now render the image if it has one int item = pLVCD->nmcd.dwItemSpec; LVITEM rItem; ZeroMemory(&rItem, sizeof(LVITEM)); rItem.mask = LVIF\_IMAGE | LVIF\_STATE; rItem.iItem = item; rItem.stateMask = LVIS\_SELECTED; m\_Log.GetItem(&rItem ); // we render the text ourselves in the right colour and take tabs into account int value = m\_Log.GetItemData(item); CDC\* pDC = CDC::FromHandle ( pLVCD->nmcd.hdc ); CRect rcText; CRect rcIcon; CString text; m\_Log.GetItemRect(item, &rcIcon, LVIR\_ICON); m\_Log.GetItemRect(item, &rcText, LVIR\_BOUNDS); rcText.left += rcIcon.Width(); text = m\_Log.GetItemText(item, 0); if (rItem.state & LVIS\_SELECTED) { pDC->SetTextColor(GetSysColor(COLOR\_HIGHLIGHTTEXT)); CBrush brush(GetSysColor(COLOR\_HIGHLIGHT)); pDC->FillRect(rcText, &brush); } else { pDC->SetTextColor(value); CBrush brush(GetSysColor(COLOR\_HIGHLIGHTTEXT)); pDC->FillRect(rcText, &brush); } pDC->DrawText(text, rcText, DT\_END\_ELLIPSIS | DT\_EXPANDTABS | DT\_SINGLELINE | DT\_VCENTER); pLVCD->clrText = value; m\_ilLog.Draw(pDC, rItem.iImage, rcIcon.TopLeft(), ILD\_TRANSPARENT); \*pResult = CDRF\_SKIPDEFAULT; }
}
Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
Thanks for the quick reply. I got it working.. but I am still confused. I don't understand why I have to draw it out in the pre paint stage. Post paint I might be able to understand.. but I don't understand why I can loop through message for each Item, and change there colors using nmcd.clr...() but I can't check if the item is selected and use mncd to change color????? C# a poor attempt at bringing C++ to the VB masses