Disable TreeGadget Item

Just starting out? Need help? Post your questions and find answers here.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Disable TreeGadget Item

Post by Inf0Byt3 »

I need to make a TreeGadget with checkboxes and be able to disable some of the items so I can restrict users from disabling the checkboxes. I searched the forum and it was asked before but there was no solution. How can I disable the items?

Thanks.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Here you are my old mucka : :)

Code: Select all

Global oldTreeProc

Procedure TreeProc(hwnd, uMsg, wParam, lParam)
  Protected result, HitTest.TV_HITTESTINFO, i
  Select uMsg
    Case #WM_LBUTTONDOWN
      ;Determine which item was clicked etc.
        HitTest\pt\x = lParam&$FFFF 
        HitTest\pt\y = (lParam>>16)&$FFFF 
        SendMessage_(hwnd, #TVM_HITTEST, 0, HitTest) 
        For i = 0 To CountGadgetItems(0)-1 
          If HitTest\hItem = GadgetItemID(TreeGadgetID,i)  
            If (HitTest\flags = #TVHT_ONITEMSTATEICON And i <> 0) Or (HitTest\flags <> #TVHT_ONITEMSTATEICON And i <> 1)
              result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam)
            EndIf
          EndIf 
        Next 
    Default
      result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam)
    EndSelect
  ProcedureReturn result
EndProcedure 


