Disable TreeGadget Item
Disable TreeGadget Item
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.
Thanks.
None are more hopelessly enslaved than those who falsely believe they are free. (Goethe)
Here you are my old mucka :
The message #TVN_ITEMCHANGING would be perfect, but it only exists on Vista - hence the wild hack!

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
I may look like a mule, but I'm not a complete ass.
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.
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.
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:
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