[SOLVED] Treeview item handle and item index nr (Windows)

Just starting out? Need help? Post your questions and find answers here.
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

[SOLVED] Treeview item handle and item index nr (Windows)

Post by boddhi »

Hello,

I'd like to retrieve the item number hovered over (0 to x) of a treeview.
I have this piece of code that gives me the item's handle, but I can't establish a correspondence with the PB index number (like the one returned by GetGadgetState() during a selection).
How can I do this?
Thanks for your help.

Code: Select all

OpenWindow(0,0,0,400,200,"Treeview",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
TreeGadget(0,10,10,380,180)
AddGadgetItem(0,-1,"Item 0",0,0)
AddGadgetItem(0,-1,"Item 1",0,0)
AddGadgetItem(0,-1,"Node (Item 2)"+Str(a),0,0)
AddGadgetItem(0,-1,"Sub-Item 1 (Item 3)",0,1)
AddGadgetItem(0,-1,"Sub-Item 2 (Item 4)",0,1)
AddGadgetItem(0,-1,"Sub-Item 3 (Item 5)",0,1)
;
TVHTI.TV_HITTESTINFO
RECT.RECT
TVITEM.TVITEMEX
OldhItem.i
;
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow:Break
    Case #WM_MOUSEMOVE
      GetCursorPos_(@TVHTI\pt)
      ScreenToClient_(GadgetID(0),@TVHTI\pt)
      SendMessage_(GadgetID(0),#TVM_HITTEST,0,@TVHTI)
      RECT\left=TVHTI\hItem
      If TVHTI\hItem<>OldhItem
        OldhItem=TVHTI\hItem
        Debug "Handle item : "+OldhItem
        If OldhItem<>0
          ; Something else here ?
          SendMessage_(TVHTI\hItem,#TVM_GETITEM,0,@TVITEM)
          Debug "Item : "+TVITEM\hItem
          ; 
        EndIf
      EndIf
  EndSelect 
ForEver
 
 
[EDIT] : To see a fully fonctional code, see this message
Last edited by boddhi on Tue Feb 18, 2025 10:49 pm, edited 2 times in total.
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
normeus
Enthusiast
Enthusiast
Posts: 475
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Treeview item handle and item index nr (Windows)

Post by normeus »

Maybe use a map to keep track of the handles?

Code: Select all

OpenWindow(0,0,0,400,200,"Treeview",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
TreeGadget(0,10,10,380,180)
AddGadgetItem(0,-1,"Item 0",0,0)
AddGadgetItem(0,-1,"Item 1",0,0)
AddGadgetItem(0,-1,"Node (Item 2)"+Str(a),0,0)
AddGadgetItem(0,-1,"Sub-Item 1 (Item 3)",0,1)
AddGadgetItem(0,-1,"Sub-Item 2 (Item 4)",0,1)
AddGadgetItem(0,-1,"Sub-Item 3 (Item 5)",0,1)
;
NewMap gItem.i()
gItem(Str(GadgetItemID(0, 0)))=0
gItem(Str(GadgetItemID(0, 1)))=1
gItem(Str(GadgetItemID(0, 2)))=2
gItem(Str(GadgetItemID(0, 3)))=3
gItem(Str(GadgetItemID(0, 4)))=4
gItem(Str(GadgetItemID(0, 5)))=5

TVHTI.TV_HITTESTINFO
RECT.RECT
TVITEM.TVITEMEX
OldhItem.i
;
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow:Break
    Case #WM_MOUSEMOVE
      GetCursorPos_(@TVHTI\pt)
      ScreenToClient_(GadgetID(0),@TVHTI\pt)
      SendMessage_(GadgetID(0),#TVM_HITTEST,0,@TVHTI)
      RECT\left=TVHTI\hItem
      If TVHTI\hItem<>OldhItem
        OldhItem=TVHTI\hItem
        Debug "Handle item : "+OldhItem
        Debug "Item from Hamdle: " + gItem(Str(OldhItem))
        If OldhItem<>0
          ; Something else here ?
          SendMessage_(TVHTI\hItem,#TVM_GETITEM,0,@TVITEM)
          ;Debug "Item : "+TVITEM\hItem

          ; 
        EndIf
      EndIf
  EndSelect 
ForEver

Norm.
P.S. slow post
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Treeview item handle and item index nr (Windows)

Post by RASHAD »

Hi

Code: Select all

If OpenWindow(0, 0, 0, 400, 600, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    TreeGadget(0, 10, 10, 380, 580)
      For a = 0 To 10
        AddGadgetItem (0, -1, "Normal Item "+Str(a), 0, 0)
        AddGadgetItem (0, -1, "Node "+Str(a), 0, 0)
        AddGadgetItem(0, -1, "Sub-Item 1", 0, 1)
        AddGadgetItem(0, -1, "Sub-Item 2", 0, 1)
        AddGadgetItem(0, -1, "Sub-Item 3", 0, 1)
        AddGadgetItem(0, -1, "Sub-Item 4", 0, 1)
        AddGadgetItem (0, -1, "File "+Str(a), 0, 0)
      Next
      tv.TV_HITTESTINFO 
      SetActiveGadget(0)  
Repeat
  Select WaitWindowEvent()
     
    Case #PB_Event_CloseWindow
      Quit = 1
                       
    Case #WM_MOUSEMOVE
      GetCursorPos_(@tv\pt)
      ScreenToClient_(GadgetID(0),@tv\pt)
      h = SendMessage_(GadgetID(0),#TVM_HITTEST,0,tv)
      id = SendMessage_(GadgetID(0),4395 ,h,0) - 1
      SetGadgetState(0 , id)
  EndSelect
Until Quit = 1
EndIf
Egypt my love
User avatar
HeX0R
Addict
Addict
Posts: 1218
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Treeview item handle and item index nr (Windows)

Post by HeX0R »

in case you are wondering (like me) what that 4395 in RASHADs code might be:

Code: Select all

#TVM_MAPHTREEITEMTOACCID = #TV_FIRST + 43
Debug #TVM_MAPHTREEITEMTOACCID
;https://learn.microsoft.com/en-us/windows/win32/controls/tvm-maphtreeitemtoaccid
;https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/CommCtrl.h
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Treeview item handle and item index nr (Windows)

Post by Piero »

I was thinking this thread was a provocation, but then I realized it was just the consuete windows stuff :wink: :mrgreen:
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Treeview item handle and item index nr (Windows)

Post by RASHAD »

Hi HeXor :D
You are eight
Yes it's
Lately I just became a bad guy :mrgreen:
Egypt my love
User avatar
HeX0R
Addict
Addict
Posts: 1218
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: Treeview item handle and item index nr (Windows)

Post by HeX0R »

RASHAD wrote: Wed Feb 12, 2025 10:32 pm Hi HeXor :D
You are eight
No, I'm a ten, ask my wife :mrgreen:
(o.k. maybe better not)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Treeview item handle and item index nr (Windows)

Post by RASHAD »

:mrgreen:
Sorry mate
I should use my reading glass all time
Egypt my love
User avatar
Piero
Addict
Addict
Posts: 1040
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Treeview item handle and item index nr (Windows)

Post by Piero »

RASHAD wrote: Wed Feb 12, 2025 10:32 pmLately I just became a bad guy :mrgreen:
Pfft… that's SO easy… didn't you find some other interesting thing to do?
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: Treeview item handle and item index nr (Windows)

Post by boddhi »

Hi,

@normeus
Thanks for your code suggestion. It does the job perfectly, even if I prefer Rashad's solution, which is simpler in terms of coding.

@Rashad (and Hex0r for the precision and links).
Thanks. That's exactly what I needed.

Subsidiary question: Is it technically possible to “grey out” the element hovered over without changing the one already selected?
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Little John
Addict
Addict
Posts: 4802
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Treeview item handle and item index nr (Windows)

Post by Little John »

Thanks Rashad! That looks very nice.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Treeview item handle and item index nr (Windows)

Post by RASHAD »

@boddhi
@LJ
Thank you guys
Much appreciated
Egypt my love
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Treeview item handle and item index nr (Windows)

Post by boddhi »

Personal adaptation (for the example) from codes provided by Sparks, Andre, Falsam & Rashad (see links).
1) Tooltip displayed only if label or checkbox is hovered.
2) Multiline if item is a subitem

Code: Select all

; PB links
;   https://www.purebasic.fr/english/viewtopic.php?p=635240#p635240
;   https://www.purebasic.fr/english/viewtopic.php?p=364256#p364256
; External links
;   https://learn.microsoft.com/en-us/windows/win32/controls/tvm-maphtreeitemtoaccid
;   https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/um/CommCtrl.h
;
EnableExplicit
#TVM_MAPHTREEITEMTOACCID=#TV_FIRST+43
;
#WINDOW=1 ; 1 to make sure everything works properly, but can be any value, of course !
#TREEVVIEW=1
;
Global.i IdToolTip
Define.a Count
;
Procedure.i Fc_ToolTip_Creation(ArgWindowNr.i,ArgGadgetNr.i,ArgTitle.s,ArgText.s,ArgMaxLength.u=0,ArgFlags.u=0)
  Protected.TOOLINFO TOOLINFO
  Protected.i IdToolTip
  
  ArgFlags|#TTS_NOPREFIX ; Other possible options : |#TTS_BALLOON|#TTS_CLOSE
  IdToolTip=CreateWindowEx_(0,"ToolTips_Class32","",ArgFlags,0,0,0,0,WindowID(ArgWindowNr),0,GetModuleHandle_(0),0)
  SendMessage_(IdToolTip,#TTM_SETTIPTEXTCOLOR,GetSysColor_(#COLOR_INFOTEXT),0)
  SendMessage_(IdToolTip,#TTM_SETTIPBKCOLOR,GetSysColor_(#COLOR_INFOBK),0)
  If ArgMaxLength=0:ArgMaxLength=2000:EndIf
  SendMessage_(IdToolTip,#TTM_SETMAXTIPWIDTH,0,ArgMaxLength)
  ;
  With TOOLINFO
    \cbSize=SizeOf(TOOLINFO)
    \uFlags=#TTF_SUBCLASS|#TTF_IDISHWND
    \hWnd=WindowID(ArgWindowNr)
    \uId=GadgetID(ArgGadgetNr)
    \hinst=0
    \lpszText=@ArgText
  EndWith
  SendMessage_(IdToolTip,#TTM_ADDTOOL,0,TOOLINFO)
  SendMessage_(IdToolTip,#TTM_SETDELAYTIME,#TTDT_AUTOPOP,15000)
  If ArgTitle
    SendMessage_(IdToolTip,#TTM_SETTITLE,0,@ArgTitle)
  EndIf
  SendMessage_(IdToolTip,#TTM_UPDATE,0,0)
  ProcedureReturn IdToolTip
EndProcedure
Procedure   Pc_ToolTip_Modification(ArgIdToolTip.i,ArgWindowNr.i,ArgGadgetNr.u,ArgTitle.s,ArgText.s)
  Protected.TOOLINFO TOOLINFO
  
  With TOOLINFO
    \cbSize=SizeOf(TOOLINFO)
    \hWnd=WindowID(ArgWindowNr)
    \uId=GadgetID(ArgGadgetNr)
    \lpszText=@ArgText
  EndWith
  If ArgTitle
    SendMessage_(ArgIdToolTip,#TTM_SETTITLE,0,@ArgTitle)
  EndIf
  SendMessage_(ArgIdToolTip,#TTM_UPDATETIPTEXT,0,TOOLINFO)
EndProcedure
Procedure   Pc_ToolTip_Display(ArgWindowNr.i,ArgGadgetNr.i)
  Protected.TV_HITTESTINFO TVHITTESTINFO
  Protected.i IdItem,Item
  Protected.s String

  GetCursorPos_(@TVHITTESTINFO\pt)
  ScreenToClient_(GadgetID(ArgGadgetNr),@TVHITTESTINFO\pt)
  IdItem=SendMessage_(GadgetID(ArgGadgetNr),#TVM_HITTEST,0,TVHITTESTINFO)
  Item=SendMessage_(GadgetID(ArgGadgetNr),#TVM_MAPHTREEITEMTOACCID,IdItem,0)-1
  ;
  ; Zones de l'item survolées (Item hovered zones) : TVHITTESTINFO\flags
  ; #TVHT_NOWHERE             : 1         -> TVHITTESTINFO\flags&1
  ; #TVHT_ONITEMICON          : 2         -> TVHITTESTINFO\flags>>1&1
  ; #TVHT_ONITEMLABEL         : 4         -> TVHITTESTINFO\flags>>2&1
  ; #TVHT_ONITEMINDENT        : 8         -> TVHITTESTINFO\flags>>3&1
  ; #TVHT_ONITEMBUTTON        : 16        -> TVHITTESTINFO\flags>>4&1
  ; #TVHT_ONITEMRIGHT         : 32        -> TVHITTESTINFO\flags>>5&1
  ; #TVHT_ONITEMSTATEICON     : 64        -> TVHITTESTINFO\flags>>6&1
  ; #TVHT_ONITEM              : 70        -> Bool(TVHITTESTINFO\flags&70=70)
  ; #TVHT_ABOVE               : 256       -> TVHITTESTINFO\flags>>8&1
  ; #TVHT_BELOW               : 512       -> TVHITTESTINFO\flags>>9&1
  ; #TVHT_TORIGHT             : 1024      -> TVHITTESTINFO\flags>>10&1
  ; #TVHT_TOLEFT              : 2048      -> TVHITTESTINFO\flags>>11&1
  ; 
  If Item>=0 And (TVHITTESTINFO\flags>>2&1 Or TVHITTESTINFO\flags>>6&1):String=GetGadgetItemText(ArgGadgetNr,Item):EndIf
  ; Multiline if item sublevel > 0
  If String
    If GetGadgetItemAttribute(ArgGadgetNr,Item,#PB_Tree_SubLevel)>0
      String+#CRLF$+"Subitem level : "+Str(GetGadgetItemAttribute(ArgGadgetNr,Item,#PB_Tree_SubLevel))
    EndIf
  EndIf
  If IdToolTip=0 And Item>=0
    IdToolTip=Fc_ToolTip_Creation(ArgWindowNr,ArgGadgetNr,"Title "+String,String,200)
  Else
    Pc_ToolTip_Modification(IdToolTip,ArgWindowNr,ArgGadgetNr,"Title "+String,String)
  EndIf
  ; SetGadgetState(ArgGadgetNr,Item) ; Select hovered item
EndProcedure
;
If OpenWindow(#WINDOW,0,0,400,600,"TreeGadget",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  TreeGadget(#TREEVVIEW,10,10,380,280,#PB_Tree_CheckBoxes)
  For Count=0 To 1
    AddGadgetItem (#TREEVVIEW,-1,"Normal Item "+Str(Count),0,0)
    AddGadgetItem (#TREEVVIEW,-1,"Node "+Str(Count),0,0)
    AddGadgetItem(#TREEVVIEW,-1,"Sub-Item 1",0,1)
    AddGadgetItem(#TREEVVIEW,-1,"Sub-Item 2",0,1)
    AddGadgetItem(#TREEVVIEW,-1,"Sub-Item 3",0,1)
    AddGadgetItem(#TREEVVIEW,-1,"Sub-Item 4",0,1)
    AddGadgetItem (#TREEVVIEW,-1,"File "+Str(Count),0,0)
  Next
  SetActiveGadget(#TREEVVIEW)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow:Break
      Case #WM_MOUSEMOVE:Pc_ToolTip_Display(#WINDOW,#TREEVVIEW)
    EndSelect
  ForEver
EndIf
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Treeview item handle and item index nr (Windows)

Post by RASHAD »

Hi boddhi
1- Too much coding
2- The ToolTip flicker badly
Next is simple and fancy ToolTip
I hope you will like it

Code: Select all

LoadFont(0,"Georgia",12)
OpenWindow(0,0,0,400,300,"TreeView ToolTips",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

TreeGadget(0,10,10,380,280)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE)|#TVS_TRACKSELECT )
For a = 0 To 10
  AddGadgetItem (0, -1, "Normal Item "+Str(a), 0, 0)
  AddGadgetItem (0, -1, "Node "+Str(a), 0, 0)
  AddGadgetItem(0, -1, "Sub-Item 1", 0, 1)
  AddGadgetItem(0, -1, "Sub-Item 2", 0, 1)
  AddGadgetItem(0, -1, "Sub-Item 3", 0, 1)
  AddGadgetItem(0, -1, "Sub-Item 4", 0, 1)
  AddGadgetItem (0, -1, "File "+Str(a), 0, 0)
Next
ttip = CreateWindowEx_(0, "Tooltips_Class32", "", #TTS_ALWAYSTIP|#TTS_BALLOON, 0, 0, 0, 0, 0, 0, 0, 0)
SetWindowTheme_(ttip, @null.w, @null.w)
SendMessage_(ttip,#WM_SETFONT,FontID(0),0)
SendMessage_(ttip,#TTM_SETTIPTEXTCOLOR,$0202FD,0)
SendMessage_(ttip,#TTM_SETTIPBKCOLOR,$DCFFFF,0)
SendMessage_(ttip, #TTM_SETMAXTIPWIDTH, 0, 150)
SendMessage_(ttip, #TTM_SETDELAYTIME, #TTDT_AUTOMATIC,200)

tv.TV_HITTESTINFO

ti.TOOLINFO
ti\cbSize   = SizeOf(ti)
ti\uFlags   = #TTF_IDISHWND | #TTF_SUBCLASS
ti\uId= GadgetID(0)

Repeat
  Select WaitWindowEvent()     
    Case #PB_Event_CloseWindow
      Quit = 1       
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
      EndSelect         
      
    Case #WM_MOUSEMOVE
      GetCursorPos_(@tv\pt)
      ScreenToClient_(GadgetID(0),@tv\pt)
      item = SendMessage_(GadgetID(0),#TVM_HITTEST,0,tv)
      r.RECT\left = tv\hItem
      SendMessage_(GadgetID(0),#TVM_GETITEMRECT,1,r)
      If tv\pt\x <= r\right And tv\hItem > 0 And tv\hItem <> hItemOld
        SendMessage_(ttip, #TTM_DELTOOL, 0, ti)
        SendMessage_(GadgetID(0),#TVM_SELECTITEM,#TVGN_CARET,tv\hItem)
        SendMessage_(ttip, #TTM_SETDELAYTIME, #TTDT_INITIAL,10)
        Text$ ="ToolTip for Item "+Str(GetGadgetState(0))+" SubLevel : "+Str(GetGadgetItemAttribute(0, GetGadgetState(0), #PB_Tree_SubLevel ))
        ti\lpszText = @Text$
        SendMessage_(ttip, #TTM_ADDTOOL, 0, ti)
        hItemOld = tv\hItem
      EndIf
  EndSelect
Until Quit = 1
End
Egypt my love
boddhi
Enthusiast
Enthusiast
Posts: 524
Joined: Mon Nov 15, 2010 9:53 pm

Re: Treeview item handle and item index nr (Windows)

Post by boddhi »

RASHAD wrote: I hope you will like it
Hi RASCHAD,

Thanks for your code.
However, the code doesn't seem to work properly on my PC under Win10-x64 & PB 6.12-x64 :( .
The tooltip appears “randomly”.
In the screenshot below, I couldn't even get it to display.

Image
If my English syntax and lexicon are incorrect, please bear with Google translate and DeepL. They rarely agree with each other!
Except on this sentence...
Post Reply