ListView Custom Draw (LVS_EX_FULLROWSELECT)

Anonymous
2021-08-16T15:06:30.877+00:00

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 Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,839 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,430 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,545 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Castorix31 81,831 Reputation points
    2021-08-16T15:23:45.57+00:00

    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;