question

Default-1573 avatar image
0 Votes"
Default-1573 asked XiaopoYang-MSFT commented

ListView Custom Draw (LVS_EX_FULLROWSELECT)

I have a list view the has the LVS_EX_FULLROWSELECT style. When I do a NM_CUSTDOMDRAW on the list view and custom draw a subitem icon I can no longer see the full highlight of the row when I click on it. The subitem were I did the custom draw has a white background. Do I need to handle CDIS_SELECTED in the NM_CUSTOMDRAW or change the background of the subitem?

123662-no-highlight.png



 case NM_CUSTOMDRAW:
                 {
                     NMLVCUSTOMDRAW *nm = (NMLVCUSTOMDRAW *)lp;
    
                     switch(nm->nmcd.dwDrawStage)
                     {
                         case CDDS_PREPAINT:
                         case CDDS_ITEMPREPAINT:
                         {
                             return CDRF_NOTIFYSUBITEMDRAW;
                         }
    
                         case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
                         {
                             RECT rc;
                             HICON hIcon;
    
                             ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
                             if (nm->iSubItem == 2 && nm->nmcd.lItemlParam != -1)
                             {
                                 hIcon = ImageList_GetIcon(ghImageList, 0, ILD_NORMAL);
                                 DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
                                 DestroyIcon(hIcon);
                                 return CDRF_SKIPDEFAULT;
                             }
                             else break;
                         }
                     }
                 }
                 break;


windows-apic++windows-forms
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Castorix31 avatar image
0 Votes"
Castorix31 answered XiaopoYang-MSFT commented

Yes, you must test if the row is selected

Like :

 bool IsRowSelected(HWND hWnd, int nRow)
 {
  return ListView_GetItemState(hWnd, nRow, LVIS_SELECTED | LVIS_FOCUSED) != 0;
 }

then :

 if (IsRowSelected(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec))
 {
     // Draw icon with selected color background
  //  ... your code  ...
  return CDRF_SKIPDEFAULT;
 }
 else
 {
     hIcon = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
  DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
  DestroyIcon(hIcon);
  return CDRF_SKIPDEFAULT;
 }


or

 if (IsRowSelected(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec))
     FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
 {
     hIcon = ImageList_GetIcon(hImageList, 0, ILD_NORMAL);
     DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
     DestroyIcon(hIcon);                        
 }
 return CDRF_SKIPDEFAULT;






· 11
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I did get it to highlight but when I deselect it it remains blue. I tried some stuff but I couldn't get it to go back to white.

123666-still-highlighted.png



 case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
                         {
                             RECT rc;
                             HICON hIcon;
    
                             ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
                             if (nm->iSubItem == 2 && nm->nmcd.lItemlParam != -1)
                             {
                                 if (IsRowSelected(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec))
                                 {
                                     FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
                                     hIcon = ImageList_GetIcon(ghImageList, 0, ILD_NORMAL);
                                     DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
                                     DestroyIcon(hIcon);
                                     return CDRF_SKIPDEFAULT;
                                 }
                                 else
                                 {
                                     hIcon = ImageList_GetIcon(ghImageList, 0, ILD_NORMAL);
                                     DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
                                     DestroyIcon(hIcon);
                                     return CDRF_SKIPDEFAULT;
                                 }
                             }
                             else break
0 Votes 0 ·

You can add a test on the focus :

 bool IsRowHighlighted(HWND hWnd, int nRow)
 {
     return IsRowSelected(hWnd, nRow) && (GetFocus() == hWnd);
 }

then replace IsRowSelected by IsRowHighlighted

(must not have LVS_SHOWSELALWAYS style or the gray rectangle must be drawn too...)

0 Votes 0 ·

Still dosen't seem to work. I think it has to be repainted white when it loses focuses.

 case NM_CUSTOMDRAW:
                 {
                     NMLVCUSTOMDRAW *nm = (NMLVCUSTOMDRAW *)lp;
    
                     switch(nm->nmcd.dwDrawStage)
                     {
                         case CDDS_PREPAINT:
                         case CDDS_ITEMPREPAINT:
                         {
                             return CDRF_NOTIFYSUBITEMDRAW;
                         }
    
                         case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
                         {
                             RECT rc;
                             HICON hIcon;
    
                             ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
                             if (nm->iSubItem == 2 && nm->nmcd.lItemlParam != -1)
                             {
                                 if (IsRowHighlighted(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec))
                                 {
                                     FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
                                     hIcon = ImageList_GetIcon(ghImageList, 0, ILD_NORMAL);
                                     DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
                                     DestroyIcon(hIcon);
                                     return CDRF_SKIPDEFAULT;
                                 }
                                 else
                                 {
                                     hIcon = ImageList_GetIcon(ghImageList, 0, ILD_NORMAL);
                                     DrawIconEx(nm->nmcd.hdc, rc.left + 5, (rc.top + rc.bottom - GetSystemMetrics(SM_CYSMICON)) / 2, hIcon, 16, 16, 0, NULL, DI_NORMAL);
                                     DestroyIcon(hIcon);
                                     return CDRF_SKIPDEFAULT;
                                 }
                             }
                             else break;
                         }
                     }
                 }
                 break;
0 Votes 0 ·
Show more comments