NM_CUSTOMDRAW and Listviews in Plain C

I recently spent 4 days trying to set the colour of the headers of a Listview in my Windows program SQLite-OLE. It was a painful experience partially because I program in plain C using the bare Win API and not using MFC (Microsoft Foundation Classes).

Hmm, well it was all my own fault. If you do not read the documentation carefully, what can one expect.

The solution was ultimately simple.

Here are a few tips if you want to set the background colour of a listview’s  cells or its column headers.

  1. When a Listview is displayed on the screen a number of  WM_NOTIFY messages are sent. We need to intercept a  subset of these WM_NOTIFY,  specifically those indicating a NM_CUSTOMDRAW operation.
  2. WM_NOTIFY / NM_CUSTOMDRAW messages concerning the data cells of the Listview are sent to the WndProc of the Listview’s PARENT, in my case the Window containing the Listview. These messages are also sent for some other controls, so be sure to check that the   (LPNMHDR)lParam)->hwndFrom  identifies the wanted Listview’s HWND.
  3. If you intercept these (cell) messages you can set the colour of the cell, the colour of the cells’ text, and the background color of the text, simply by providing a new RGB value to the data structure pointed at by the message’s lParam.
  4. WM_NOTIFY / NM_CUSTOMDRAW messages concerning the header of the Listview are sent to the WndProc of the Listview: In my case I had to subclass the Listview in order to create a WndProc for the Listview that I could intercept.
  5. If you intercept these (header) messages you can set the colour of the header cell, the colour of the text, and the background color of the text. BUT  you must use functions such as: FillRect, SetTextColor and SetBkColor.

Once I got this sorted out, the code was easy, and I can now modify the display of a Listview as shown below.

Before:

After: