#include #include #include "GuiListViewEx.au3" #include "ListViewCustomDraw.au3" Opt( "MustDeclareVars", 1 ) Global $hGui, $idListView, $hListView, $fListViewHasFocus = 0, $hLVfont, $iItems = 5, $aLines[$iItems][4] Example() Func Example() ; Create GUI $hGui = GUICreate( "Two-line listview items", 440, 320 ) ; Create ListView $idListView = GUICtrlCreateListView( "", 10, 10, 420, 300, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE+$LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES ) $hListView = GUICtrlGetHandle( $idListView ) ; Reduce flicker ; Increase item height $hLVfont = _GUICtrlListView_SetItemHeightByFont( $hListView, 26 ) ; Add columns to ListView _GUICtrlListView_AddColumn( $hListView, "Column 1", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 2", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 3", 94 ) _GUICtrlListView_AddColumn( $hListView, "Column 4", 94 ) ; Register WM_NOTIFY message handler ; To handle NM_CUSTOMDRAW notifications ; And to check when ListView receives/loses focus GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Register WM_ACTIVATE message handler ; If GUI loses focus selected listview items are drawn with a button face background color. ; To check when GUI receives/loses focus ; When GUI receives focus selected items are redrawn with the dark blue background color. GUIRegisterMsg( $WM_ACTIVATE, "WM_ACTIVATE" ) ; Detection of received focus is faster through the WM_ACTIVATE message than directly ; Show GUI GUISetState( @SW_SHOW ) ; Fill ListView Local $idItem For $i = 0 To $iItems - 1 $idItem = GUICtrlCreateListViewItem( $i & " Column 1|" & $i & " Column 2|" & $i & " Column 3|" & $i & " Column 4", $idListView ) ; $idItem (controlID) is stored in ItemParam in the internal storage allocated for the ListView Sleep(1000) If Not $i Then ReDim $aLines[$idItem+$iItems][4] ; Second line in ListView items is stored in $aLines array $aLines[$idItem][0] = $i & " Line 2/1" ; $idItem (controlID, stored in ItemParam) is row index in $aLines $aLines[$idItem][1] = $i & " Line 2/2" ; Four item texts are stored in four columns in $aLines array $aLines[$idItem][2] = $i & " Line 2/3" ; If line texts are stored as strings it's easy to test for empty texts $aLines[$idItem][3] = $i & " Line 2/4" Next ; Adjust height of GUI and ListView to fit ten rows Local $iLvHeight = _GUICtrlListView_GetHeightToFitRows( $hListView, 10 ) WinMove( $hGui, "", Default, Default, Default, WinGetPos( $hGui )[3] - WinGetClientSize( $hGui )[1] + $iLvHeight + 20 ) WinMove( $hListView, "", Default, Default, Default, $iLvHeight ) ; through the listview. This provides a faster and smoother redraw of selected items. ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIDelete() EndFunc ; WM_NOTIFY message handler Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) #forceref $hWnd, $iMsg, $wParam Local Static $iLvIndex, $iArrayIdx, $iSelected, $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $hDC Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCustomDraw = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCustomDraw, "dwDrawStage" ) Switch $dwDrawStage ; Specifies the drawing stage ; Stage 1 Case $CDDS_PREPAINT ; Before the paint cycle begins $hDC = DllStructGetData( $tNMLVCustomDraw, "hDC" ) ; Device context _WinAPI_SelectObject( $hDC, $hLVfont ) ; Set original font _WinAPI_SetBkMode( $hDC, $TRANSPARENT ) ; Transparent background Return $CDRF_NOTIFYITEMDRAW+$CDRF_NEWFONT ; Notify the parent window before an item is painted ; Stage 2 Case $CDDS_ITEMPREPAINT ; Before an item is painted $iLvIndex = DllStructGetData( $tNMLVCustomDraw, "dwItemSpec" ) ; Item index $iArrayIdx = DllStructGetData( $tNMLVCustomDraw, "lItemlParam" ) ; Array index $iSelected = GUICtrlSendMsg( $idListView, $LVM_GETITEMSTATE, $iLvIndex, $LVIS_SELECTED ) ; Item state Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window before a subitem is painted ; Stage 3 Case BitOR( $CDDS_ITEMPREPAINT, $CDDS_SUBITEM ) ; Before a subitem is painted: Default painting of checkbox, image, icon Return $CDRF_NOTIFYPOSTPAINT ; Notify the parent window after a subitem is painted ; Stage 4 Case BitOR( $CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM ) ; After a subitem has been painted: Custom painting of text lines Local $iSubItem = DllStructGetData( $tNMLVCustomDraw, "iSubItem" ) ; Subitem index ; Subitem rectangle DllStructSetData( $tRect, "Top", $iSubItem ) DllStructSetData( $tRect, "Left", $iSubItem ? $LVIR_BOUNDS : $LVIR_LABEL ) GUICtrlSendMsg( $idListView, $LVM_GETSUBITEMRECT, $iLvIndex, $pRect ) ; Subitem text color DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", ( $iSelected And $fListViewHasFocus ) ? 0xFFFFFF : 0x000000 ) ; _WinAPI_SetTextColor ; Custom painting of first text line in subitem RepaintFirstTextLine( $idListView, $iLvIndex, $iSubItem, $iSelected, $fListViewHasFocus, $hDC, $tRect ) ; Custom painting of second text line in subitem If Not $aLines[$iArrayIdx][$iSubItem] Then Return $CDRF_NEWFONT DllStructSetData( $tRect, "Top", DllStructGetData( $tRect, "Top" ) + 12 ) ; Top margin DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $aLines[$iArrayIdx][$iSubItem], "int", -1, "struct*", $tRect, "uint", $DT_WORD_ELLIPSIS ) ; _WinAPI_DrawText Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $NM_KILLFOCUS If $fListViewHasFocus Then GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 0 EndIf Case $NM_SETFOCUS If Not $fListViewHasFocus Then _ GUICtrlSendMsg( $idListView, $LVM_REDRAWITEMS, 0, $iItems - 1 ) $fListViewHasFocus = 2 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ; WM_ACTIVATE message handler Func WM_ACTIVATE( $hWnd, $iMsg, $wParam, $lParam ) #forceref $iMsg, $lParam If $hWnd = $hGui Then _ $fListViewHasFocus = BitAND( $wParam, 0xFFFF ) ? 1 : 0 Return $GUI_RUNDEFMSG EndFunc