#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIListBox.au3>
#include <WinAPI.au3>
Global Const $ODT_LISTBOX = 2
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODA_SELECT = 0x2
Global Const $ODA_FOCUS = 0x4
Global Const $ODS_SELECTED = 0x1
Global Const $ODS_NOACCEL = 0x100
Global Const $ODS_NOFOCUSRECT = 0x200
Global $iLB_LastSelIndx = -1
Global $sSep_RegExp = '^(—+) .*? \1$'
$hGUI = GUICreate("ListBox Separator Demo", 300, 200)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_MEASUREITEM, "WM_MEASUREITEM")
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
$iListBox = GUICtrlCreateList("", 10, 10, 280, 180, BitOR($LBS_HASSTRINGS, $LBS_OWNERDRAWFIXED, $WS_VSCROLL))
$hListBox = GUICtrlGetHandle($iListBox)
For $i = 1 To 10
If Mod($i, 3) = 0 Then
_GUICtrlListBox_AddString($iListBox, "———————————————— Separator" & -Mod($i, 4) + 4 & " ————————————————")
EndIf
_GUICtrlListBox_AddString($iListBox, "String " & $i)
Next
GUISetState()
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndList
$hWndListBox = $hListBox
If Not IsHWnd($hListBox) Then $hWndListBox = GUICtrlGetHandle($hListBox)
$hWndFrom = $ilParam
$iIDFrom = BitAND($iwParam, 0xFFFF); Low Word
$iCode = BitShift($iwParam, 16); Hi Word
Switch $hWndFrom
Case $hWndListBox
Switch $iCode
Case $LBN_SELCHANGE ;, $LBN_DBLCLK
Local $iIndex = _GUICtrlListBox_GetCurSel($hListBox)
Local $sText = _GUICtrlListBox_GetText($hListBox, $iIndex)
If StringRegExp($sText, $sSep_RegExp) Then
_GUICtrlListBox_SetCurSel($hListBox, $iLB_LastSelIndx)
Else
$iLB_LastSelIndx = $iIndex
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
Func WM_MEASUREITEM($hWnd, $Msg, $wParam, $lParam)
Local $CtlType, $tagMEASUREITEMSTRUCT = "UINT CtlType;UINT CtlID;UINT itemID;UINT itemWidth;UINT itemHeight;ULONG_PTR itemData;"
Local $MEASUREITEMSTRUCT = DllStructCreate($tagMEASUREITEMSTRUCT, $lParam)
$CtlType = DllStructGetData($MEASUREITEMSTRUCT, "CtlType")
If $CtlType <> $ODT_LISTBOX Then Return $GUI_RUNDEFMSG
;Set height of the item's (text and background)
DllStructSetData($MEASUREITEMSTRUCT, 5, 15)
DllStructSetData($MEASUREITEMSTRUCT, 4, DllStructGetData($MEASUREITEMSTRUCT, 4) + 15)
Return
EndFunc
Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
Local $tagDRAWITEMSTRUCT, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $hBrush, $hBrushOld
$tagDRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _
"hwnd hItm;hwnd hDC;int itmRect[4];dword itmData", $lParam)
If DllStructGetData($tagDRAWITEMSTRUCT, "cType") <> $ODT_LISTBOX Then Return $GUI_RUNDEFMSG
$cID = DllStructGetData($tagDRAWITEMSTRUCT, "cID")
$itmID = DllStructGetData($tagDRAWITEMSTRUCT, "itmID")
$itmAction = DllStructGetData($tagDRAWITEMSTRUCT, "itmAction")
$itmState = DllStructGetData($tagDRAWITEMSTRUCT, "itmState")
$hItm = DllStructGetData($tagDRAWITEMSTRUCT, "hItm")
$hDC = DllStructGetData($tagDRAWITEMSTRUCT, "hDC")
Switch $itmAction
Case $ODA_DRAWENTIRE, $ODA_SELECT
;get the text to be drawn
Local $iStringLen = _GUICtrlListBox_GetTextLen($hItm, $itmID)
Local $itmText = _GUICtrlListBox_GetText($hItm, $itmID)
Local $iBrushColor = 0XFFFFFF, $iTxtColor = 0x000000
If $itmState = $ODS_SELECTED Or $itmState = BitOR($ODS_SELECTED, $ODS_NOACCEL, $ODS_NOFOCUSRECT) Then
$iBrushColor = _WinAPI_GetSysColor($COLOR_HIGHLIGHT)
$iTxtColor = 0xFFFFFF
EndIf
If StringRegExp($itmText, $sSep_RegExp) Then
$iBrushColor = 0XFFFFFF
$iTxtColor = 0XCCCCCC
EndIf
$hBrush = _WinAPI_CreateSolidBrush($iBrushColor)
$hBrushOld = _WinAPI_SelectObject($hDC, $hBrush)
_WinAPI_SetTextColor($hDC, $iTxtColor)
_WinAPI_FillRect($hDC, DllStructGetPtr($tagDRAWITEMSTRUCT, "itmRect"), $hBrush)
_WinAPI_SelectObject($hDC, $hBrushOld)
_WinAPI_DeleteObject($hBrush)
_WinAPI_SetBkMode($hDC, 1)
Local $tRECT = DllStructCreate("int Left;int Top;int Right;int Bottom")
DllStructSetData($tRECT, "Left", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 1) + 5)
DllStructSetData($tRECT, "Top", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 2))
DllStructSetData($tRECT, "Right", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 3))
DllStructSetData($tRECT, "Bottom", DllStructGetData($tagDRAWITEMSTRUCT, "itmRect", 4))
_WinAPI_DrawText($hDC, $itmText, $tRECT, $DT_LEFT)
Return 1
Case $ODA_FOCUS
Return 1
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc