Thank you very much. Both of you did a great job !
Why hasn't Microsoft done anything to simplify this ? All this just to display an icon with a transparent backgound in listview...
ListIcon and image transparency
Re: ListIcon and image transparency
Windows 10 Pro x64
PureBasic 6.20 x64
PureBasic 6.20 x64
Re: ListIcon and image transparency
I've got a similar problem when I want to center the image/icon inside its column. The highlight of the line is erased by the redraw of the subitem image :
I guess I should apply the highlight color to the image/icon transparent background. Is it possible ?
Code: Select all
Global ImgList, OldWndProc, ListIcon
Procedure ListIcon_SetItemImage(tempListIconGadget, index_item.w, index_subitem.w, index_image.w)
Protected itemLV.LVITEM ; tagLVITEM
itemLV\mask = #LVIF_IMAGE
itemLV\iItem = index_item
itemLV\iSubItem = index_subitem
itemLV\iImage = index_image
If Not SendMessage_(GadgetID(tempListIconGadget), #LVM_SETITEM, 0, @itemLV)
Debug "#LVM_SETITEM error"
EndIf
EndProcedure
Procedure Add_Icon_To_ImageList(ImgList, DLL_Path.s, index)
Protected hIcon, img_index = -1
hIcon = ExtractIcon_(#Null, DLL_Path, index)
If hIcon
img_index = ImageList_AddIcon_(ImgList, hIcon)
DestroyIcon_(hIcon)
Else
ProcedureReturn -1
EndIf
ProcedureReturn img_index
EndProcedure
Procedure WndProc(hWnd, Message, wParam, lParam)
Protected *lparam.NMHDR, *lvcd.NMLVCUSTOMDRAW
Select Message
Case #WM_NOTIFY
If lParam
*lparam = lParam
If *lparam\hwndFrom = GadgetID(ListIcon)
Select *lparam\code
Case #NM_CUSTOMDRAW
*lvcd = lParam
Select *lvcd\nmcd\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
Protected hDC
Protected ptLVITEM.LVITEM
Protected Imgindex, hIcon
Protected ptRECT.RECT
Protected rectangle_width, new_x
Select *lvcd\iSubItem
Case 2
; ItemSelected = Bool(GetGadgetItemState(ListIcon, *lvcd\nmcd\dwItemSpec) & #PB_ListIcon_Selected)
; If ItemSelected And GetActiveGadget() = ListIcon
; BkColor = GetSysColor_(#COLOR_HIGHLIGHT)
; Else
; BkColor = GetSysColor_(#COLOR_BTNFACE)
; EndIf
hDC = *lvcd\nmcd\hdc
; hBrush = CreateSolidBrush_(BkColor)
; If hBrush
; FillRect_(hDC, ptRECT, hBrush)
; DeleteObject_(hBrush)
; EndIf
ptLVITEM\mask = #LVIF_IMAGE
ptLVITEM\iItem = *lvcd\nmcd\dwItemSpec
ptLVITEM\iSubItem = *lvcd\iSubItem
SendMessage_(*lparam\hwndFrom, #LVM_GETITEMW, 0, @ptLVITEM)
Imgindex = ptLVITEM\iImage
hIcon = ImageList_GetIcon_(ImgList, Imgindex, #ILD_NORMAL)
ptRECT\top = *lvcd\iSubItem
ptRECT\left = #LVIR_BOUNDS
SendMessage_(*lparam\hwndFrom, #LVM_GETSUBITEMRECT, *lvcd\nmcd\dwItemSpec, @ptRECT)
rectangle_width = ptRECT\right - ptRECT\left
new_x = ptRECT\left + (rectangle_width / 2) - 8 ; 8 = 16px / 2
DrawIconEx_(hDC, new_x, ptRECT\top, hIcon, 16, 16, 0, #Null, #DI_NORMAL)
DestroyIcon_(hIcon)
ReleaseDC_(*lparam\hwndFrom, hDC)
ProcedureReturn #CDRF_SKIPDEFAULT
EndSelect
Default
ProcedureReturn #CDRF_DODEFAULT
EndSelect
EndSelect
EndIf
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Define Window = OpenWindow(#PB_Any, 0, 0, 464, 462, "Image transparency", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIcon = ListIconGadget(#PB_Any, 34, 30, 388, 402, "Col 1", 100, #PB_ListIcon_FullRowSelect); | #PB_ListIcon_AlwaysShowSelection); | #PB_ListIcon_MultiSelect)
AddGadgetColumn(ListIcon, 1, "Col 2", 100)
AddGadgetColumn(ListIcon, 2, "Col 3", 100)
; SetGadgetColor(ListIcon, #PB_Gadget_BackColor, $CCCCCC)
ImgList = ImageList_Create_(16, 16, #ILC_COLOR32 | #ILC_MASK, 0, 10)
SendMessage_(GadgetID(ListIcon), #LVM_SETIMAGELIST, #LVSIL_SMALL, ImgList)
SendMessage_(GadgetID(ListIcon), #LVM_SETEXTENDEDLISTVIEWSTYLE, #LVS_EX_SUBITEMIMAGES, #LVS_EX_SUBITEMIMAGES)
;For i = 0 To 10
For i = 0 To 50
AddGadgetItem(ListIcon, i, "item" + i + Chr(10) + "subitem" + i)
Next
EnableGadgetDrop(ListIcon, #PB_Drop_Private, #PB_Drag_Move)
icon_index = Add_Icon_To_ImageList(ImgList, "shell32.dll", 296)
ListIcon_SetItemImage(ListIcon, 5, 2, icon_index)
ListIcon_SetItemImage(ListIcon, 6, 2, icon_index)
ListIcon_SetItemImage(ListIcon, 10, 2, icon_index)
SetWindowCallback(@WndProc())
Repeat
e = WaitWindowEvent()
Until e = #PB_Event_CloseWindow
Windows 10 Pro x64
PureBasic 6.20 x64
PureBasic 6.20 x64
Re: ListIcon and image transparency
Fill in the background color as shown below.
Code: Select all
Global ImgList, OldWndProc, ListIcon
Procedure ListIcon_SetItemImage(tempListIconGadget, index_item.w, index_subitem.w, index_image.w)
Protected itemLV.LVITEM ; tagLVITEM
itemLV\mask = #LVIF_IMAGE
itemLV\iItem = index_item
itemLV\iSubItem = index_subitem
itemLV\iImage = index_image
If Not SendMessage_(GadgetID(tempListIconGadget), #LVM_SETITEM, 0, @itemLV)
Debug "#LVM_SETITEM error"
EndIf
EndProcedure
Procedure Add_Icon_To_ImageList(ImgList, DLL_Path.s, index)
Protected hIcon, img_index = -1
hIcon = ExtractIcon_(#Null, DLL_Path, index)
If hIcon
img_index = ImageList_AddIcon_(ImgList, hIcon)
DestroyIcon_(hIcon)
Else
ProcedureReturn -1
EndIf
ProcedureReturn img_index
EndProcedure
Procedure WndProc(hWnd, Message, wParam, lParam)
Protected *lparam.NMHDR, *lvcd.NMLVCUSTOMDRAW
Select Message
Case #WM_NOTIFY
If lParam
*lparam = lParam
If *lparam\hwndFrom = GadgetID(ListIcon)
Select *lparam\code
Case #NM_CUSTOMDRAW
*lvcd = lParam
Select *lvcd\nmcd\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
Protected hDC
Protected ptLVITEM.LVITEM
Protected Imgindex, hIcon
Protected ptRECT.RECT
Protected rectangle_width, new_x
Select *lvcd\iSubItem
Case 2
ptLVITEM\mask = #LVIF_IMAGE
ptLVITEM\iItem = *lvcd\nmcd\dwItemSpec
ptLVITEM\iSubItem = *lvcd\iSubItem
SendMessage_(*lparam\hwndFrom, #LVM_GETITEMW, 0, @ptLVITEM)
Imgindex = ptLVITEM\iImage
hIcon = ImageList_GetIcon_(ImgList, Imgindex, #ILD_NORMAL)
ptRECT\top = *lvcd\iSubItem
ptRECT\left = #LVIR_BOUNDS
SendMessage_(*lparam\hwndFrom, #LVM_GETSUBITEMRECT, *lvcd\nmcd\dwItemSpec, @ptRECT)
rectangle_width = ptRECT\right - ptRECT\left
new_x = ptRECT\left + (rectangle_width / 2) - 8 ; 8 = 16px / 2
ItemSelected = Bool(GetGadgetItemState(ListIcon, *lvcd\nmcd\dwItemSpec) & #PB_ListIcon_Selected)
If ItemSelected And GetActiveGadget() = ListIcon
BkColor = GetSysColor_(#COLOR_HIGHLIGHT)
Else
BkColor = GetSysColor_(#COLOR_WINDOW)
EndIf
hDC = *lvcd\nmcd\hdc
hBrush = CreateSolidBrush_(BkColor)
If hBrush
FillRect_(hDC, ptRECT, hBrush)
DeleteObject_(hBrush)
EndIf
DrawIconEx_(hDC, new_x, ptRECT\top, hIcon, 16, 16, 0, #Null, #DI_NORMAL)
DestroyIcon_(hIcon)
ReleaseDC_(*lparam\hwndFrom, hDC)
ProcedureReturn #CDRF_SKIPDEFAULT
EndSelect
Default
ProcedureReturn #CDRF_DODEFAULT
EndSelect
EndSelect
EndIf
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Define Window = OpenWindow(#PB_Any, 0, 0, 464, 462, "Image transparency", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIcon = ListIconGadget(#PB_Any, 34, 30, 388, 402, "Col 1", 100, #PB_ListIcon_FullRowSelect); | #PB_ListIcon_AlwaysShowSelection); | #PB_ListIcon_MultiSelect)
AddGadgetColumn(ListIcon, 1, "Col 2", 100)
AddGadgetColumn(ListIcon, 2, "Col 3", 100)
; SetGadgetColor(ListIcon, #PB_Gadget_BackColor, $CCCCCC)
ImgList = ImageList_Create_(16, 16, #ILC_COLOR32 | #ILC_MASK, 0, 10)
SendMessage_(GadgetID(ListIcon), #LVM_SETIMAGELIST, #LVSIL_SMALL, ImgList)
SendMessage_(GadgetID(ListIcon), #LVM_SETEXTENDEDLISTVIEWSTYLE, #LVS_EX_SUBITEMIMAGES, #LVS_EX_SUBITEMIMAGES)
;For i = 0 To 10
For i = 0 To 50
AddGadgetItem(ListIcon, i, "item" + i + Chr(10) + "subitem" + i)
Next
EnableGadgetDrop(ListIcon, #PB_Drop_Private, #PB_Drag_Move)
icon_index = Add_Icon_To_ImageList(ImgList, "shell32.dll", 296)
ListIcon_SetItemImage(ListIcon, 5, 2, icon_index)
ListIcon_SetItemImage(ListIcon, 6, 2, icon_index)
ListIcon_SetItemImage(ListIcon, 10, 2, icon_index)
SetWindowCallback(@WndProc())
Repeat
e = WaitWindowEvent()
Until e = #PB_Event_CloseWindow
Re: ListIcon and image transparency
Thank you it work fine !
But I don't undestand why ? This code doesn't work :
The only difference is the position of the bloc between ";-------------------------------------"
But I don't undestand why ? This code doesn't work :
Code: Select all
Procedure WndProc(hWnd, Message, wParam, lParam)
Protected *lparam.NMHDR, *lvcd.NMLVCUSTOMDRAW
Select Message
Case #WM_NOTIFY
If lParam
*lparam = lParam
If *lparam\hwndFrom = GadgetID(ListIcon)
Select *lparam\code
Case #NM_CUSTOMDRAW
*lvcd = lParam
Select *lvcd\nmcd\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
Protected hDC
Protected ptLVITEM.LVITEM
Protected Imgindex, hIcon
Protected ptRECT.RECT
Protected rectangle_width, new_x
Select *lvcd\iSubItem
Case 2
ItemSelected = Bool(GetGadgetItemState(ListIcon, *lvcd\nmcd\dwItemSpec) & #PB_ListIcon_Selected)
If ItemSelected And GetActiveGadget() = ListIcon
BkColor = GetSysColor_(#COLOR_HIGHLIGHT)
Else
BkColor = GetSysColor_(#COLOR_WINDOW)
EndIf
hDC = *lvcd\nmcd\hdc
hBrush = CreateSolidBrush_(BkColor)
If hBrush
FillRect_(hDC, ptRECT, hBrush)
DeleteObject_(hBrush)
EndIf
;----------------------------------------------------------------------------------------
ptLVITEM\mask = #LVIF_IMAGE
ptLVITEM\iItem = *lvcd\nmcd\dwItemSpec
ptLVITEM\iSubItem = *lvcd\iSubItem
SendMessage_(*lparam\hwndFrom, #LVM_GETITEMW, 0, @ptLVITEM)
Imgindex = ptLVITEM\iImage
hIcon = ImageList_GetIcon_(ImgList, Imgindex, #ILD_NORMAL)
ptRECT\top = *lvcd\iSubItem
ptRECT\left = #LVIR_BOUNDS
SendMessage_(*lparam\hwndFrom, #LVM_GETSUBITEMRECT, *lvcd\nmcd\dwItemSpec, @ptRECT)
rectangle_width = ptRECT\right - ptRECT\left
new_x = ptRECT\left + (rectangle_width / 2) - 8 ; 8 = 16px / 2
;----------------------------------------------------------------------------------------
DrawIconEx_(hDC, new_x, ptRECT\top, hIcon, 16, 16, 0, #Null, #DI_NORMAL)
DestroyIcon_(hIcon)
ReleaseDC_(*lparam\hwndFrom, hDC)
ProcedureReturn #CDRF_SKIPDEFAULT
EndSelect
Default
ProcedureReturn #CDRF_DODEFAULT
EndSelect
EndSelect
EndIf
EndIf
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Windows 10 Pro x64
PureBasic 6.20 x64
PureBasic 6.20 x64
Re: ListIcon and image transparency
FillRect_() does not paint the background color because the values of the fields in the ptRECT structure are all 0.
The structure variable is only populated after the #LVM_GETSUBITEMRECT message call below.
The structure variable is only populated after the #LVM_GETSUBITEMRECT message call below.
Re: ListIcon and image transparency
I'm so stupid... I completely forgot the coordinate prequisite of FillRect 

Windows 10 Pro x64
PureBasic 6.20 x64
PureBasic 6.20 x64