Page 1 of 2

ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 6:53 pm
by jacdelad
Hello,
I don't know any Windows API that can do that, but is it possible to allow checkboxes in a ListIconGadget for just some items and not all?

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 7:24 pm
by jassing
maybe this helps?
viewtopic.php?p=418994

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 7:32 pm
by jacdelad
Thanks, but unfortunately not. That's "just" (and I don't mean this in a bad way!) the API calls I already know.

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 7:38 pm
by jassing
jacdelad wrote: Mon Jul 03, 2023 7:32 pm Thanks, but unfortunately not. That's "just" (and I don't mean this in a bad way!) the API calls I already know.
well; the demo shows a listicon with some rows with checkboxes & some not...
good luck.

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 7:55 pm
by jacdelad
jassing wrote: Mon Jul 03, 2023 7:38 pm well; the demo shows a listicon with some rows with checkboxes & some not...
good luck.
Erm...no it doesn't.

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 8:06 pm
by jassing
jacdelad wrote: Mon Jul 03, 2023 7:55 pm
Erm...no it doesn't.
Sorry - I must have source codes mixed up..
Image

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 8:08 pm
by jacdelad
Seems so. :wink: No problem.

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 8:13 pm
by RASHAD
Hi jacdelad
I did the next snippet long long time back :)
You can have designed Checkboxes even for the Header too
Adapt it for your needs

Code: Select all

#HDF_IMAGE = $800
#HDI_IMAGE = $20

Global oldproc, header_h ,Header,cell.LVHITTESTINFO,ii.lv_item,hi.HDITEM,hh.HD_HITTESTINFO

ii\mask     = #LVIF_IMAGE
hi\mask     = #HDI_IMAGE
hi\fmt      = #HDF_IMAGE

