- Offizieller Beitrag
Hi,
nach der FormatListview-UDF gibt es jetzt wieder etwas "Listviewmalerei".
Den meisten von euch wird die monotone blaue Färbung von selektierten Listviewitem wohl auch nicht so gefallen. Ich habe nun eine UDF erstellt mit der man das für ein (bis 40 beliebig viele) Listview einer GUI völlig separat gestalten kann. Das basiert auf einem Workaround von Achilles aus dem Jahr 2008. Aber außer mir hatte wohl noch niemand Interesse, das in eine vernünftig zu händelnde Funktion zu packen.
- Die verwendeten Listview müssen zwingend mit "GuiCtrlCreateListView" erstellt werden! Nur so gibt es eine ID, auf die auch aus der UDF heraus zugegriffen werden kann.
- Wird ein Listview-Style bei der Erstellung des LV gesetzt, so ist dieser beim Registrieren des LV mit an die UDF zu übergeben (Ausnahme: Default-Style)
- Für jedes registrierte Listview können eigene Selektionsfarben (Text/Hintergrund) gesetzt werden.
- Die Standardfarben der Listview der GUI (gültig für alle registrierten LV) lassen sich ebenfalls setzen.
- Es können registrierte LV auch wieder zurückgesetzt werden, sie erhalten dann die Standardfarben. werden dann wieder vom System gezeichnet und verhalten sich entsprechend (grau bei Fokusverlust). Der Style wird zurückgesetzt auf den Style bei Erstellung.
Ein entscheidender Vorteil dieser Variante ist (wie ihr auf dem Bild sehen könnt): Auch nach Fokusverlust bleibt die Selektionsfärbung erhalten.
Edit 24.10.2011: Kleine Änderungen - s. durchgestrichene bzw. blaue Bereiche in der Beschreibung vorab.
OwnLVSelection(1.2).au3
#Region - TimeStamp
; 2011-10-24 12:05:40 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 ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
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 ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
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 ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
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 ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
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
OwnLVSelection_Bsp(0.2).au3
#Region - TimeStamp
; 2011-10-24 00:42:01 v 0.2
#EndRegion - TimeStamp
#include <GuiListView.au3>
#include "OwnLVSelection.au3"
$gui = GUICreate('Bsp. OwnLVSelection', 430, 300)
$cLV1 = GuiCtrlCreateListView('Spalte 1|Spalte 2', 10, 10, 200, 135)
$hLV1 = GUICtrlGetHandle($cLV1)
For $i = 1 To 20
$index = _GUICtrlListView_AddItem($hLV1, 'Item-' & $i)
_GUICtrlListView_AddSubItem($hLV1, $index, 'Item-' & $i & '-2', 1)
Next
_GuiCtrlListview_OwnSelectionAdd($hLV1)
_GuiCtrlListview_OwnSelectionSetColor($hLV1, 0xFF55AA, 0xFFFF00)
$cLV2 = GuiCtrlCreateListView('Spalte 1|Spalte 2', 220, 10, 200, 135)
$hLV2 = GUICtrlGetHandle($cLV2)
For $i = 1 To 20
$index = _GUICtrlListView_AddItem($hLV2, 'Item-' & $i)
_GUICtrlListView_AddSubItem($hLV2, $index, 'Item-' & $i & '-2', 1)
Next
_GuiCtrlListview_OwnSelectionAdd($hLV2)
_GuiCtrlListview_OwnSelectionSetColor($hLV2, 0xFFFFFF, 0x0000FF)
$cLV3 = GuiCtrlCreateListView('Spalte 1|Spalte 2', 10, 155, 200, 135)
$hLV3 = GUICtrlGetHandle($cLV3)
For $i = 1 To 20
$index = _GUICtrlListView_AddItem($hLV3, 'Item-' & $i)
_GUICtrlListView_AddSubItem($hLV3, $index, 'Item-' & $i & '-2', 1)
Next
_GuiCtrlListview_OwnSelectionAdd($hLV3)
_GuiCtrlListview_OwnSelectionSetColor($hLV3, 0x222222, 0xCCCCCC)
$cLV4 = GuiCtrlCreateListView('Spalte 1|Spalte 2', 220, 155, 200, 135)
$hLV4 = GUICtrlGetHandle($cLV4)
For $i = 1 To 20
$index = _GUICtrlListView_AddItem($hLV4, 'Item-' & $i)
_GUICtrlListView_AddSubItem($hLV4, $index, 'Item-' & $i & '-2', 1)
Next
_GuiCtrlListview_OwnSelectionAdd($hLV4)
_GuiCtrlListview_OwnSelectionSetColor($hLV4, 0x1111FF, 0x00BBBB)
GUISetState()
[/autoit] [autoit][/autoit] [autoit]Sleep(5000)
_GuiCtrlListview_OwnSelectionDel($hLV4)
Do
Until GUIGetMsg() = -3