Jump to content

Alternating row background color?


Danp2
 Share

Recommended Posts

"Ownerdraw" by its definition implies working through messages of parent window. Subclassing the control itself isn't of much help in this task.

All this seems odd to me, if GUICtrlCreateListView offers alternate row colors, why use _GUICtrlListView_Create to begin with? What advantages does it have to make up for the obvious numerous disadvantages. And if you worked out ownerdrawing, why are you not content with it. What's so wrong about GuiRegisterMsg?

Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

Thanks for your reply. There's nothing inherently wrong with using GuiRegisterMsg. I just thought it might be simpler to subclass and override the background color instead of having the draw the entire row, including calculating text spacing, manually.

As far was why I'm not using GUICtrlCreateListView, good question. I originally coded the routine using this, then decided to switch to the "newer" _GUICtrlListView. :D

Link to comment
Share on other sites

We got your code for you man -

#include <GUIConstants.au3>
#include <Constants.au3>
$switch = False
GUICreate("listview items", 422, 622, -1, -1)
$listview = GUICtrlCreateListView ("Date    |Index|Description                 |Amount  |Debit or Credit", 11, 11, 400, 600)
For $i = 1 To 28
    $xListView = GUICtrlCreateListViewItem(" | | | | ", $listview)
    If $switch Then
        GUICtrlSetBkColor($xListView, 0xEAFAF3)
    EndIf
    SwitchWitches()
    Assign("ListItem" & $i, $xListView, 0)
Next
; $ListItem1, $ListItem2, $ListItem3, etc, now can be written to with GUICtrlSetData(controlID, data [, default])
GUICtrlSetState(-1,$GUI_DROPACCEPTED) ; to allow drag and dropping
GUISetState()
Do
  $msg = GUIGetMsg ()
  Sleep(12)
Until $msg = $GUI_EVENT_CLOSE
Func SwitchWitches()
    If $switch Then
        $switch = False
    Else
        $switch = True
    EndIf
EndFunc
Edited by Squirrely1

Das Häschen benutzt Radar

Link to comment
Share on other sites

...

Assign("ListItem" & $i, $xListView, 0)

I take it this statement is optional, only needed for D&D?...

That statement works with others to ensure that each ListViewItem has a unique controlID to it so that you can write data to the controls.

See the commented line that reads this way:

; $ListItem1, $ListItem2, $ListItem3, etc, now can be written to with GUICtrlSetData ...

$ListItem1 contains the controlID of the first ListViewItem :D

Das Häschen benutzt Radar

Link to comment
Share on other sites

We got your code for you man -

#include <GUIConstants.au3>
#include <Constants.au3>
$switch = False
GUICreate("listview items", 422, 622, -1, -1)
$listview = GUICtrlCreateListView ("Date    |Index|Description                 |Amount  |Debit or Credit", 11, 11, 400, 600)
For $i = 1 To 28
    $xListView = GUICtrlCreateListViewItem(" | | | | ", $listview)
    If $switch Then
        GUICtrlSetBkColor($xListView, 0xEAFAF3)
    EndIf
    SwitchWitches()
    Assign("ListItem" & $i, $xListView, 0)
Next
; $ListItem1, $ListItem2, $ListItem3, etc, now can be written to with GUICtrlSetData(controlID, data [, default])
GUICtrlSetState(-1,$GUI_DROPACCEPTED); to allow drag and dropping
GUISetState()
Do
  $msg = GUIGetMsg ()
  Sleep(12)
Until $msg = $GUI_EVENT_CLOSE
Func SwitchWitches()
    If $switch Then
        $switch = False
    Else
        $switch = True
    EndIf