;Example 
If OpenWindow(0, 0, 0, 350, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  TreeGadget(0, 10, 10, 250, 180, #PB_Tree_CheckBoxes) 
  
    AddGadgetItem (0, -1, "Cannot alter checkbox") 
      SetGadgetItemState(0,0,#PB_Tree_Checked)
    AddGadgetItem (0, -1, "Can alter checkbox but cannot select") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 

  oldTreeProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @TreeProc())
  
  Repeat 
   event = WaitWindowEvent() 
    
  Until event = #PB_Event_CloseWindow 
  
EndIf 
The message #TVN_ITEMCHANGING would be perfect, but it only exists on Vista - hence the wild hack!
I may look like a mule, but I'm not a complete ass.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Post by Inf0Byt3 »

Excellent! Thank you!
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

You're welcome.
I may look like a mule, but I'm not a complete ass.
CNESM
User
User
Posts: 54
Joined: Sat Jun 21, 2003 11:15 pm
Contact:

Post by CNESM »

Nice code srod, but it doesnt work 100%!

I can use the up and down buttons on my keyboard to select the disable item ... :roll:
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Good point; needs adjusting.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Right, smoke this one :

Code: Select all

Global oldTreeProc 

Procedure TreeProc(hwnd, uMsg, wParam, lParam) 
  Protected result, HitTest.TV_HITTESTINFO, i 
  Select uMsg 
    ;Here we prevent the checkbox of the zero item being altered.
      Case #WM_LBUTTONDOWN 
        ;Determine which item was clicked etc. 
          HitTest\pt\x = lParam&$FFFF 
          HitTest\pt\y = (lParam>>16)&$FFFF 
          SendMessage_(hwnd, #TVM_HITTEST, 0, HitTest) 
          For i = 0 To CountGadgetItems(0)-1 
            If HitTest\hItem = GadgetItemID(TreeGadgetID,i)  
              If (HitTest\flags <> #TVHT_ONITEMSTATEICON  Or i <> 0) 
                result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
              EndIf 
            EndIf 
          Next 
      Case #WM_KEYDOWN
        If wParam <> #VK_SPACE Or GetGadgetState(0)<>0
          result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
        EndIf
    Default 
      result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
    EndSelect 
  ProcedureReturn result 
EndProcedure 


Procedure.l WincallBack(hwnd, uMsg, wParam, lParam) 
  Protected result
  Protected *pnmtv.NM_TREEVIEW
  result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_NOTIFY
      *pnmtv=lParam
      Select *pnmtv\hdr\code
        ;Here we prevent item 1 being selected.
          Case #TVN_SELCHANGING
            If *pnmtv\itemNew\lParam = 1
              result = 1
            EndIf
      EndSelect
  EndSelect 
  ProcedureReturn result
EndProcedure



;Example 
If OpenWindow(0, 0, 0, 350, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  TreeGadget(0, 10, 10, 250, 180, #PB_Tree_CheckBoxes) 
  
    AddGadgetItem (0, -1, "Cannot alter checkbox") 
      SetGadgetItemState(0,0,#PB_Tree_Checked) 
    AddGadgetItem (0, -1, "Can alter checkbox but cannot select") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 

  oldTreeProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @TreeProc()) 
  SetWindowCallback(@WincallBack())

  Repeat 
   Event = WaitWindowEvent() 
    
  Until Event = #PB_Event_CloseWindow 
  
EndIf 
:)
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

A more refined version :

Code: Select all

Global oldTreeProc 

Procedure TreeProc(hwnd, uMsg, wParam, lParam) 
  Protected result, HitTest.TV_HITTESTINFO, item, tvitem.TV_ITEM
  Select uMsg 
    ;Here we prevent the checkbox of the zero item being altered.
      Case #WM_LBUTTONDOWN 
        ;Determine which item was clicked etc. 
          HitTest\pt\x = lParam&$FFFF 
          HitTest\pt\y = (lParam>>16)&$FFFF 
          If SendMessage_(hwnd, #TVM_HITTEST, 0, HitTest) 
            ;Identify the zero-based item index of the item clicked.
              tvitem\mask = #TVIF_PARAM	
              tvitem\hItem = HitTest\hItem
              SendMessage_(hwnd, #TVM_GETITEM, 0, tvitem)
              item = tvitem\lParam
            If (HitTest\flags <> #TVHT_ONITEMSTATEICON  Or item <> 0) 
                result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
            EndIf 
          EndIf
      Case #WM_KEYDOWN
        If wParam <> #VK_SPACE Or GetGadgetState(0)<>0
          result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
        EndIf
    Default 
      result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
    EndSelect 
  ProcedureReturn result 
EndProcedure 


Procedure.l WincallBack(hwnd, uMsg, wParam, lParam) 
  Protected result
  Protected *pnmtv.NM_TREEVIEW
  result = #PB_ProcessPureBasicEvents
  Select uMsg 
    Case #WM_NOTIFY
      *pnmtv=lParam
      Select *pnmtv\hdr\code
        ;Here we prevent item 1 being selected.
          Case #TVN_SELCHANGING
            If *pnmtv\itemNew\lParam = 1
              result = 1
            EndIf
      EndSelect
  EndSelect 
  ProcedureReturn result
EndProcedure



;Example 
If OpenWindow(0, 0, 0, 350, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  TreeGadget(0, 10, 10, 250, 180, #PB_Tree_CheckBoxes) 
  
    AddGadgetItem (0, -1, "Cannot alter checkbox") 
      SetGadgetItemState(0,0,#PB_Tree_Checked) 
    AddGadgetItem (0, -1, "Can alter checkbox but cannot select") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 

  oldTreeProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @TreeProc()) 
  SetWindowCallback(@WincallBack())

  Repeat 
   Event = WaitWindowEvent() 
    
  Until Event = #PB_Event_CloseWindow 
  
EndIf 
I may look like a mule, but I'm not a complete ass.
Inf0Byt3
PureBasic Fanatic
PureBasic Fanatic
Posts: 2236
Joined: Fri Dec 09, 2005 12:15 pm
Location: Elbonia

Post by Inf0Byt3 »

Works perfectly, thanks!
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
CNESM
User
User
Posts: 54
Joined: Sat Jun 21, 2003 11:15 pm
Contact:

Post by CNESM »

The last code works correct for the up and down button but now the left and right mouse buttons are not the same like the first example. With the first up mouse click (Left and right) i can select the item.

This version worky fine at my pc:

Code: Select all

Global oldTreeProc 

Procedure TreeProc(hwnd, uMsg, wParam, lParam) 
  Protected result, HitTest.TV_HITTESTINFO, i 
  Select uMsg 
    Case #WM_LBUTTONDOWN,#WM_RBUTTONDOWN
      ;Determine which item was clicked etc. 
        HitTest\pt\x = lParam&$FFFF 
        HitTest\pt\y = (lParam>>16)&$FFFF 
        SendMessage_(hwnd, #TVM_HITTEST, 0, HitTest) 
        For i = 0 To CountGadgetItems(0)-1 
          If HitTest\hItem = GadgetItemID(TreeGadgetID,i)  
            If (HitTest\flags = #TVHT_ONITEMSTATEICON And i <> 0) Or (HitTest\flags <> #TVHT_ONITEMSTATEICON And i <> 1) 
              result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
            EndIf 
          EndIf 
        Next 
          Case #WM_KEYDOWN 
        If wParam <> #VK_SPACE Or GetGadgetState(0)<>0 
          result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
        EndIf 
    Default 
      result = CallWindowProc_(oldTreeProc, hwnd, uMsg, wParam, lParam) 
    EndSelect 
  ProcedureReturn result 
EndProcedure 

Procedure.l WincallBack(hwnd, uMsg, wParam, lParam) 
  Protected result 
  Protected *pnmtv.NM_TREEVIEW 
  result = #PB_ProcessPureBasicEvents 
  Select uMsg 
    Case #WM_NOTIFY 
      *pnmtv=lParam 
      Select *pnmtv\hdr\code 
        ;Here we prevent item 1 being selected. 
          Case #TVN_SELCHANGING 
            If *pnmtv\itemNew\lParam = 1 
              result = 1 
            EndIf 
      EndSelect 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

;Example 
If OpenWindow(0, 0, 0, 350, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  TreeGadget(0, 10, 10, 250, 180) 
  
    AddGadgetItem (0, -1, "Cannot alter checkbox") 
      SetGadgetItemState(0,0,#PB_Tree_Checked) 
    AddGadgetItem (0, -1, "Can alter checkbox but cannot select") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 
    AddGadgetItem(0, -1, "Anything goes!") 

  oldTreeProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @TreeProc()) 
    SetWindowCallback(@WincallBack()) 
    
  Repeat 
   event = WaitWindowEvent() 
    
  Until event = #PB_Event_CloseWindow 
  
EndIf 
Post Reply