
Listicon Gadget bitmap ?
Just to prove I've been trying and not being lazy by asking you to do it, here
is a cut-down version of your code that ALMOST does what I want, but the
red text seems to be about 2 pixels to the left, and I haven't been able to
successfully move it those 2 pixels to the right. I'm probably overlooking
the obvious, but I've been at this for about an hour now with no luck.
is a cut-down version of your code that ALMOST does what I want, but the
red text seems to be about 2 pixels to the left, and I haven't been able to
successfully move it those 2 pixels to the right. I'm probably overlooking
the obvious, but I've been at this for about an hour now with no luck.

Code: Select all
Enumeration
#WindowMain=1
EndEnumeration
Enumeration
#ListIcon1=1
#Button1
EndEnumeration
#LVM_GETSUBITEMRECT=#LVM_FIRST+56
#CDDS_ITEM=$10000
#CDDS_POSTERASE=4
#CDDS_POSTPAINT=2
#CDDS_PREERASE=3
#CDDS_PREPAINT=1
#CDDS_ITEMPOSTERASE=#CDDS_ITEM|#CDDS_POSTERASE
#CDDS_ITEMPOSTPAINT=#CDDS_ITEM|#CDDS_POSTPAINT
#CDDS_ITEMPREERASE=#CDDS_ITEM|#CDDS_PREERASE
#CDDS_ITEMPREPAINT=#CDDS_ITEM|#CDDS_PREPAINT
#CDDS_SUBITEM=$20000
#CDRF_DODEFAULT=0
#CDRF_NOTIFYITEMDRAW=$20
#CDRF_NOTIFYPOSTERASE=$40
#CDRF_NOTIFYPOSTPAINT=$10
#CDRF_NOTIFYSUBITEMDRAW=$20
#CDRF_SKIPDEFAULT=4
Procedure GetCharWidth(hListIcon,char$)
ProcedureReturn SendMessage_(hListIcon,#LVM_GETSTRINGWIDTH,0,@char$)
EndProcedure
Procedure WinCallback(hwnd,msg,wparam,lparam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*nmhdr.NMHDR=lparam
If *nmhdr\code=#NM_CUSTOMDRAW And *nmhdr\hwndFrom=GadgetID(#ListIcon1)
*lvCD.NMLVCUSTOMDRAW=lparam
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result=#CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result=#CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT|#CDDS_SUBITEM
result=#CDRF_NOTIFYPOSTPAINT
Case #CDDS_ITEMPOSTPAINT|#CDDS_SUBITEM
If *lvCD\nmcd\dwItemSpec>-1 And *lvCD\iSubItem>-1
item$=GetGadgetItemText(#ListIcon1,*lvCD\nmcd\dwItemSpec,*lvCD\iSubItem)
subItemRc.RECT\left=#LVIR_LABEL : subItemRc\top=*lvCD\iSubItem
SendMessage_(*lvCD\nmcd\hdr\hwndFrom,#LVM_GETSUBITEMRECT,*lvCD\nmcd\dwItemSpec,@subItemRc)
For char=1 To Len(item$)
zz=#Black : If (char>7 And char<12) Or (char>16 And char<22) : zz=#Red : EndIf
char$=Mid(item$,char,1) : SetTextColor_(*lvCD\nmcd\hdc,zz) : DrawText_(*lvCD\nmcd\hdc,char$,1,subItemRc,#DT_NOCLIP)
subItemRc\left+GetCharWidth(*nmhdr\hwndFrom,char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
Next char
EndIf
result=#CDRF_SKIPDEFAULT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(#WindowMain,200,200,620,235,"Sparkies Multicolor ListIconGadget",#PB_Window_SystemMenu) And CreateGadgetList(WindowID(#WindowMain))
SetWindowCallback(@WinCallback())
ListIconGadget(#ListIcon1,5,5,610,195,"Column 0",270,#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect)
AddGadgetItem(#ListIcon1,-1,"I want THIS and THIS to be red")
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Try adding this after creating the ListIconGadget. I will try to find a better answer ASAP. 

Code: Select all
SendMessage_(GadgetID(#ListIcon1), #LVM_SETTEXTCOLOR, 0, #White)
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
hmmm...not sure why I was doing all the fancy work in the #CDDS_ITEMPOSTPAINT|#CDDS_SUBITEM portion but try this. It does the work in the #CDDS_ITEMPREPAINT portion. No need for the above mentioned #LVM_SETTEXTCOLOR
Code: Select all
Enumeration
#WindowMain=1
EndEnumeration
Enumeration
#ListIcon1=1
#Button1
EndEnumeration
#LVM_GETSUBITEMRECT=#LVM_FIRST+56
#CDDS_ITEM=$10000
#CDDS_POSTERASE=4
#CDDS_POSTPAINT=2
#CDDS_PREERASE=3
#CDDS_PREPAINT=1
#CDDS_ITEMPOSTERASE=#CDDS_ITEM|#CDDS_POSTERASE
#CDDS_ITEMPOSTPAINT=#CDDS_ITEM|#CDDS_POSTPAINT
#CDDS_ITEMPREERASE=#CDDS_ITEM|#CDDS_PREERASE
#CDDS_ITEMPREPAINT=#CDDS_ITEM|#CDDS_PREPAINT
#CDDS_SUBITEM=$20000
#CDRF_DODEFAULT=0
#CDRF_NOTIFYITEMDRAW=$20
#CDRF_NOTIFYPOSTERASE=$40
#CDRF_NOTIFYPOSTPAINT=$10
#CDRF_NOTIFYSUBITEMDRAW=$20
#CDRF_SKIPDEFAULT=4
Procedure GetCharWidth(hListIcon,char$)
ProcedureReturn SendMessage_(hListIcon,#LVM_GETSTRINGWIDTH,0,@char$)
EndProcedure
Procedure WinCallback(hwnd,msg,wParam,lParam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*nmhdr.NMHDR=lParam
If *nmhdr\code=#NM_CUSTOMDRAW And *nmhdr\hwndFrom=GadgetID(#ListIcon1)
*lvCD.NMLVCUSTOMDRAW=lParam
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result=#CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
If *lvCD\nmcd\dwItemSpec>-1 And *lvCD\iSubItem>-1
item$=GetGadgetItemText(#ListIcon1,*lvCD\nmcd\dwItemSpec,*lvCD\iSubItem)
subItemRc.RECT\left=#LVIR_LABEL : subItemRc\top=*lvCD\iSubItem
SendMessage_(*lvCD\nmcd\hdr\hwndFrom,#LVM_GETSUBITEMRECT,*lvCD\nmcd\dwItemSpec,@subItemRc)
For Char=1 To Len(item$)
zz=#Black : If (Char>7 And Char<12) Or (Char>16 And Char<22) : zz=#Red : EndIf
char$=Mid(item$,Char,1) : SetTextColor_(*lvCD\nmcd\hdc,zz) : DrawText_(*lvCD\nmcd\hdc,char$,1,subItemRc,#DT_NOCLIP)
subItemRc\left+GetCharWidth(*nmhdr\hwndFrom,char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
Next Char
EndIf
result=#CDRF_SKIPDEFAULT;#CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT|#CDDS_SUBITEM
result=#CDRF_NOTIFYPOSTPAINT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(#WindowMain,200,200,620,235,"Sparkies Multicolor ListIconGadget",#PB_Window_SystemMenu) And CreateGadgetList(WindowID(#WindowMain))
SetWindowCallback(@WinCallback())
ListIconGadget(#ListIcon1,5,5,610,195,"Column 0",270,#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect)
AddGadgetItem(#ListIcon1,-1,"I want THIS and THIS to be red")
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Code: Select all
SendMessage_(GadgetID(#ListIcon1), #LVM_SETTEXTCOLOR, 0, #White)

As for your updated example, I can't click the item at all?
Sorry PB, it's past my bedtime.
I added line 52 subItemRc\left + 2 and it seems to work. Must be a border issue. I can take a closer look tomorrow is necessary.

I added line 52 subItemRc\left + 2 and it seems to work. Must be a border issue. I can take a closer look tomorrow is necessary.

Code: Select all
Enumeration
#WindowMain=1
EndEnumeration
Enumeration
#ListIcon1=1
#Button1
EndEnumeration
#LVM_GETSUBITEMRECT=#LVM_FIRST+56
#CDDS_ITEM=$10000
#CDDS_POSTERASE=4
#CDDS_POSTPAINT=2
#CDDS_PREERASE=3
#CDDS_PREPAINT=1
#CDDS_ITEMPOSTERASE=#CDDS_ITEM|#CDDS_POSTERASE
#CDDS_ITEMPOSTPAINT=#CDDS_ITEM|#CDDS_POSTPAINT
#CDDS_ITEMPREERASE=#CDDS_ITEM|#CDDS_PREERASE
#CDDS_ITEMPREPAINT=#CDDS_ITEM|#CDDS_PREPAINT
#CDDS_SUBITEM=$20000
#CDRF_DODEFAULT=0
#CDRF_NOTIFYITEMDRAW=$20
#CDRF_NOTIFYPOSTERASE=$40
#CDRF_NOTIFYPOSTPAINT=$10
#CDRF_NOTIFYSUBITEMDRAW=$20
#CDRF_SKIPDEFAULT=4
Procedure GetCharWidth(hListIcon,char$)
ProcedureReturn SendMessage_(hListIcon,#LVM_GETSTRINGWIDTH,0,@char$)
EndProcedure
Procedure WinCallback(hwnd,msg,wParam,lParam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*nmhdr.NMHDR=lParam
If *nmhdr\code=#NM_CUSTOMDRAW And *nmhdr\hwndFrom=GadgetID(#ListIcon1)
*lvCD.NMLVCUSTOMDRAW=lParam
SetBkMode_(*lvCD\nmcd\hdc,#TRANSPARENT)
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result=#CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result=#CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT|#CDDS_SUBITEM
result=#CDRF_NOTIFYPOSTPAINT
Case #CDDS_ITEMPOSTPAINT|#CDDS_SUBITEM
If *lvCD\nmcd\dwItemSpec>-1 And *lvCD\iSubItem>-1
item$=GetGadgetItemText(#ListIcon1,*lvCD\nmcd\dwItemSpec,*lvCD\iSubItem)
subItemRc.RECT\left=#LVIR_LABEL : subItemRc\top=*lvCD\iSubItem
SendMessage_(*lvCD\nmcd\hdr\hwndFrom,#LVM_GETSUBITEMRECT,*lvCD\nmcd\dwItemSpec,@subItemRc)
subItemRc\left + 2
For Char=1 To Len(item$)
zz=#Black : If (Char>7 And Char<12) Or (Char>16 And Char<22) : zz=#Red : EndIf
char$=Mid(item$,Char,1) : SetTextColor_(*lvCD\nmcd\hdc,zz) : DrawText_(*lvCD\nmcd\hdc,char$,1,subItemRc,#DT_NOCLIP)
subItemRc\left+GetCharWidth(*nmhdr\hwndFrom,char$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
Next Char
EndIf
result=#CDRF_SKIPDEFAULT
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(#WindowMain,200,200,620,235,"Sparkies Multicolor ListIconGadget",#PB_Window_SystemMenu) And CreateGadgetList(WindowID(#WindowMain))
SetWindowCallback(@WinCallback())
ListIconGadget(#ListIcon1,5,5,610,195,"Column 0",270,#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect)
AddGadgetItem(#ListIcon1,-1,"I want THIS and THIS to be red")
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
Sorry but where does this code draws images? Maybe I'm to blind to see because of all the
and
Seriously, I can't read it. I get totally dizzy.
Code: Select all
; //////////////////////////////////////////
Code: Select all
; ...................................................
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
> I can take a closer look tomorrow
It's okay; it works fine now. Good job! I owe you many beers.
Here is your code stripped down even more, but still working just fine.
It's okay; it works fine now. Good job! I owe you many beers.

Here is your code stripped down even more, but still working just fine.
Code: Select all
Procedure GetCharWidth(gad,c$)
ProcedureReturn SendMessage_(gad,#LVM_GETSTRINGWIDTH,0,@c$)
EndProcedure
Procedure WinCallback(hwnd,msg,wParam,lParam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*nmhdr.NMHDR=lParam
If *nmhdr\code=#NM_CUSTOMDRAW And *nmhdr\hwndFrom=GadgetID(0)
*lvCD.NMLVCUSTOMDRAW=lParam
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_ITEMPREPAINT
result=#CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT|#CDDS_SUBITEM
result=#CDRF_NOTIFYPOSTPAINT
Case #CDDS_ITEMPOSTPAINT|#CDDS_SUBITEM
If *lvCD\nmcd\dwItemSpec>-1 And *lvCD\iSubItem>-1
item$=GetGadgetItemText(0,*lvCD\nmcd\dwItemSpec,*lvCD\iSubItem)
subItemRc.RECT\left=#LVIR_LABEL : subItemRc\top=*lvCD\iSubItem
SendMessage_(*lvCD\nmcd\hdr\hwndFrom,#LVM_GETSUBITEMRECT,*lvCD\nmcd\dwItemSpec,@subItemRc)
subItemRc\left+2
For c=1 To Len(item$)
zz=#Black : If (c>7 And c<12) Or (c>16 And c<22) : zz=#Red : EndIf
c$=Mid(item$,c,1) : SetTextColor_(*lvCD\nmcd\hdc,zz) : DrawText_(*lvCD\nmcd\hdc,c$,1,subItemRc,#DT_NOCLIP)
subItemRc\left+GetCharWidth(*nmhdr\hwndFrom,c$) + *lvCD\nmcd\dwItemSpec + *lvCD\iSubItem
Next
EndIf
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0,200,200,620,235,"Sparkies Multicolor ListIconGadget",#PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
SetWindowCallback(@WinCallback())
ListIconGadget(0,5,5,610,195,"Column 0",270,#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect)
AddGadgetItem(0,-1,"I want THIS and THIS to be red")
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Had a little tinker with your code.
The thing is that if you are returning #CDRF_SKIPDEFAULT in a pre-paint notification (as you need to do with this code of yours) then you must take steps to erase the background of each item if you are to allow item selection etc.
REMOVED whilst making changes.
The thing is that if you are returning #CDRF_SKIPDEFAULT in a pre-paint notification (as you need to do with this code of yours) then you must take steps to erase the background of each item if you are to allow item selection etc.
REMOVED whilst making changes.
I may look like a mule, but I'm not a complete ass.
Further to my previous post, you get very strange effects if you add extra columns with the spacing between characters. This is because of the custom spacing you employ.
Because of this, it's best if you custom draw all the text in the control etc.
Consequently I really have to take charge of showing the selction box etc.
You'll need to add extra logic if you require multi-select etc.
Because of this, it's best if you custom draw all the text in the control etc.
Consequently I really have to take charge of showing the selction box etc.
You'll need to add extra logic if you require multi-select etc.
Code: Select all
Procedure GetCharWidth(gad,c$)
ProcedureReturn SendMessage_(gad,#LVM_GETSTRINGWIDTH,0,@c$)
EndProcedure
Procedure WinCallback(hwnd,msg,wParam,lParam)
result=#PB_ProcessPureBasicEvents
Select msg
Case #WM_NOTIFY
*nmhdr.NMHDR=lParam
If *nmhdr\code=#NM_CUSTOMDRAW And *nmhdr\hwndFrom=GadgetID(0)
*lvCD.NMLVCUSTOMDRAW=lParam
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_ITEMPREPAINT
result=#CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT|#CDDS_SUBITEM
result=#CDRF_SKIPDEFAULT
If *lvCD\nmcd\dwItemSpec>-1 And *lvCD\iSubItem>-1
item$=GetGadgetItemText(0,*lvCD\nmcd\dwItemSpec,*lvCD\iSubItem)
subItemRc.RECT\left=#LVIR_LABEL : subItemRc\top=*lvCD\iSubItem
SendMessage_(*lvCD\nmcd\hdr\hwndFrom,#LVM_GETSUBITEMRECT,*lvCD\nmcd\dwItemSpec,@subItemRc)
If GetGadgetState(0)<>*lvCD\nmcd\dwItemSpec
FillRect_(*lvCD\nmcd\hdc, subItemRc, GetStockObject_(#WHITE_BRUSH))
Else
hBrush = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
FillRect_(*lvCD\nmcd\hdc, subItemRc, hBrush)
DeleteObject_(hBrush)
EndIf
For c=1 To Len(item$)
zz=#Black : If (c>7 And c<12) Or (c>16 And c<22) : zz=#Red : EndIf
c$=Mid(item$,c,1) : SetTextColor_(*lvCD\nmcd\hdc,zz) : DrawText_(*lvCD\nmcd\hdc,c$,1,subItemRc,#DT_NOCLIP)
subItemRc\left+GetCharWidth(*nmhdr\hwndFrom,c$) + *lvCD\iSubItem
Next
EndIf
EndSelect
EndIf
EndSelect
ProcedureReturn result
EndProcedure
If OpenWindow(0,200,200,620,235,"Sparkies Multicolor ListIconGadget",#PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
SetWindowCallback(@WinCallback())
ListIconGadget(0,5,5,610,195,"Column 0",270,#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect)
AddGadgetColumn(0,1,"ll",110)
AddGadgetItem(0,-1,"I want THIS and THIS to be red"+Chr(10)+"kk")
AddGadgetItem(0,-1,"I want THIS and THIS to be red")
AddGadgetItem(0,-1,"I want THIS and THIS to be red")
AddGadgetItem(0,-1,"I want THIS and THIS to be red")
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
I may look like a mule, but I'm not a complete ass.
I still can't remember why I handled this in the post paint process.
I thought this code was based on my multiline item ListIconGadget code, which handles all drawing, including selected and focused items, in pre-paint and post-paint process.
I'm on my way out to walk the dog so I'll let srod take over whilst I'm gone

I'm on my way out to walk the dog so I'll let srod take over whilst I'm gone

What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
...knowing that you'll need to repair all the damage done by that idiot srod when you return!Sparkie wrote:I still can't remember why I handled this in the post paint process.I thought this code was based on my multiline item ListIconGadget code, which handles all drawing, including selected and focused items, in pre-paint and post-paint process.
I'm on my way out to walk the dog so I'll let srod take over whilst I'm gone

I may look like a mule, but I'm not a complete ass.
The only damage I see thus far is the damage to my brain. In my original code I think I was being lazy by drawing in postpaint. Why else would I try to draw text on top of text rather than on top of a blank background 
@PB: I'll redo the code properly and post when it's done

@PB: I'll redo the code properly and post when it's done

What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1