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 



