This task, while certainly doable, is not exactly trivial. You must solve for the case where columns are moved or resized and it is advisable to employ a method of controlling the line height of your ListIcon to accomodate image sizes. At the "standard" height, by the time you get button edges in there, there's only a handful of pixels left for your image height. Height is managed here with ownerdraw. Also, resizing of the column containing the button should be disallowed.
Disclaimer: Fair warning, this code is venturing into unsupported Purebasic territory; Overlapping gadgets are not supported at all in Purebasic. This code works fine on 4.60 RC1 but there is no guarantee that the team won't change the way ListIcon events and/or drawing get handled in the future and throw a monkey wrench into this.
Code: Select all
Procedure MainWindowCallBack(hwnd, msg, wparam, lparam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_DRAWITEM
*lpdis.DRAWITEMSTRUCT = lparam
Dim itemrect.RECT(3)
For i = 1 To 3
FillMemory(@itemrect(i),SizeOf(RECT))
itemrect(i)\top = i
SendMessage_(*lpdis\hwndItem, #LVM_GETSUBITEMRECT, *lpdis\itemid, @itemrect(i))
text$ = GetGadgetItemText(GetDlgCtrlID_(*lpdis\hwndItem), *lpdis\itemid, i)
SelectObject_(*lpdis\hDC, GetStockObject_(#NULL_PEN))
WhiteBrush = CreateSolidBrush_(#White)
SelectObject_(*lpdis\hDC, WhiteBrush)
Rectangle_(*lpdis\hDC, itemrect(i)\left+4, itemrect(i)\top+4, itemrect(i)\right, itemrect(i)\bottom)
TextOut_(*lpdis\hDC, itemrect(i)\left+4, itemrect(i)\top+4, text$, Len(text$))
DeleteObject_(WhiteBrush)
Next
Case #WM_MEASUREITEM
*lpmis.MEASUREITEMSTRUCT = lparam
*lpmis\itemheight = 20
EndSelect
ProcedureReturn result
EndProcedure
Procedure Reposition_Buttons()
Static firstcall = #True
Static topline=0
If firstcall
header = SendMessage_(GadgetID(0), #LVM_GETHEADER,0,0)
SendMessage_(header, #HDM_GETITEMRECT, 0, @hr.RECT)
topline = hr\bottom
firstcall = #False
EndIf
For i=1 To 3
FillMemory(itemrect.RECT, SizeOf(RECT))
itemrect\top = 3
itemrect\left = #LVIR_BOUNDS
SendMessage_(GadgetID(0), #LVM_GETSUBITEMRECT, i-1, @itemrect.RECT)
If itemrect\top >= topline
ResizeGadget(i, itemrect\left+1, itemrect\top+1, #PB_Ignore, #PB_Ignore)
HideGadget(i,0)
Else
HideGadget(i,1)
EndIf
Next
EndProcedure
Procedure SubClass_LV(hwnd, msg, wparam, lparam)
oldproc = GetProp_(hwnd, "oldproc")
Select msg
Case #WM_NCDESTROY
RemoveProp_(hwnd, "oldproc")
Case #WM_HSCROLL, #WM_VSCROLL
Reposition_Buttons()
Case #WM_NOTIFY
*nmHEADER.HD_NOTIFY = lParam
Select *nmHEADER\hdr\code
Case #HDN_ITEMCHANGINGA, #HDN_ITEMCHANGINGW
If *nmHEADER\iItem=3
SetCursor_(LoadCursor_(0, #IDC_NO))
ProcedureReturn #True
EndIf
Reposition_Buttons()
EndSelect
EndSelect
ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure
OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
SetWindowCallback(@MainWindowCallBack())
ListIconGadget(0,0,0,320,240,"",0,#LVS_OWNERDRAWFIXED|#PB_ListIcon_GridLines)
SetWindowLong_(GadgetID(0),#GWL_STYLE,GetWindowLong_(GadgetID(0),#GWL_STYLE)|#WS_CLIPCHILDREN)
SetProp_(GadgetID(0), "oldproc", SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubClass_LV()))
AddGadgetColumn(0,1,"Column 1",100)
AddGadgetColumn(0,2,"Column 2",100)
AddGadgetColumn(0,3,"Column 3",90)
AddGadgetItem(0, -1, Chr(10) + "Line 0 Col 1" + Chr(10) + "Line 0 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 1 Col 1" + Chr(10) + "Line 1 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 2 Col 1" + Chr(10) + "Line 2 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 3 Col 1" + Chr(10) + "Line 3 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 4 Col 1" + Chr(10) + "Line 4 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 5 Col 1" + Chr(10) + "Line 5 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 6 Col 1" + Chr(10) + "Line 6 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 7 Col 1" + Chr(10) + "Line 7 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 8 Col 1" + Chr(10) + "Line 8 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 9 Col 1" + Chr(10) + "Line 9 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 10 Col 1" + Chr(10) + "Line 10 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 11 Col 1" + Chr(10) + "Line 11 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 12 Col 1" + Chr(10) + "Line 12 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 13 Col 1" + Chr(10) + "Line 13 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 14 Col 1" + Chr(10) + "Line 14 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 15 Col 1" + Chr(10) + "Line 15 Col 2" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Line 16 Col 1" + Chr(10) + "Line 16 Col 2" + Chr(10) )
CreateImage(0, 80,12)
StartDrawing(ImageOutput(0))
Box(0,0,80,16,#Red)
StopDrawing()
UseGadgetList(GadgetID(0))
For i=1 To 3
FillMemory(itemrect.RECT, SizeOf(RECT))
itemrect\top = 3
itemrect\left = #LVIR_BOUNDS
SendMessage_(GadgetID(0),#LVM_GETSUBITEMRECT, i-1, @itemrect)
ResizeImage(0, itemrect\right-itemrect\left, itemrect\bottom-itemrect\top)
ContainerGadget(i, itemrect\left+1, itemrect\top+1, itemrect\right-itemrect\left-2, itemrect\bottom-itemrect\top-2)
ButtonImageGadget(i+3, 0,0, itemrect\right-itemrect\left-2, itemrect\bottom-itemrect\top-2, ImageID(0))
CloseGadgetList()
Next
UseGadgetList(WindowID(0))
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
Select GadgetType(EventGadget())
Case #PB_GadgetType_ButtonImage
Debug "Button "+Str(EventGadget())+" pressed"
EndSelect
EndSelect
Until EventID = #WM_CLOSE