EndFunc
Good example with Assign("ListItem" & $i, $xListView, 0), i don`t know about this function. :D Facilitate example, without function:

#include <GUIConstants.au3>

Dim $switch = False

GUICreate("listview items", 422, 622)

$listview = GUICtrlCreateListView ("Date    |Index|Description                   |Amount  |Debit or Credit", 11, 11, 400, 600)

For $i = 1 To 28
    $xListView = GUICtrlCreateListViewItem(" | | | | ", $listview)
    If $switch Then
        GUICtrlSetBkColor($xListView, 0xEAFAF3)
    EndIf
    $switch = Not $switch
    Assign("ListItem" & $i, $xListView, 0)
Next

GUICtrlSetState(-1, $GUI_DROPACCEPTED)

GUISetState()

Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE

:P

Link to comment
Share on other sites

Thanks for your reply. There's nothing inherently wrong with using GuiRegisterMsg. I just thought it might be simpler to subclass and override the background color instead of having the draw the entire row, including calculating text spacing, manually.

Subclassing listview would get you access to its own WM_PAINT, WM_NOTIFY etc messages, but that's not what you really need to use for item drawing. I think this would be necessary if you'd want to paint headers and do some transparency stuff.

Anyway.

Instead of ownerdraw you can use customdraw, this way you don't have to deal with text writing manually at all, and can also pass and let LV do default drawing at any time:

#Include <GuiConstantsEx.au3>
#Include <GuiListView.au3>

;custom draw constants
Global Const $CDDS_ITEM = 0x10000
Global Const $CDDS_MAPPART = 0x5
Global Const $CDDS_POSTERASE = 0x4
Global Const $CDDS_POSTPAINT = 0x2
Global Const $CDDS_PREERASE = 0x3
Global Const $CDDS_PREPAINT = 0x1
Global Const $CDDS_SUBITEM = 0x20000
Global Const $CDDS_ITEMPOSTERASE = BitOR($CDDS_ITEM, $CDDS_POSTERASE)
Global Const $CDDS_ITEMPOSTPAINT = BitOR($CDDS_ITEM, $CDDS_POSTPAINT)
Global Const $CDDS_ITEMPREERASE = BitOR($CDDS_ITEM, $CDDS_PREERASE)
Global Const $CDDS_ITEMPREPAINT = BitOR($CDDS_ITEM, $CDDS_PREPAINT)

Global Const $CDRF_DODEFAULT = 0x0
Global Const $CDRF_NEWFONT = 0x2
Global Const $CDRF_NOTIFYITEMDRAW = 0x20
Global Const $CDRF_NOTIFYPOSTERASE = 0x40
Global Const $CDRF_NOTIFYPOSTPAINT = 0x10
Global Const $CDRF_NOTIFYSUBITEMDRAW = 0x20
Global Const $CDRF_SKIPDEFAULT = 0x4

;fonts for custom draw example
;bold
Global $aFont1 = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 700, _
                        "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _
                        "dword", 0, "str", "")
;italic
Global $aFont2 = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 400, _
                        "dword", 1, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _
                        "dword", 0, "str", "")
                        


$GUI = GUICreate("Listview Custom Draw", 400, 300)

$cListView = GUICtrlCreateListView("", 2, 2, 394, 268)
$hListView = GUICtrlGetHandle($cListView)
;or
;~ $hListView = _GUICtrlListView_Create($GUI, "", 2, 2, 394, 268)

_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

_GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
_GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
_GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

; Add items
For $i = 1 To 30
    _GUICtrlListView_AddItem($hListView, "Row" & $i & ": Col 1", $i-1)
    For $j = 1 To 2
        _GUICtrlListView_AddSubItem ($hListView, $i-1, "Row" & $i & ": Col " & $j+1, $j)
    Next
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFont1[0])
DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFont2[0])
Exit

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                     Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;' & _
                                        'dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;' & _
                                        'dword clrText;dword clrTextBk;int SubItem;' & _
                                        'dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align', _ ;winxp or later
                                        $lParam), $iDrawStage, $iItem, $iSubitem, $hDC, $iColor1, $iColor2, $iColor3
                    $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage')
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
                    If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
                    $iItem = DllStructGetData($tCustDraw, 'ItemSpec')
                    $iSubitem = DllStructGetData($tCustDraw, 'SubItem')
                    Switch $iItem
                        Case 0 To 9 ;for rows 1-10 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(-1)
                            $iColor3 = RGB2BGR(0xFF0000)
                            If Mod($iSubitem, 2) Then ;odd columns
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                DllStructSetData($tCustDraw, 'clrText', 0)
                            Else ;even columns
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                DllStructSetData($tCustDraw, 'clrText', $iColor3)
                            EndIf
                        Case 10 To 19 ;for rows 11-20 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(0x3DF8FF)
                            $hDC = DllStructGetData($tCustDraw, 'hdc')
                            If Mod($iItem, 2) Then
                                If Mod($iSubitem, 2) Then
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                Else
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                EndIf
                                DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont1[0]) ;select our chosen font into DC
                            Else
                                If Mod($iSubitem, 2) Then
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                Else
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                EndIf
                                DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont2[0])
                            EndIf
                        Case 20 To 29 ;for rows 21-30 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(-1)
                            If Mod($iItem, 2) Then ;odd rows
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                            Else
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                            EndIf                           
                    EndSwitch
                    Return $CDRF_NEWFONT
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func RGB2BGR($iColor)
    Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc

As far was why I'm not using GUICtrlCreateListView, good question. I originally coded the routine using this, then decided to switch to the "newer" _GUICtrlListView. :D

Not a very good decision 99% of the time, and I wish UDF documentation would warn that this is in no way mandatory, and has quite a few serious drawbacks if you chose to go that way. Right now lot of GUI newbies for whatever reason seem to be inclined to think that in order to use other GuiListview UDF functions they need to create listview using that function, or that it's somehow "newer" and "more advanced". Edited by Siao

"be smart, drink your wine"

Link to comment
Share on other sites

  • 3 months later...
  • 6 months later...

Miss your coding Siao

UPDATED 11-11-2008

#Include <GuiConstantsEx.au3>
#Include <GuiListView.au3>
#include <WindowsConstants.au3>


;fonts for custom draw example
;bold
Global $aFont1 = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 700, _
                        "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _
                        "dword", 0, "str", "")
;italic
Global $aFont2 = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 400, _
                        "dword", 1, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _
                        "dword", 0, "str", "")
                        


$GUI = GUICreate("Listview Custom Draw", 400, 300)

$cListView = GUICtrlCreateListView("", 2, 2, 394, 268)
$hListView = GUICtrlGetHandle($cListView)
;or
;~ $hListView = _GUICtrlListView_Create($GUI, "", 2, 2, 394, 268)

_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))

_GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
_GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
_GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

; Add items
For $i = 1 To 30
    _GUICtrlListView_AddItem($hListView, "Row" & $i & ": Col 1", $i-1)
    For $j = 1 To 2
        _GUICtrlListView_AddSubItem ($hListView, $i-1, "Row" & $i & ": Col " & $j+1, $j)
    Next
Next

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFont1[0])
DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFont2[0])
Exit

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_CUSTOMDRAW
                    If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG
                     Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;' & _
                                        'dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;' & _
                                        'dword clrText;dword clrTextBk;int SubItem;' & _
                                        'dword ItemType;dword clrFace;int IconEffect;int IconPhase;int PartID;int StateID;long rectText[4];int Align', _ ;winxp or later
                                        $lParam), $iDrawStage, $iItem, $iSubitem, $hDC, $iColor1, $iColor2, $iColor3
                    $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage')
                    If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW ;request custom drawing of items
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW ;request drawing each cell separately
                    If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT
                    $iItem = DllStructGetData($tCustDraw, 'ItemSpec')
                    $iSubitem = DllStructGetData($tCustDraw, 'SubItem')
                    Switch $iItem
                        Case 0 To 9 ;for rows 1-10 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(-1)
                            $iColor3 = RGB2BGR(0xFF0000)
                            If Mod($iSubitem, 2) Then ;odd columns
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                DllStructSetData($tCustDraw, 'clrText', 0)
                            Else ;even columns
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                DllStructSetData($tCustDraw, 'clrText', $iColor3)
                            EndIf
                        Case 10 To 19 ;for rows 11-20 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(0x3DF8FF)
                            $hDC = DllStructGetData($tCustDraw, 'hdc')
                            If Mod($iItem, 2) Then
                                If Mod($iSubitem, 2) Then
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                Else
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                EndIf
                                DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont1[0]) ;select our chosen font into DC
                            Else
                                If Mod($iSubitem, 2) Then
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                Else
                                    DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                EndIf
                                DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont2[0])
                            EndIf
                        Case 20 To 29 ;for rows 21-30 lets do this
                            $iColor1 = RGB2BGR(0xFBFFD8)
                            $iColor2 = RGB2BGR(-1)
                            If Mod($iItem, 2) Then ;odd rows
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                            Else
                                DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                            EndIf                     
                    EndSwitch
                    Return $CDRF_NEWFONT
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func RGB2BGR($iColor)
    Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc

8)

NEWHeader1.png

Link to comment
Share on other sites

  • 3 months later...

Siao, this is a breakthrough!

Cant say how glad i am that finally you can color single ListView Items, and even set the Font.

In the past this only was possible with GUICtrlSetBkColor where you had to deal with internal LV functions and the ControlID's for the items.

Now we can use the new List view UDF's which hold much more possibilities AND have custom coloring :P

BugFix extended this to a nice usable Template: http://www.autoitscript.com/forum/index.ph...=0&p=644312

Just wanted to thank you again for showing us this possibility!

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...