子类模块中 Public Const WM_NOTIFY& = &H4E Public Const WM_DRAWITEM = &H2B Public Const CDDS_PREPAINT& = &H1 Public Const CDDS_POSTPAINT& = &H2 Public Const CDDS_PREERASE& = &H3 Public Const CDDS_POSTERASE& = &H4 Public Const CDDS_ITEM& = &H10000 Public Const CDDS_ITEMPREPAINT& = CDDS_ITEM Or CDDS_PREPAINT Public Const CDDS_ITEMPOSTPAINT& = CDDS_ITEM Or CDDS_POSTPAINT Public Const CDDS_ITEMPREERASE& = CDDS_ITEM Or CDDS_PREERASE Public Const CDDS_ITEMPOSTERASE& = CDDS_ITEM Or CDDS_POSTERASE Public Const CDDS_SUBITEM& = &H20000 Public Const CDRF_DODEFAULT& = &H0 Public Const CDRF_NEWFONT& = &H2 Public Const CDRF_SKIPDEFAULT& = &H4 Public Const CDRF_NOTIFYPOSTPAINT& = &H10 Public Const CDRF_NOTIFYITEMDRAW& = &H20 Public Const CDRF_NOTIFYSUBITEMDRAW = &H20 ' flags are the same, we candistinguish by context Public Const CDRF_NOTIFYPOSTERASE& = &H40 Public Const CDRF_NOTIFYITEMERASE& = &H80 Public Const LVM_FIRST As Long = &H1000 Public Const LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 ' << Note the diff Public Const LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 ' << One is Set,Ohter is Get Public Const GW_OWNER = 4 Public Const FULLROWSELECT = &H20 Public Const LVS_EX_HEADERDRAGDROP = &H10 Public Const WM_GETFONT = &H31 Public Const GWL_WNDPROC = (-4)Public Enum WinNotifications NM_FIRST = -0& NM_LAST = -99& NM_OUTOFMEMORY = (NM_FIRST - 1) NM_CLICK = (NM_FIRST - 2) NM_DBLCLK = (NM_FIRST - 3) NM_RETURN = (NM_FIRST - 4) NM_RCLICK = (NM_FIRST - 5) NM_RDBLCLK = (NM_FIRST - 6) NM_SETFOCUS = (NM_FIRST - 7) NM_KILLFOCUS = (NM_FIRST - 8) NM_CUSTOMDRAW = (NM_FIRST - 12) NM_HOVER = (NM_FIRST - 13) End EnumPublic Type RECT Left As Long Top As Long Right As Long Bottom As Long End TypePublic Type NMHDR hwndFrom As Long idFrom As Long code As Long End TypePublic Type NMCUSTOMDRAWINFO hdr As NMHDR dwDrawStage As Long hDC As Long rc As RECT dwItemSpec As Long iItemState As Long lItemLParam As Long End TypePublic Type NMLVCUSTOMDRAW nmcmd As NMCUSTOMDRAWINFO clrText As Long clrTextBk As Long 'iSubItem As Integer End Type Public Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb As Long) As Long Public Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long Public Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private origLVwinProc As Long Private m_hooked_lv As Long Public Sub HookToLV(hwnd, B As Boolean) If B Then origLVwinProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf LVSubcls_WProc4Hdr) m_hooked_lv = hwnd glHdrBkClr = vbYellow glHdrTextClr = vbRed Else Call SetWindowLong(m_hooked_lv, GWL_WNDPROC, origLVwinProc) End If End Sub Public Function LVSubcls_WProc4Hdr(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long On Error Resume Next Dim tMessage As NMHDR Dim lCode As Long Dim tLVRedrawMessage As NMLVCUSTOMDRAW Select Case msg Case WM_NOTIFY CopyMemory tMessage, ByVal lParam, Len(tMessage) lCode = tMessage.code Select Case lCode Case NM_CUSTOMDRAW CopyMemory tLVRedrawMessage, ByVal lParam, Len(tLVRedrawMessage) If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then LVSubcls_WProc4Hdr = CDRF_NOTIFYITEMDRAW Exit Function End If If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then If tLVRedrawMessage.nmcmd.lItemLParam < 3 Then '以前我做的时候因为前面几列是输入数据,而后面几列是输出数据,所以以不同颜色显示 SetTextColor tLVRedrawMessage.nmcmd.hDC, vbBlue '可以在这里修改相关颜色参数 SetBkColor tLVRedrawMessage.nmcmd.hDC, &HC0FFC0 Else SetTextColor tLVRedrawMessage.nmcmd.hDC, RGB(255, 0, 0) SetBkColor tLVRedrawMessage.nmcmd.hDC, RGB(2, 255, 255) End If LVSubcls_WProc4Hdr = CDRF_DODEFAULT Exit Function End If If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_ITEMPOSTPAINT Then LVSubcls_WProc4Hdr = CDRF_DODEFAULT Exit Function End If End Select LVSubcls_WProc4Hdr = CallWindowProc(origLVwinProc, hwnd, msg, wParam, lParam) Case Else LVSubcls_WProc4Hdr = CallWindowProc(origLVwinProc, hwnd, msg, wParam, lParam) End Select End Function
窗体中,为安全起见,测试前请您保存你的代码。Private Sub Form_Load() ListView1.View = lvwReport Dim nLen As Long nLen = ListView1.Width / (7) Dim i As Integer Call ListView1.ColumnHeaders.Clear Call ListView1.ColumnHeaders.Add(, , "数据", nLen, lvwColumnLeft) For i = 1 To 6 Call ListView1.ColumnHeaders.Add(, , "第" & i & "列", nLen, lvwColumnCenter) Next
For i = 1 To 8 Set Item = ListView1.ListItems.Add(, , "第" & i & "行") For j = l To 6 Call Item.ListSubItems.Add(, , CInt(Rnd * 1000)) '添加数据 Next Next
HookToLV ListView1.hwnd, TrueEnd SubPrivate Sub Form_Unload(Cancel As Integer) HookToLV ListView1.hwnd, FalseEnd Sub
Public Const WM_NOTIFY& = &H4E
Public Const WM_DRAWITEM = &H2B
Public Const CDDS_PREPAINT& = &H1
Public Const CDDS_POSTPAINT& = &H2
Public Const CDDS_PREERASE& = &H3
Public Const CDDS_POSTERASE& = &H4
Public Const CDDS_ITEM& = &H10000
Public Const CDDS_ITEMPREPAINT& = CDDS_ITEM Or CDDS_PREPAINT
Public Const CDDS_ITEMPOSTPAINT& = CDDS_ITEM Or CDDS_POSTPAINT
Public Const CDDS_ITEMPREERASE& = CDDS_ITEM Or CDDS_PREERASE
Public Const CDDS_ITEMPOSTERASE& = CDDS_ITEM Or CDDS_POSTERASE
Public Const CDDS_SUBITEM& = &H20000
Public Const CDRF_DODEFAULT& = &H0
Public Const CDRF_NEWFONT& = &H2
Public Const CDRF_SKIPDEFAULT& = &H4
Public Const CDRF_NOTIFYPOSTPAINT& = &H10
Public Const CDRF_NOTIFYITEMDRAW& = &H20
Public Const CDRF_NOTIFYSUBITEMDRAW = &H20 ' flags are the same, we candistinguish by context
Public Const CDRF_NOTIFYPOSTERASE& = &H40
Public Const CDRF_NOTIFYITEMERASE& = &H80
Public Const LVM_FIRST As Long = &H1000
Public Const LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 ' << Note the diff
Public Const LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 ' << One is Set,Ohter is Get
Public Const GW_OWNER = 4
Public Const FULLROWSELECT = &H20
Public Const LVS_EX_HEADERDRAGDROP = &H10
Public Const WM_GETFONT = &H31
Public Const GWL_WNDPROC = (-4)Public Enum WinNotifications
NM_FIRST = -0&
NM_LAST = -99&
NM_OUTOFMEMORY = (NM_FIRST - 1)
NM_CLICK = (NM_FIRST - 2)
NM_DBLCLK = (NM_FIRST - 3)
NM_RETURN = (NM_FIRST - 4)
NM_RCLICK = (NM_FIRST - 5)
NM_RDBLCLK = (NM_FIRST - 6)
NM_SETFOCUS = (NM_FIRST - 7)
NM_KILLFOCUS = (NM_FIRST - 8)
NM_CUSTOMDRAW = (NM_FIRST - 12)
NM_HOVER = (NM_FIRST - 13)
End EnumPublic Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End TypePublic Type NMHDR
hwndFrom As Long
idFrom As Long
code As Long
End TypePublic Type NMCUSTOMDRAWINFO
hdr As NMHDR
dwDrawStage As Long
hDC As Long
rc As RECT
dwItemSpec As Long
iItemState As Long
lItemLParam As Long
End TypePublic Type NMLVCUSTOMDRAW
nmcmd As NMCUSTOMDRAWINFO
clrText As Long
clrTextBk As Long
'iSubItem As Integer
End Type
Public Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb As Long) As Long
Public Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
Public Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private origLVwinProc As Long
Private m_hooked_lv As Long
Public Sub HookToLV(hwnd, B As Boolean)
If B Then
origLVwinProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf LVSubcls_WProc4Hdr)
m_hooked_lv = hwnd
glHdrBkClr = vbYellow
glHdrTextClr = vbRed
Else
Call SetWindowLong(m_hooked_lv, GWL_WNDPROC, origLVwinProc)
End If
End Sub
Public Function LVSubcls_WProc4Hdr(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
On Error Resume Next
Dim tMessage As NMHDR
Dim lCode As Long
Dim tLVRedrawMessage As NMLVCUSTOMDRAW
Select Case msg
Case WM_NOTIFY
CopyMemory tMessage, ByVal lParam, Len(tMessage)
lCode = tMessage.code
Select Case lCode
Case NM_CUSTOMDRAW
CopyMemory tLVRedrawMessage, ByVal lParam, Len(tLVRedrawMessage)
If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then
LVSubcls_WProc4Hdr = CDRF_NOTIFYITEMDRAW
Exit Function
End If
If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then
If tLVRedrawMessage.nmcmd.lItemLParam < 3 Then '以前我做的时候因为前面几列是输入数据,而后面几列是输出数据,所以以不同颜色显示
SetTextColor tLVRedrawMessage.nmcmd.hDC, vbBlue '可以在这里修改相关颜色参数
SetBkColor tLVRedrawMessage.nmcmd.hDC, &HC0FFC0
Else
SetTextColor tLVRedrawMessage.nmcmd.hDC, RGB(255, 0, 0)
SetBkColor tLVRedrawMessage.nmcmd.hDC, RGB(2, 255, 255)
End If LVSubcls_WProc4Hdr = CDRF_DODEFAULT
Exit Function
End If If tLVRedrawMessage.nmcmd.dwDrawStage = CDDS_ITEMPOSTPAINT Then
LVSubcls_WProc4Hdr = CDRF_DODEFAULT
Exit Function
End If
End Select
LVSubcls_WProc4Hdr = CallWindowProc(origLVwinProc, hwnd, msg, wParam, lParam)
Case Else
LVSubcls_WProc4Hdr = CallWindowProc(origLVwinProc, hwnd, msg, wParam, lParam)
End Select
End Function
ListView1.View = lvwReport
Dim nLen As Long
nLen = ListView1.Width / (7)
Dim i As Integer
Call ListView1.ColumnHeaders.Clear
Call ListView1.ColumnHeaders.Add(, , "数据", nLen, lvwColumnLeft)
For i = 1 To 6
Call ListView1.ColumnHeaders.Add(, , "第" & i & "列", nLen, lvwColumnCenter)
Next
For i = 1 To 8
Set Item = ListView1.ListItems.Add(, , "第" & i & "行")
For j = l To 6
Call Item.ListSubItems.Add(, , CInt(Rnd * 1000)) '添加数据
Next
Next
HookToLV ListView1.hwnd, TrueEnd SubPrivate Sub Form_Unload(Cancel As Integer)
HookToLV ListView1.hwnd, FalseEnd Sub