Ever wanted to display a report using the ListView control, but didn't want to do anything with the data? Obviously, the highlight effect is a bit annoying.
Of course, someone would say, "Why not use a custom routine, which includes, say, a picturebox?" Well, if the data didn't fit in the form/screen, a scrollbar would be required.

Now, to the point.

After searching around the web, I couldn't find a suitable code for this situation.
Then I realized that subclassing was necessary, so I searched the MSDN library and I found that the appropriate message was LVN_ITEMCHANGING, which is sent when the selection is about to change (obviously).

Enough talking. Let's see the code:

vb Code:
  1. 'I have excluded the subclassing code, since there are plenty of examples around the internet.
  2.  
  3. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
  4.  
  5. Private Const WM_NOTIFY As Long = &H4E
  6.  
  7. Private Const LVN_FIRST As Long = -100
  8. Private Const LVN_ITEMCHANGING As Long = LVN_FIRST
  9.  
  10. Private Const LVIS_SELECTED As Long = &H2
  11.  
  12.  
  13. Public Type POINTAPI
  14.     X As Long
  15.     Y As Long
  16. End Type
  17.  
  18. Public Type NMHDR
  19.     hWndFrom As Long
  20.     idfrom As Long
  21.     code As Long
  22. End Type
  23.  
  24. Private Type NMLISTVIEW
  25.     hdr As NMHDR
  26.     iItem As Long
  27.     iSubItem As Long
  28.     uNewState As Long
  29.     uOldState As Long
  30.     uChanged As Long
  31.     ptAction As POINTAPI
  32.     lParam As Long
  33. End Type
  34.  
  35.  
  36. Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  37. Dim nmlv As NMLISTVIEW
  38.  
  39. If uMsg = WM_NOTIFY Then
  40.     CopyMemory nmlv, ByVal lParam, Len(nmlv)  'lParam contains a pointer to NMLISTVIEW structure. Copy it to a local variable.
  41.    
  42.     If nmlv.hdr.code = LVN_ITEMCHANGING Then
  43.         If (nmlv.uNewState And LVIS_SELECTED) <> 0 Then  'uNewState is a bit mask
  44.             WindowProc = 1  'According to MSDN, if the application processes the message, the function should return TRUE.
  45.             Exit Function
  46.         End If
  47.     End If
  48. End If
  49.  
  50. WindowProc = CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam)
  51. End Function


Explanation
We subclass the parent form and capture the WM_NOTIFY message. Then, we wait for the notification code LVN_ITEMCHANGING, which is sent just before the highlight changes. The rest of the code is obvious.

The result will be a "selectionless" listview. However, mouse events, such as MouseDown, will still fire.
Of course, the SelectedItem property will always be Nothing.