Procedure setItemImg(Row,Col,Img)  
  ii\iItem    = Row
  ii\iSubItem = Col
  ii\iImage   = Img
  SendMessage_(GadgetID(0), #LVM_SETITEM, 0, @ii)
EndProcedure

Procedure getItemImg(Row,Col)
  ii\iItem    = Row
  ii\iSubItem = Col
  SendMessage_(GadgetID(0), #LVM_GETITEM, 0, @ii)
EndProcedure

Procedure setHeaderImg(Col,Img)  
  hi\iImage = Img
  SendMessage_(Header , #HDM_SETITEM, Col, @hi)
EndProcedure

Procedure getHeaderImg(Col)
  SendMessage_(Header , #HDM_GETITEM, col, @hi)
EndProcedure

Procedure IsMouseOver(hWnd) 
  GetWindowRect_(hWnd,r.RECT) 
  GetCursorPos_(p.POINT) 
  Result = PtInRect_(r,p\y << 32 + p\x) 
  ProcedureReturn Result 
EndProcedure 

Procedure Hheight(hWnd, uMsg, wParam, lParam)
  Select uMsg
    Case #HDM_LAYOUT
      result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
      *hdlayout.HD_LAYOUT = lParam
      If *hdlayout\prc <> 0
        *rect.RECT = *hdlayout\prc
        *rect\top = header_h
      EndIf
      If *hdlayout\pwpos <> 0
        *windowpos.WINDOWPOS = *hdlayout\pwpos
        *windowpos\cy = header_h
      EndIf
      
    Default
      result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
      
  EndSelect
  ProcedureReturn result
EndProcedure

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents 
  Select uMsg
      
    Case #WM_SIZE
      ResizeGadget(0,#PB_Ignore,#PB_Ignore,WindowWidth(0)-20, WindowHeight(0)-60)
      ResizeGadget(2,#PB_Ignore,WindowHeight(0)-30,80,20)
      
  EndSelect
  ProcedureReturn result
EndProcedure

LoadFont(0,"Marlett",120)
iinf.ICONINFO
iinf\fIcon = 1

ILwnd = ImageList_Create_(26,20,#ILC_COLOR32| #ILC_MASK, 0, 100)

CreateImage(0,26,20,24,#White)
iinf\hbmMask = ImageID(0)
iinf\hbmColor = ImageID(0)
Icwnd = CreateIconIndirect_(iinf)
ImageList_AddIcon_(ILwnd,Icwnd)

For img = 0 To 1
  CreateImage(0,260,200,24,#White)
  StartDrawing(ImageOutput(0))
  Box(60,0,160,160,0)
  Box(80,20,120,120,$FFFFFF)
  If img = 1
    DrawingFont(FontID(0))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(70,0,Chr($61),0)
  EndIf
  StopDrawing()
  ResizeImage(0,26,20,#PB_Image_Smooth)
  iinf\hbmMask = ImageID(0)
  iinf\hbmColor = ImageID(0)
  Icwnd = CreateIconIndirect_(iinf)
  ImageList_AddIcon_(ILwnd,Icwnd)
Next

FreeFont(0)
FreeImage(0)

LoadFont(0,"Broadway",16)

OpenWindow(0,0,0,800,500, "Special ListIcon", #PB_Window_ScreenCentered |#PB_Window_SystemMenu | #PB_Window_MaximizeGadget| #PB_Window_SizeGadget)       
ListIconGadget(0,10,10,780,440,"Column 0",150,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect)
SetGadgetColor(0,#PB_Gadget_BackColor,$EEEEEF)
SetGadgetColor(0,#PB_Gadget_LineColor,$CBCBCC)

SetGadgetFont(0,FontID(0))

AddGadgetColumn(0, 1, "Column 1",150)
AddGadgetColumn(0, 2, "Column 2",150)
AddGadgetColumn(0, 3, "Column 3",150)
AddGadgetColumn(0, 4, "Column 4",150)
AddGadgetColumn(0, 5, "Column 5",150)

SendMessage_(GadgetID(0), #LVM_SETEXTENDEDLISTVIEWSTYLE , #LVS_EX_SUBITEMIMAGES, #LVS_EX_SUBITEMIMAGES)

SendMessage_(GadgetID(0), #LVM_SETIMAGELIST, #LVSIL_SMALL, ILwnd)

For i = 0 To 5
  AddGadgetItem(0, -1, "  000"+Chr(10)+"  111"+Chr(10)+"  222"+Chr(10)+ "  333"+Chr(10)+ "  444")
Next

itemn = CountGadgetItems(0)

ButtonGadget(2,10,470,120,20,"Get check 2 state")

header_h = 42
Header = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0)
SendMessage_(header,#HDM_SETBITMAPMARGIN,0,0)

oldproc = SetWindowLongPtr_(Header, #GWL_WNDPROC, @Hheight())

;For cel = 0 To 5
setItemImg(0,0,1)
setItemImg(1,0,1)
setItemImg(2,0,1)
setItemImg(5,0,1)
;Next

; setHeaderImg(0,1)
; setHeaderImg(1,1) 
; setHeaderImg(2,1)
; setHeaderImg(4,1) 

SetWindowCallback(@WinCallback())

Repeat
  Select WaitWindowEvent()
      
    Case #PB_Event_CloseWindow
      Quit = 1
      
      ;       Case #WM_LBUTTONDOWN
      ;         If IsMouseOver(header) 
      ;           GetCursorPos_(@p.POINT)
      ;           ScreenToClient_(header, p)
      ;           hh\pt\x = p\x
      ;           hh\pt\y = p\y
      ;           SendMessage_(header,#HDM_HITTEST,0,@hh)
      ;           SendMessage_(header,#HDM_GETITEMRECT,hh\iItem,r.RECT)
      ;           If p\x < (r\left+20) And p\x > r\Left And p\y > 10 And p\y < 26
      ;             getHeaderImg(hh\iItem)
      ;             hindex = hi\iImage
      ;             If hindex % 2 = 1
      ;               hindex + 1
      ;             Else
      ;               hindex - 1
      ;             EndIf            
      ;             setHeaderImg(hh\iItem,hindex)
      ;             For item = 0 To itemn
      ;               setItemImg(item,hh\iItem,hindex)
      ;             Next 
      ;           EndIf
      ;         EndIf
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_LeftClick
              GetCursorPos_(@p.POINT)
              ScreenToClient_(GadgetID(0), p)
              cell\pt\x = p\x
              cell\pt\y = p\y  
              SendMessage_(GadgetID(0),#LVM_SUBITEMHITTEST,0,@cell)
              LI_row = cell\iItem
              LI_col = cell\iSubItem
              r.RECT
              r\top = LI_col
              r\left = #LVIR_BOUNDS  
              SendMessage_(GadgetID(0),#LVM_GETSUBITEMRECT,LI_col,@r)
              getItemImg(LI_row,LI_col)
              index = ii\iImage
              If p\x > r\left And p\x < (r\left+26) And  index > 0
                If index % 2 = 1
                  setItemImg(LI_row,LI_col,index + 1)
                Else
                  setItemImg(LI_row,LI_col,index - 1)
                EndIf 
                ;                 Else
                ;                   SetGadgetItemColor(0,OLdr,#PB_Gadget_FrontColor,#Black ,Oldc)
                ;                   SetGadgetItemColor(0,Oldr, #PB_Gadget_BackColor, $EEEEEF,Oldc)
                ;                   SetGadgetItemColor(0,LI_row,#PB_Gadget_FrontColor,GetSysColor_(#COLOR_HIGHLIGHTTEXT) ,LI_col)
                ;                   SetGadgetItemColor(0,LI_row, #PB_Gadget_BackColor,GetSysColor_(#COLOR_HIGHLIGHT),LI_col)
                ;                   OLdr = LI_row
                ;                   OLdc = LI_col
              EndIf
          EndSelect 
          
        Case 2
          getItemImg(2,0)
          If ii\iImage = 2
            Debug "Checkbox is checked" 
          Else
            Debug "Checkbox NOT checked" 
          EndIf       
      EndSelect             
  EndSelect
  
Until Quit = 1
End

Re: ListIconGadget with just some checkboxes

Posted: Mon Jul 03, 2023 8:18 pm
by jacdelad
Hi RASHAD,
thanks for the great code. I should have given clearer demands: I mean without using simulated checkboxes.

I hope I find the right words: That happens regularly here. I know I can use a canvas do everything we want, but often the questions are regarding the standard gadgets. Like in my case, it sometimes is impossible (which will make me use something custom, like yours or adapt the program).

Re: ListIconGadget with just some checkboxes

Posted: Tue Jul 04, 2023 12:00 am
by wombats
I modified RASHAD's code and came up with this. It removes the checkboxes from items 1 and 4 only, but they come back when you click on them. I tried removing them again in response to LVN_ITEMCHANGING, but it crashes. I also tried doing it in a #PB_EventType_LeftClick event, but the checkbox still briefly became visible before being removed again, even when I tried #WM_SETREDRAW to disable it drawing. I'm no WinAPI expert by any means, so hopefully someone more knowledgeable can make it work.

Code: Select all

#HDF_IMAGE = $800
#HDI_IMAGE = $20

Global oldproc, header_h ,Header,cell.LVHITTESTINFO,ii.lv_item,hi.HDITEM,hh.HD_HITTESTINFO

ii\mask = #LVIF_IMAGE
hi\mask = #HDI_IMAGE
hi\fmt = #HDF_IMAGE

Procedure RemoveCheckbox(item)  
  ii\iItem = item
  ii\state = 0
  ii\mask = #LVIF_STATE
  ii\stateMask = #LVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(0), #LVM_SETITEM, 0, @ii)
EndProcedure

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  Protected *nmhdr.NMHDR
  result = #PB_ProcessPureBasicEvents 
  Select uMsg
      
    Case #WM_NOTIFY
      *nmhdr = lParam      
      If *nmhdr\hwndFrom = GadgetID(0)
        Select *nmhdr\code
          Case #LVN_ITEMCHANGING
            ;RemoveCheckbox(1) - crashes here
        EndSelect
      EndIf
      
  EndSelect
  ProcedureReturn result
EndProcedure

OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)       
ListIconGadget(0, 10, 10, 620, 460, "Column 0", 150, #PB_ListIcon_CheckBoxes)

For i = 0 To 5
  AddGadgetItem(0, -1, "Item " + Str(i))
Next

RemoveCheckbox(1)
RemoveCheckbox(4)

SetWindowCallback(@WinCallback())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: ListIconGadget with just some checkboxes

Posted: Tue Jul 04, 2023 8:26 am
by BarryG
Here's some short code I got somewhere (can't remember where), and it works but only because of SetGadgetState(0,0) first.

Code: Select all

Procedure ListIconNoCheckBox(gad,item)
  lv.LV_ITEM\stateMask=#LVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(gad),#LVM_SETITEMSTATE,item-1,lv)
EndProcedure

Procedure NoCheckBoxes()
  ListIconNoCheckBox(0,2)
  ListIconNoCheckBox(0,4)
EndProcedure

If OpenWindow(0,350,250,270,150,"ListIconGadget",#PB_Window_SystemMenu)
  
  ListIconGadget(0,10,10,250,125,"test",300,#PB_ListIcon_CheckBoxes)
  For a=1 To 10
    addtext$="Item index #"+Str(a)+ " in the ListIconGadget"
    AddGadgetItem(0,-1,addtext$)
  Next
  
  NoCheckBoxes()
  SetActiveGadget(0)
  SetGadgetState(0,0)
  
  Repeat
    event=WaitWindowEvent()
    If event=#PB_Event_Gadget
      NoCheckBoxes()
    EndIf
  Until event=#PB_Event_CloseWindow
  
EndIf

Re: ListIconGadget with just some checkboxes

Posted: Tue Jul 04, 2023 1:31 pm
by jacdelad
Wow, thank you both. I didn't think this was possible natively!

Interesting detail:
I thought of automating it, but

Code: Select all

BindEvent(#PB_Event_Gadget,@NoCheckBoxes(),0,0)
let's the checkbox pop up for a fraction of a second when clicked. Strange.

Re: ListIconGadget with just some checkboxes

Posted: Sun Feb 01, 2026 5:17 pm
by jacdelad
BarryG wrote: Tue Jul 04, 2023 8:26 am Here's some short code I got somewhere (can't remember where), and it works but only because of SetGadgetState(0,0) first.

Code: Select all

Procedure ListIconNoCheckBox(gad,item)
  lv.LV_ITEM\stateMask=#LVIS_STATEIMAGEMASK
  SendMessage_(GadgetID(gad),#LVM_SETITEMSTATE,item-1,lv)
EndProcedure

Procedure NoCheckBoxes()
  ListIconNoCheckBox(0,2)
  ListIconNoCheckBox(0,4)
EndProcedure

If OpenWindow(0,350,250,270,150,"ListIconGadget",#PB_Window_SystemMenu)
  
  ListIconGadget(0,10,10,250,125,"test",300,#PB_ListIcon_CheckBoxes)
  For a=1 To 10
    addtext$="Item index #"+Str(a)+ " in the ListIconGadget"
    AddGadgetItem(0,-1,addtext$)
  Next
  
  NoCheckBoxes()
  SetActiveGadget(0)
  SetGadgetState(0,0)
  
  Repeat
    event=WaitWindowEvent()
    If event=#PB_Event_Gadget
      NoCheckBoxes()
    EndIf
  Until event=#PB_Event_CloseWindow
  
EndIf
This code works great. Dow anyone know how I can readd a checkbox without having to remove and add the item?

Re: ListIconGadget with just some checkboxes

Posted: Sun Feb 01, 2026 5:45 pm
by mk-soft

Code: Select all

If GetGadgetItemState(Gadget, Item) & #PB_ListIcon_Checked
...

Re: ListIconGadget with just some checkboxes

Posted: Sun Feb 01, 2026 6:23 pm
by jacdelad
mk-soft wrote: Sun Feb 01, 2026 5:45 pm

Code: Select all

If GetGadgetItemState(Gadget, Item) & #PB_ListIcon_Checked
...
How does this readd the checkbox?