#Region - TimeStamp
; 2011-10-24 12:16:34   v 1.2
#EndRegion - TimeStamp
#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global Const $ODT_LISTVIEW = 102
Global Const $ODA_DRAWENTIRE = 0x1
Global Const $ODS_SELECTED = 0x0001

;===============================================================================
; Function Name....: _GuiCtrlListview_OwnSelectionAdd
; Description......: Registriert ein Listview für eigene Selektion
; Parameter(s).....: $hWnd    Handle (oder ID) des Listview
; Requirement(s)...: Das Listview MUSS ZWINGEND mit "GuiCtrlCreateListView" erstellt werden!
; Return Value(s)..: Fehler   @error - Handle/ID nicht vorhanden
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GuiCtrlListview_OwnSelectionAdd($hWnd)
	Local $ret = __ManageSelection('add', $hWnd)
	If @error Then Return SetError(1)
EndFunc  ;==>_GuiCtrlListview_OwnSelectionAdd

;===============================================================================
; Function Name....: _GuiCtrlListview_OwnSelectionDel
; Description......: Listview nicht mehr in eigener Selektion zeichnen
;                    Selektion wird wieder vom System gezeichnet, graut aus bei Fokusverlust
; Parameter(s).....: $hWnd    Handle (oder ID) des Listview
; Return Value(s)..: Fehler   @error - 1 Handle/ID nicht vorhanden
;                                      2 Handle/ID nicht registriert
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GuiCtrlListview_OwnSelectionDel($hWnd)
	Local $ret = __ManageSelection('del', $hWnd)
	If @error Then Return SetError(@error)
EndFunc  ;==>_GuiCtrlListview_OwnSelectionDel

;===============================================================================
; Function Name....: _GuiCtrlListview_OwnSelectionSetColor
; Description......: Text- und Hintergrundfarbe für die Selektion setzen
; Parameter(s).....: $hWnd        Handle (oder ID) des Listview (-1 setzt die Farben für alle registrierten Listview)
;                    $iForeColor  Textfarbe der Selektion (-1 setzt Default-Color)
;                    $iBackColor  Hintergrundfarbe der Selektion (-1 setzt Default-Color)
; Return Value(s)..: Fehler   @error - 1 Handle/ID nicht vorhanden
;                                      2 Handle/ID nicht registriert
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GuiCtrlListview_OwnSelectionSetColor($hWnd=-1, $iForeColor=-1, $iBackColor=-1)
	Local $aParam[3] = [$hWnd, $iForeColor, $iBackColor]
	Local $ret = __ManageSelection('setcol', $aParam)
	If @error Then Return SetError(@error)
EndFunc  ;==>_GuiCtrlListview_OwnSelectionSetColor

;===============================================================================
; Function Name....: _GuiCtrlListview_OwnSelectionSetDefCol
; Description......: Setzen der Standardfarben (nicht selektierter Bereich) für alle Listview
; Parameter(s).....: $iForeColor  Textfarbe nicht selektierter Bereich (Standard: schwarz)
;                    $iBackColor  Hintergrundfarbe nicht selektierter Bereich (Standard: weiß)
; Return Value(s)..: keiner
; Author(s)........: BugFix ( bugfix@autoit.de )
;===============================================================================
Func _GuiCtrlListview_OwnSelectionSetDefCol($iForeColor=0xFFFFFF, $iBackColor=0x000000)
	Local $aParam[2] = [$iForeColor, $iBackColor]
	__ManageSelection('defcol', $aParam)
EndFunc  ;==>_GuiCtrlListview_OwnSelectionSetDefCol

