Page 1 of 1

Disable TreeGadget Item

Posted: Tue Sep 18, 2007 2:13 pm
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.

Posted: Tue Sep 18, 2007 2:45 pm
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!

Posted: Tue Sep 18, 2007 2:49 pm
by Inf0Byt3
Excellent! Thank you!

Posted: Tue Sep 18, 2007 3:03 pm
by srod
You're welcome.

Posted: Tue Sep 18, 2007 7:02 pm
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:

Posted: Tue Sep 18, 2007 7:09 pm
by srod
Good point; needs adjusting.

Posted: Tue Sep 18, 2007 7:26 pm
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 
:)

Posted: Tue Sep 18, 2007 8:44 pm
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 

Posted: Wed Sep 19, 2007 1:01 pm
by Inf0Byt3
Works perfectly, thanks!

Posted: Wed Sep 19, 2007 2:36 pm
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