Danp2 Posted January 27, 2008 Share Posted January 27, 2008 (edited) Is it possible to control the background color for individual rows within a Listview control created using _GUICtrlListView_Create? Edited January 27, 2008 by DanP2 Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Danp2 Posted January 27, 2008 Author Share Posted January 27, 2008 Figured it out myself by modifying the code found here. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Danp2 Posted January 27, 2008 Author Share Posted January 27, 2008 Anyone know how this can be accomplished by subclassing the Listview control instead of using GUIRegisterMsg? Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Siao Posted January 27, 2008 Share Posted January 27, 2008 (edited) "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 January 28, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Danp2 Posted January 28, 2008 Author Share Posted January 28, 2008 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. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Squirrely1 Posted January 28, 2008 Share Posted January 28, 2008 (edited) 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 January 28, 2008 by Squirrely1 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
Danp2 Posted January 28, 2008 Author Share Posted January 28, 2008 Interesting. I previously implemented using $GUI_BKCOLOR_LV_ALTERNATE. Assign("ListItem" & $i, $xListView, 0) I take it this statement is optional, only needed for D&D? Thanks, Dan Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Squirrely1 Posted January 28, 2008 Share Posted January 28, 2008 ... 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 Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
rasim Posted January 28, 2008 Share Posted January 28, 2008 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. 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 Link to comment Share on other sites More sharing options...
Siao Posted January 28, 2008 Share Posted January 28, 2008 (edited) 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: expandcollapse popup#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. 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 January 28, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Squirrely1 Posted January 28, 2008 Share Posted January 28, 2008 Nice technique Uzebekistan - "$switch = Not $switch" We aren't supposed to SwitchWitches in my religion either, anyway. Das Häschen benutzt Radar Link to comment Share on other sites More sharing options...
Danp2 Posted January 28, 2008 Author Share Posted January 28, 2008 Thanks, Siao. The customdraw functionality is exactly what I was looking for. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
rasim Posted January 29, 2008 Share Posted January 29, 2008 Siao great work! You the best Link to comment Share on other sites More sharing options...
tryer777 Posted May 10, 2008 Share Posted May 10, 2008 (edited) Siao cool~!!! Edited May 10, 2008 by tryer777 Link to comment Share on other sites More sharing options...
Valuater Posted November 12, 2008 Share Posted November 12, 2008 Miss your coding Siao UPDATED 11-11-2008 expandcollapse popup#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) Link to comment Share on other sites More sharing options...
qsek Posted March 8, 2009 Share Posted March 8, 2009 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 BugFix extended this to a nice usable Template: http://www.autoitscript.com/forum/index.ph...=0&p=644312Just 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now