;===============================================================================
; Function Name....: Hilfsfunktion - __ManageSelection
; Description......: Verwaltung der Einstellungen
;===============================================================================
Func __ManageSelection($sAction, $vParam='')
	Local Static $aHwnd[40][4], $iCurr = -1  ; [[hWnd, TxtCol, BackCol, OldStyle]]
	Local Static $aDefCol[2] = [0x000000,0xFFFFFF]
	Local $hLV, $index, $iFrom = 0, $iTo = $iCurr, $iStyle
	Switch $sAction
		Case 'add'
			$hLV = $vParam
			If Not IsHWnd($hLV) Then $hLV = GUICtrlGetHandle($hLV)
			If Not IsHWnd($hLV) Then Return SetError(1)
			If $iCurr = -1 Then GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
			$iCurr += 1
			If $iCurr > 39 Then ReDim $aHwnd[$iCurr+1][4]
			$aHwnd[$iCurr][0] = $hLV
			$iStyle = GUICtrlGetStyle($hLV)
			$iStyle = Hex($iStyle[0],4)
			$aHwnd[$iCurr][3] = $iStyle
			GUICtrlSetStyle(_WinAPI_GetDlgCtrlID($hLV), BitOR($iStyle,$LVS_REPORT,$LVS_OWNERDRAWFIXED))
		Case 'del'
			$hLV = $vParam
			If Not IsHWnd($hLV) Then $hLV = GUICtrlGetHandle($hLV)
			If Not IsHWnd($hLV) Then Return SetError(1)
			$index = _ArraySearch($aHwnd, $hLV)
			If @error Then Return SetError(2)
			; == Standardfarbe Systemmarkierung und Standardverhalten (Ausgrauen bei Fokusverlust)
			GUICtrlSetStyle(_WinAPI_GetDlgCtrlID($hLV), '0x' & $aHwnd[$index][3])
			$aHwnd[$index][0] = 0
		Case 'setcol'
			$hLV = $vParam[0]
			If $hLV <> -1 Then  ; == -1 alle Werte setzen
				If Not IsHWnd($hLV) Then $hLV = GUICtrlGetHandle($hLV)
				If Not IsHWnd($hLV) Then Return SetError(1)
				$index = _ArraySearch($aHwnd, $hLV)
				If @error Then Return SetError(2)
				$iFrom = $index
				$iTo = $index
			EndIf
			If $iCurr < 0 Then Return SetError(2) ; == noch kein Fenster registriert
			If $vParam[1] = -1 Then $vParam[1] = $aDefCol[0]
			If $vParam[2] = -1 Then $vParam[2] = $aDefCol[1]
			For $i = $iFrom To $iTo
				$aHwnd[$i][1] = RGB2BGR($vParam[1])
				$aHwnd[$i][2] = RGB2BGR($vParam[2])
			Next
		Case 'getcol'
			$index = _ArraySearch($aHwnd, $vParam)
			If @error Then Return SetError(1)
			Local $aRet[2] = [$aHwnd[$index][1],$aHwnd[$index][2]]
			Return $aRet
		Case 'defcol'
			$aDefCol[0] = RGB2BGR($vParam[0])
			$aDefCol[1] = RGB2BGR($vParam[1])
		Case 'getdef'
			Return $aDefCol
	EndSwitch
EndFunc

Func RGB2BGR($iColor)
	Local $sH = Hex($iColor,6)
    Return '0x' & StringRight($sH, 2) & StringMid($sH,3,2) & StringLeft($sH, 2)
