It is accomplished in three steps: One, the ListIcon is placed into OwnerDrawFixed mode so that the #WM_MEASUREITEM message can be intercepted and the rowheight of our choice applied. In this case 20 is appropriate, as that is the height of the ComboBox we're using. This is done in the main window callback. Next, the ListIcon is subclassed and the hit tests are processed to give the index, size and location of the subitem to update. Third, the change event of the combobox is caught in the main loop and its contents used to update the current subitem. Here's the code:
Code: Select all
;================================================================
; Program: ListIcon FillByGadget Sample
; Author: netmaestro
; Date: January 7, 2007
; Target OS: Windows All
; Target Compiler: PureBasic 4.02
; License: Free, Unrestricted, Credit appreciated
; but not required
;================================================================
#LVM_SUBITEMHITTEST = #LVM_FIRST + 57
#LVM_GETSUBITEMRECT = #LVM_FIRST + 56
Global oldproc
Global currentitem, currentsubitem
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
RtlZeroMemory_(@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 SubClass_LV(hwnd, msg, wparam, lparam)
result = CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
If msg = #WM_RBUTTONDOWN Or msg = #WM_LBUTTONDOWN
GetCursorPos_(@cp.POINT)
MapWindowPoints_(0,hwnd,@cp,1)
HitInfo.LVHITTESTINFO
Hitinfo\pt\x = cp\x
HitInfo\pt\y = cp\y
SendMessage_(hwnd,#LVM_SUBITEMHITTEST ,0,@HitInfo)
If hitinfo\isubitem > 0 And HitInfo\iItem >= 0
currentitem = hitinfo\iitem
currentsubitem = hitinfo\isubitem
RtlZeroMemory_(@itemrect.RECT,SizeOf(RECT))
itemrect\top = hitinfo\iSubItem
SendMessage_(hwnd,#LVM_GETSUBITEMRECT, hitinfo\iitem, @itemrect)
If HitInfo\iSubItem = 3
ResizeGadget(1, itemrect\left, itemrect\top, itemrect\right-itemrect\left, itemrect\bottom-itemrect\top)
SetGadgetState(1,0)
HideGadget(1,0)
Else
HideGadget(1,1)
EndIf
Else
HideGadget(1,1)
EndIf
EndIf
ProcedureReturn result
EndProcedure
OpenWindow(0,0,0,320,240,"",$CF0001)
SetWindowCallback(@MainWindowCallBack())
CreateGadgetList(WindowID(0))
ListIconGadget(0,0,0,320,240,"",0,#PB_ListIcon_GridLines|#LVS_OWNERDRAWFIXED)
oldproc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubClass_LV())
AddGadgetColumn(0,1,"FirstName",100)
AddGadgetColumn(0,2,"LastName",100)
AddGadgetColumn(0,3,"City",115)
AddGadgetItem(0, -1, Chr(10) + "Lloyd" + Chr(10) + "Gallant" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Eric" + Chr(10) + "Penrose" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Mark" + Chr(10) + "Dutton" + Chr(10) )
AddGadgetItem(0, -1, Chr(10) + "Tim" + Chr(10) + "Knechtel" + Chr(10) )
ComboBoxGadget(1, 0,20,100,200,#PB_Window_Invisible)
SetParent_(GadgetID(1),GadgetID(0))
AddGadgetItem(1,0,"")
AddGadgetItem(1,1,"Toronto")
AddGadgetItem(1,2,"Kitchener")
AddGadgetItem(1,3,"Waterloo")
AddGadgetItem(1,4,"Barrie")
HideGadget(1,1)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
Select EventGadget()
Case 1
If EventType() = 1
SetGadgetItemText(0, currentitem, GetGadgetText(1), currentsubitem)
HideGadget(1,1)
EndIf
EndSelect
EndSelect
Until EventID = #WM_CLOSE