Page 1 of 1
Multiline Listicon
Posted: Fri Aug 20, 2010 11:05 am
by captain_skank
Hi all,
I found some code by sparkie for a multiline listicon.
I've hacked around with it and have got it down to what i want/need except I can't figure out how to colour alternate lines.
Anybody know how I can do this ?? or if there is a better way to acheive this with a listicon ?
Code: Select all
; English forum: http://www.purebasic.fr/english/viewtopic.php?t=13226&highlight=
; Author: Sparkie (updated for PB 4.00 by Andre)
; Date: 06. December 2004
; OS: Windows
; Demo: No
; --> Constants
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
#DT_END_ELLIPSIS = $8000
#CDDS_ITEM = $10000
#CDDS_PREPAINT = 1
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEM = $20000
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYSUBITEMDRAW = $20
#CDRF_SKIPDEFAULT = 4
; --> Windowcallback
Procedure myWindowCallback(hWnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*lvCD.NMLVCUSTOMDRAW = lParam
If *lvCD\nmcd\hdr\hwndFrom=GadgetID(0) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
;result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisItem = *lvCD\nmcd\dwItemSpec
; --> Define rect for text
subItemRect.RECT\left = #LVIR_LABEL
subItemRect.RECT\top = *lvCD\iSubItem
; --> Get the subitem rect
SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, thisItem, @subItemRect)
subItemText$ = GetGadgetItemText(0, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem)
sitLen = Len(subItemText$)
; --> Adjust rect for text margins
lvFlags = #DT_END_ELLIPSIS | #DT_WORDBREAK
subItemRect\left +3
subItemRect\right -3
subItemRect\bottom -3
; --> Draw our text
DrawText_(*lvCD\nmcd\hDC, subItemText$, sitLen, subItemRect, lvFlags)
result = #CDRF_SKIPDEFAULT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 480, 260, "Sparkies Multiline ListIconGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
CreateStatusBar(0, WindowID(0))
ListIconGadget(0, 10, 10, 470, 225, "Column 0", 150, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Column 1", 150)
AddGadgetColumn(0, 2, "Column 2", 150)
; --> Create a new imagelist (1x30) to increase row hieght
;imageList = ImageList_Create_(1, increase this 15 = 1 line, #ILC_COLOR32, 0, 30)
imageList = ImageList_Create_(1, 45, #ILC_COLOR32, 0, 30)
SendMessage_(GadgetID(0), #LVM_SETIMAGELIST, #LVSIL_SMALL, imageList)
; chr(13) new line required for wordwrap - will not automaticaly wordwrap
For a=0 To 5
addtext$ = "Locked Column 0 item # " + Str(a) + Chr(13) + "on 2 lines of text." + Chr(13) + "on 3 lines of text."+ Chr(13) + Chr(10) + "Column 1 item #" + Str(a) + " on 1 line" + Chr(13) + "Column 1 item #" +Chr(10) + "Column 2 item #" + Str(a) + " on 1 line"
atLen = Len(addtext$)
AddGadgetItem(0, -1, addtext$)
; If varbackground$ = "white"
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $DCFDEE, -1)
; varbackground$ = "green"
; Else
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $FFFFFF, -1)
; varbackground$ = "white"
; EndIf
Next
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
; --> Display selected ListIconGadget index in statusbar
StatusBarText(0, 0, "Selected item index is: " + Str(GetGadgetState(0)))
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf
End
cheers
Captain_S
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 1:41 pm
by GeBonet
Hello,
Perhaps what you seek? If yes, fine ...
Yours
Code: Select all
; ------------------------------------------------------------------
; Constantes nécessaires a la procedure ListIconGadget_CustomDraw
#NM_CUSTOMDRAW = #NM_FIRST - 12
#CDDS_ITEM = $10000
#CDDS_SUBITEM = $20000
#CDDS_PREPAINT = $1
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEMPREPAINT = #CDDS_SUBITEM | #CDDS_ITEMPREPAINT
#CDRF_DODEFAULT = $0
#CDRF_NEWFONT = $2
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYSUBITEMDRAW = $20
; window callback permettant de personnaliser l'affichage du ListIconGadget
; ------------------------------------------------------------------
Declare.l ListIconGadget_CustomDraw(WindowID.l, Message.l, wParam.l, lParam.l)
; On charge des polices de caractères
Global FontReg.l, FontBold.l
FontReg = LoadFont(1, "Tahoma", 9)
FontBold = LoadFont(2, "Tahoma", 9, #PB_Font_Bold)
; On crée une fenêtre
OpenWindow(0, 0, 0, 356, 197, "ListIconGadget_CustomDraw",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
; On crée un ListIconGadget avec 8 colonnes
Global posthilit.l
posthilit = ListIconGadget(1, 10, 10, 336, 177,"", 70, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
; il est important de stocker le Handle du ListIconGadget dans une variable
; global car il est utile pour la Procedure ListIconGadget_CustomDraw()
AddGadgetColumn(1, 1, "Lun", 35)
AddGadgetColumn(1, 2, "Mar", 35)
AddGadgetColumn(1, 3, "Mer", 35)
AddGadgetColumn(1, 4, "Jeu", 35)
AddGadgetColumn(1, 5, "Ven", 35)
AddGadgetColumn(1, 6, "Sam", 35)
AddGadgetColumn(1, 7, "Dim", 35)
; On ajoute quelque ligne dans le ListIconGadget
For n = 0 To 23
AddGadgetItem(1, -1, Str(n) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX" + Chr(10) + Chr(10) + "XXX")
; Le chr(10) permet de passer à la case suivante (vers la droite)
Next
; On appelle la procedure permettant de personnaliser le ListIconGadget
SetWindowCallback(@ListIconGadget_CustomDraw())
Repeat
event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow
End
; ------------------------------------------------------------------------
; window callback permettant de personnaliser l'affichage du ListIconGadget
; ------------------------------------------------------------------------
Procedure.l ListIconGadget_CustomDraw(WindowID.l, Message.l, wParam.l, lParam.l)
If Message = #WM_NOTIFY
*LVCDHeader.NMLVCUSTOMDRAW = lParam
If *LVCDHeader\nmcd\hdr\hWndFrom = posthilit And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *LVCDHeader\nmcd\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_SUBITEMPREPAINT
; Modifier la couleur de fond
; *LVCDHeader\clrTextBk = RGB(255, 255, 223)
; Modifier la couleur du texte
; *LVCDHeader\clrText = RGB(0, 0, 255)
; Modifier la police
; SelectObject_(*LVCDHeader\nmcd\hDC, FontBold)
; -------------------------------------------------
; On récupère les coordonnées de la case à colorier
Row1.l = *LVCDHeader\nmcd\dwItemSpec
Col1.l = *LVCDHeader\iSubItem
; On personnalise la case
If Col1 = 0
SelectObject_(*LVCDHeader\nmcd\hDC, FontBold)
Else
SelectObject_(*LVCDHeader\nmcd\hDC, FontReg)
EndIf
If Mod(Row1,2) = 0
*LVCDHeader\clrTextBk = RGB(255, 255, 223)
If Col1 = 3
*LVCDHeader\clrText = RGB(255, 0, 0)
EndIf
Else
*LVCDHeader\clrTextBk = RGB(208, 208, 176)
If Col1 = 3
*LVCDHeader\clrText = RGB(0, 0, 255)
EndIf
EndIf
ProcedureReturn #CDRF_NEWFONT
Default
ProcedureReturn #PB_ProcessPureBasicEvents
EndSelect
Else
ProcedureReturn #PB_ProcessPureBasicEvents
EndIf
Else
ProcedureReturn #PB_ProcessPureBasicEvents
EndIf
EndProcedure
; --------------------------------------------------------------------------------
; Les structures utilisées dans la procédure ListIconGadget_CustomDraw
; Structure NMCUSTOMDRAW
; hdr.NMHDR
; dwDrawStage.l
; hdc.l
; rc.RECT
; dwItemSpec.l
; uItemState.l
; lItemlParam.l
; EndStructure
;
; Structure NMLVCUSTOMDRAW
; nmcd.NMCUSTOMDRAW
; clrText.l
; clrTextBk.l
; iSubItem.l
; dwItemType.l
;
; clrFace.l
; iIconEffect.l
; iIconPhase.l
; iPartId.l
; iStateId.l
;
; rcText.RECT
; uAlign.l
; EndStructure
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:09 pm
by captain_skank
Thanks for the code.
Unfortunately whilst this colours individual lines, I doesn't have muliple lines per cell.
I will continue trying to hack something up
Thanks again
C_S
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:29 pm
by srod
Code: Select all
; English forum: http://www.purebasic.fr/english/viewtopic.php?t=13226&highlight=
; Author: Sparkie (updated for PB 4.00 by Andre)
; Date: 06. December 2004
; OS: Windows
; Demo: No
; --> Constants
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
#DT_END_ELLIPSIS = $8000
#CDDS_ITEM = $10000
#CDDS_PREPAINT = 1
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEM = $20000
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYSUBITEMDRAW = $20
#CDRF_SKIPDEFAULT = 4
; --> Windowcallback
Procedure myWindowCallback(hWnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*lvCD.NMLVCUSTOMDRAW = lParam
If *lvCD\nmcd\hdr\hwndFrom=GadgetID(0) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
;result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisItem = *lvCD\nmcd\dwItemSpec
; --> Define rect for text
subItemRect.RECT\left = #LVIR_LABEL
subItemRect.RECT\top = *lvCD\iSubItem
; --> Get the subitem rect
SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, thisItem, @subItemRect)
subItemText$ = GetGadgetItemText(0, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem)
sitLen = Len(subItemText$)
; --> Adjust rect for text margins
lvFlags = #DT_END_ELLIPSIS | #DT_WORDBREAK
subItemRect\left +3
subItemRect\right -3
subItemRect\bottom -3
; --> Draw our text
If *lvCD\nmcd\dwItemSpec = *lvCD\nmcd\dwItemSpec>>1<<1
SetTextColor_(*lvCD\nmcd\hDC, #Red)
Else
SetTextColor_(*lvCD\nmcd\hDC, #Blue)
EndIf
DrawText_(*lvCD\nmcd\hDC, subItemText$, sitLen, subItemRect, lvFlags)
result = #CDRF_SKIPDEFAULT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 480, 260, "Sparkies Multiline ListIconGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
CreateStatusBar(0, WindowID(0))
ListIconGadget(0, 10, 10, 470, 225, "Column 0", 150, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Column 1", 150)
AddGadgetColumn(0, 2, "Column 2", 150)
; --> Create a new imagelist (1x30) to increase row hieght
;imageList = ImageList_Create_(1, increase this 15 = 1 line, #ILC_COLOR32, 0, 30)
imageList = ImageList_Create_(1, 45, #ILC_COLOR32, 0, 30)
SendMessage_(GadgetID(0), #LVM_SETIMAGELIST, #LVSIL_SMALL, imageList)
; chr(13) new line required for wordwrap - will not automaticaly wordwrap
For a=0 To 5
addtext$ = "Locked Column 0 item # " + Str(a) + Chr(13) + "on 2 lines of text." + Chr(13) + "on 3 lines of text."+ Chr(13) + Chr(10) + "Column 1 item #" + Str(a) + " on 1 line" + Chr(13) + "Column 1 item #" +Chr(10) + "Column 2 item #" + Str(a) + " on 1 line"
atLen = Len(addtext$)
AddGadgetItem(0, -1, addtext$)
; If varbackground$ = "white"
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $DCFDEE, -1)
; varbackground$ = "green"
; Else
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $FFFFFF, -1)
; varbackground$ = "white"
; EndIf
Next
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
; --> Display selected ListIconGadget index in statusbar
StatusBarText(0, 0, "Selected item index is: " + Str(GetGadgetState(0)))
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf
End
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:51 pm
by GeBonet
It is the Master
But, this code need :
AddStatusBarField()
Code: Select all
; After
SetWindowCallback(@myWindowCallback())
CreateStatusBar(0, WindowID(0))
; ... Here !
AddStatusBarField(300); Or more..
Bye.
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:52 pm
by srod
Aye, I just commented that out.

Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:55 pm
by captain_skank
Once again srod - you da man.
is there a way to set the background colour ??
I tried setbkcolor but this don't work.
I think i'm going to have to invest in an API book
cheers
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 2:59 pm
by captain_skank
Actualy that last statement is incorrect
SetBkMode_(*lvCD\nmcd\hDC, #opaque)
SetBKColor_(*lvCD\nmcd\hDC, #black)
works, but only changes the background colour for the text not the whole cell.
cheers
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 3:03 pm
by srod
The default background text rendering mode is transparent. Use SetBkMode_() to change this to opaque and then you can make use of SetBkColor_() etc.
If you wish to completely fill individual cells then use either FillRect_() or the Rectangle_() functions (with a transparent background so as not to upset the fill) before applying the text.
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 3:17 pm
by captain_skank
Sorry for being so thick but i placed the following in the colour section you added and it works fine :
Code: Select all
FillRect_(*lvCD\nmcd\hDC, subItemRect, CreateSolidBrush_($DCFDEE))
But is there a way to have no whitespace around the clouring in the cell ?
Cheers
C_S
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 3:18 pm
by srod
You just have to reposition some of Sparkie's rectangle calculations.
Code: Select all
; English forum: http://www.purebasic.fr/english/viewtopic.php?t=13226&highlight=
; Author: Sparkie (updated for PB 4.00 by Andre)
; Date: 06. December 2004
; OS: Windows
; Demo: No
; --> Constants
Global gYellowBrush = CreateSolidBrush_(#Yellow)
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
#DT_END_ELLIPSIS = $8000
#CDDS_ITEM = $10000
#CDDS_PREPAINT = 1
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDDS_SUBITEM = $20000
#CDRF_NOTIFYITEMDRAW = $20
#CDRF_NOTIFYSUBITEMDRAW = $20
#CDRF_SKIPDEFAULT = 4
; --> Windowcallback
Procedure myWindowCallback(hWnd, msg, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*lvCD.NMLVCUSTOMDRAW = lParam
If *lvCD\nmcd\hdr\hwndFrom=GadgetID(0) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
;result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisItem = *lvCD\nmcd\dwItemSpec
; --> Define rect for text
subItemRect.RECT\left = #LVIR_LABEL
subItemRect.RECT\top = *lvCD\iSubItem
; --> Get the subitem rect
SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, thisItem, @subItemRect)
subItemText$ = GetGadgetItemText(0, *lvCD\nmcd\dwItemSpec, *lvCD\iSubItem)
sitLen = Len(subItemText$)
; --> Adjust rect for text margins
lvFlags = #DT_END_ELLIPSIS | #DT_WORDBREAK
; --> Draw our text
SetBkMode_(*lvCD\nmcd\hDC, #TRANSPARENT)
If *lvCD\nmcd\dwItemSpec = *lvCD\nmcd\dwItemSpec>>1<<1
FillRect_(*lvCD\nmcd\hDC, subItemRect, gYellowBrush)
SetTextColor_(*lvCD\nmcd\hDC, #Red)
Else
SetTextColor_(*lvCD\nmcd\hDC, #Blue)
EndIf
subItemRect\left +3
subItemRect\right -3
subItemRect\bottom -3
DrawText_(*lvCD\nmcd\hDC, subItemText$, sitLen, subItemRect, lvFlags)
result = #CDRF_SKIPDEFAULT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0, 0, 0, 480, 260, "Sparkies Multiline ListIconGadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SetWindowCallback(@myWindowCallback())
CreateStatusBar(0, WindowID(0))
ListIconGadget(0, 10, 10, 470, 225, "Column 0", 150, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Column 1", 150)
AddGadgetColumn(0, 2, "Column 2", 150)
; --> Create a new imagelist (1x30) to increase row hieght
;imageList = ImageList_Create_(1, increase this 15 = 1 line, #ILC_COLOR32, 0, 30)
imageList = ImageList_Create_(1, 45, #ILC_COLOR32, 0, 30)
SendMessage_(GadgetID(0), #LVM_SETIMAGELIST, #LVSIL_SMALL, imageList)
; chr(13) new line required for wordwrap - will not automaticaly wordwrap
For a=0 To 5
addtext$ = "Locked Column 0 item # " + Str(a) + Chr(13) + "on 2 lines of text." + Chr(13) + "on 3 lines of text."+ Chr(13) + Chr(10) + "Column 1 item #" + Str(a) + " on 1 line" + Chr(13) + "Column 1 item #" +Chr(10) + "Column 2 item #" + Str(a) + " on 1 line"
atLen = Len(addtext$)
AddGadgetItem(0, -1, addtext$)
; If varbackground$ = "white"
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $DCFDEE, -1)
; varbackground$ = "green"
; Else
; SetGadgetItemColor(0, a, #PB_Gadget_BackColor, $FFFFFF, -1)
; varbackground$ = "white"
; EndIf
Next
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 0
; --> Display selected ListIconGadget index in statusbar
; StatusBarText(0, 0, "Selected item index is: " + Str(GetGadgetState(0)))
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf
End
**EDIT : do not create a brush in the painting procedure without then deleting it before you exit! That will give you one horrendous memory leak.
Re: Multiline Listicon
Posted: Fri Aug 20, 2010 3:28 pm
by captain_skank
srod wrote:
**EDIT : do not create a brush in the painting procedure without then deleting it before you exit! That will give you one horrendous memory leak.
Just found that out
Thanks for all your help guys and thanks to sparkie for the original code.