EndFunc

Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $tDRAWITEMSTRUCT, $iBrushColor, $cID, $itmID, $itmAction, $itmState, $hItm, $hDC, $bSelected, $aCol, $aDefCol
    $tDRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _
                                         "hwnd hItm;hwnd hDC;int itmRect[4];dword itmData", $lParam)
    If DllStructGetData($tDRAWITEMSTRUCT, "cType") <> $ODT_LISTVIEW Then Return $GUI_RUNDEFMSG
    $cID = DllStructGetData($tDRAWITEMSTRUCT, "cID")
    $itmID = DllStructGetData($tDRAWITEMSTRUCT, "itmID")
    $itmAction = DllStructGetData($tDRAWITEMSTRUCT, "itmAction")
    $itmState = DllStructGetData($tDRAWITEMSTRUCT, "itmState")
    $hItm = DllStructGetData($tDRAWITEMSTRUCT, "hItm")
    $hDC = DllStructGetData($tDRAWITEMSTRUCT, "hDC")
	$aCol = __ManageSelection('getcol', $hItm)
	$aDefCol = __ManageSelection('getdef')
	If @error Then Return $GUI_RUNDEFMSG
    $bSelected = BitAND($itmState, $ODS_SELECTED)

    Switch $itmAction
        Case $ODA_DRAWENTIRE
            If $itmState = $bSelected Then
                $iBrushColor = $aDefCol[1]
				_WinAPI_SetTextColor($hDC, $aDefCol[0])
            Else
                $iBrushColor = $aCol[1]
				_WinAPI_SetTextColor($hDC, $aCol[0])
            EndIf
            Local $aBrush = DLLCall("gdi32.dll","hwnd","CreateSolidBrush", "int", $iBrushColor)
            Local $aBrushOld = _WinAPI_SelectObject($hDC, $aBrush[0])
            _WinAPI_FillRect($hDC, DllStructGetPtr($tDRAWITEMSTRUCT, "itmRect"), $aBrush[0])
            _WinAPI_SelectObject($hDC, $aBrushOld)
            _WinAPI_DeleteObject($aBrush[0])
			; == Item
            Local $itmText = _GUICtrlListView_GetItemText($hItm, $itmID)
            DllStructSetData($tDRAWITEMSTRUCT, "itmRect", DllStructGetData($tDRAWITEMSTRUCT, "itmRect", 1) +5, 1) ; == Schrift 5px nach rechts
            DllStructSetData($tDRAWITEMSTRUCT, "itmRect", DllStructGetData($tDRAWITEMSTRUCT, "itmRect", 2) +2, 2) ; == Schrift 2px nach unten
            DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $itmText, "int", StringLen($itmText), _
                    "ptr", DllStructGetPtr($tDRAWITEMSTRUCT, "itmRect"), "int", $DT_LEFT)
			; == SubItem
			Local $iCol = _GUICtrlListView_GetColumnCount($hItm)
			If $iCol > 1 Then
				For $i = 1 To $iCol -1
					Local $iSubItmText = _GUICtrlListView_GetItemText($hItm, $itmID, $i)
					Local $aSubItmRect = _GUICtrlListView_GetSubItemRect($hItm, $itmID, $i)
					Local $iSubItmRect = DllStructCreate("int[4]")
					DllStructSetData($iSubItmRect, 1, $aSubItmRect[0] +5, 1)
					DllStructSetData($iSubItmRect, 1, $aSubItmRect[1] +2, 2)
					DllStructSetData($iSubItmRect, 1, $aSubItmRect[2], 3)
					DllStructSetData($iSubItmRect, 1, $aSubItmRect[3], 4)
					DllCall("user32.dll", "int", "DrawText", "hwnd", $hDC, "str", $iSubItmText, "int", StringLen($iSubItmText), _
							"ptr", DllStructGetPtr($iSubItmRect), "int", $DT_LEFT)
				Next
			EndIf
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

; #FUNCTION# =========================================================================================================
; Name...........: GUICtrlGetStyle
; Description ...: Retrieves the Styles/ExStyles value(s) of the control.
; Syntax.........: GUICtrlGetBkColor($iControlID)
; Parameters ....: $iControlID - A valid control ID.
; Requirement(s).: v3.3.2.0 or higher
; Return values .: Success - Returns an Array[2] = [Style, ExStyle] with the Styles/ExStyles value(s).
;                  Failure - Returns an Array with -1 as the 0 & 1 Index's.
; Author ........: guinness & additional information from Melba23.
; Example........; Yes
;=====================================================================================================================
Func GUICtrlGetStyle($iControlID)
    Local $aArray[2] = [-1, -1], $aExStyle, $aStyle, $hControl = $iControlID
	If Not IsHWnd($hControl) Then $hControl = GUICtrlGetHandle($iControlID)
    $aStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hControl, "int", 0xFFFFFFF0)
    If Not @error Then
        $aArray[0] = $aStyle[0]
    EndIf
    $aExStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hControl, "int", 0xFFFFFFEC)
    If Not @error Then
        $aArray[1] = $aExStyle[0]
    EndIf
    Return $aArray
EndFunc   ;==>GUICtrlGetStyle
