Add libraries (eg Music) to ExplorerTreeGadget?

Windows specific forum
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Add libraries (eg Music) to ExplorerTreeGadget?

Post by ozzie »

I am using the ExplorerTreeGadget and associated gadgets for a custom-built file browser, so I can include controls for previewing audio files. However, the PureBasic ExplorerTreeGadget only includes Documents as an additional item, so to get to libraries such as Music the users has to navigate through the relevant parent directories. On searching for a solution in the PB Forums I found a similar request from oryaaaaa which contained some code provided by RASHAD. That code was written for Win7, and I've tried to use this (slightly modified) on my Win10 development machine, but the code does not seem to detect that the libraries contain any sub-directories (which they do).

Here's the code I'm using:

Code: Select all

#TVGN_LASTVISIBLE = 10

Procedure AddItem(gadget.l, text.s)
  hRoot = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_LASTVISIBLE, 0)
  lpis.TV_INSERTSTRUCT
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hRoot)
  lpis\hInsertAfter = hRoot
  lpis\item\mask = #TVIF_TEXT
  lpis\item\cchTextMax = Len(text)
  lpis\item\pszText = @text
  SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
EndProcedure

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*")
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
If OSVersion() >= #PB_OS_Windows_7
  AddItem(0,"C:\Users\Public\Public Music")
  AddItem(0,"C:\Users\Public\Public Pictures")
  AddItem(0,"C:\Users\Public\Public Videos")
EndIf 

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1          
      
  EndSelect
  
Until Quit = 1
When I run this code, the public music, pictures and videos folders are displayed without the '+', even though they contain sub-directories.

Does the above code need changing for Win10? Should this code handle sub-directories?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Add libraries (eg Music) to ExplorerTreeGadget?

Post by RASHAD »

Hi

Code: Select all

#TVGN_LASTVISIBLE = 10

Procedure AddItem(gadget.l,position.l, text.s,flag.l)
  hRoot = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_LASTVISIBLE, 0)
  lpis.TV_INSERTSTRUCT
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hRoot)
  lpis\hInsertAfter = hRoot
  lpis\item\mask =  #TVIF_TEXT
  lpis\item\cchTextMax = Len(text)
  lpis\item\pszText = @text
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
  ExamineDirectory(0, text,"*.*")
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      text = DirectoryEntryName(0)
      lpis\item\cchTextMax = Len(text)
      lpis\item\pszText = @text
      SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
    EndIf
  Wend
EndProcedure

    OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester|#PB_Explorer_NoFiles)
    SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
    If OSVersion() >= #PB_OS_Windows_10
      AddItem(0,0,"C:\Users\Public\Pictures",0)
      AddItem(0,0,"C:\Users\Public\Videos",1)
    EndIf    
    
    
    Repeat
    Select WaitWindowEvent()
       Case #PB_Event_CloseWindow
           q = 1          

   EndSelect
   
    Until q = 1
Egypt my love
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Add libraries (eg Music) to ExplorerTreeGadget?

Post by RASHAD »

Workaround :)

#1 :

Code: Select all

RunProgram("CMD","/c subst x: c:\users\public\pictures","",#PB_Program_Hide )
RunProgram("CMD","/c subst t: c:\users\public\videos","",#PB_Program_Hide )
 

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
   

Repeat
Select WaitWindowEvent()
   Case #PB_Event_CloseWindow
       Quit = 1       

EndSelect

Until Quit = 1
RunProgram("CMD","/c subst x: /d","",#PB_Program_Hide )
RunProgram("CMD","/c subst t: /d","",#PB_Program_Hide )
#2 :

Code: Select all

DefineDosDevice_(0	,"x:", "c:\users\public\pictures")
DefineDosDevice_(0	,"t:", "c:\users\public\videos")
 

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
   

Repeat
Select WaitWindowEvent()
   Case #PB_Event_CloseWindow
       Quit = 1       

EndSelect

Until Quit = 1
DefineDosDevice_(#DDD_REMOVE_DEFINITION	,"x:", 0)
DefineDosDevice_(#DDD_REMOVE_DEFINITION	,"t:", 0)
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: Add libraries (eg Music) to ExplorerTreeGadget?

Post by ozzie »

Thanks, RASHAD, we're almost there. I prefer your first suggestion rather than using pseudo drive letters. Also, for the 'tree' I need the directories listed, not files, so I changed the DirectoryEntryType(0) test. However, on clicking on one of these additional directories I don't get the actual path name from GetGadgetText(0) - it just returns A:\, and if it's a subnode I get A:\A:\. For directories handled by the ExplorerTreeGadget itself, GetGadgetText(0) returns the correct path name, eg C:\Users\Mike\Documents\.

Here's my latest code:

Code: Select all

#TVGN_LASTVISIBLE = 10

Procedure AddItem(gadget.l, position.l, text.s, flag.l)
  hRoot = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_LASTVISIBLE, 0)
  lpis.TV_INSERTSTRUCT
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hRoot)
  lpis\hInsertAfter = hRoot
  lpis\item\mask =  #TVIF_TEXT
  lpis\item\cchTextMax = Len(text)
  lpis\item\pszText = @text
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
  ExamineDirectory(0, text,"*.*")
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
      text = DirectoryEntryName(0)
      Select text
        Case ".", ".."
          ; ignore
        Default
          lpis\item\cchTextMax = Len(text)
          lpis\item\pszText = @text
          SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
      EndSelect
    EndIf
  Wend
EndProcedure

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester|#PB_Explorer_NoFiles)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
If OSVersion() >= #PB_OS_Windows_10
  AddItem(0,0,"C:\Users\Public\Music",0)
  AddItem(0,0,"C:\Users\Public\Pictures",1)
  AddItem(0,0,"C:\Users\Public\Videos",2)
EndIf    

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      q = 1          
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_Change
              Debug "GetGadgetText(0)=" + GetGadgetText(0)
          EndSelect
      EndSelect
  EndSelect
  
Until q = 1
btw, the next requirement will be to make the call to AddItem recursive to handle multiple directory levels ;-)
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Add libraries (eg Music) to ExplorerTreeGadget?

Post by RASHAD »

Step forward

Code: Select all

#TVGN_LASTVISIBLE = 10
#TVM_MAPHTREEITEMTOACCID = #TV_FIRST + 43

Global tvi.TVITEM,lpis.TV_INSERTSTRUCT,Buffer$,item

tvi\mask = #TVIF_TEXT
buffer$ = Space(#MAX_PATH)
tvi\pszText = @buffer$
tvi\cchTextMax = #MAX_PATH

Structure indexinf
  index.l
  text.s
EndStructure

Global Dim Myindex.indexinf(10)

Procedure AddItem(gadget.l, position.l, text.s,dir.s, flag.l)
  hRoot = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_LASTVISIBLE, 0) 
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hRoot)
  lpis\hInsertAfter = hRoot
  lpis\item\mask =  #TVIF_TEXT | #TVIF_CHILDREN
  lpis\item\cchTextMax = Len(text)
  lpis\item\cChildren = 1
  lpis\item\pszText = @text
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
  Index = SendMessage_(GadgetID(0), #TVM_MAPHTREEITEMTOACCID,lpis\hParent, 0)
  Myindex(item)\index = index
  Myindex(item)\text = dir
  item+1
  ExamineDirectory(0, dir,"*.*")
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
      text = DirectoryEntryName(0)
      Select text
        Case ".", ".."
          ; ignore
        Default
          lpis\item\cchTextMax = Len(text)
          lpis\item\pszText = @text
          HTREEITEM = SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
          SubIndex = SendMessage_(GadgetID(0), #TVM_MAPHTREEITEMTOACCID,HTREEITEM, 0)
          Myindex(item)\index = subindex
          Myindex(item)\text = text
          item+1
      EndSelect
    EndIf
  Wend
EndProcedure

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester|#PB_Explorer_NoFiles)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
If OSVersion() >= #PB_OS_Windows_10
  AddItem(0,0,"My Music","C:\Users\Public\Music",0)
  AddItem(0,0,"My Pictures","C:\Users\Public\Pictures",1)
  AddItem(0,0,"My Videos","C:\Users\Public\Videos",2)
EndIf   

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      q = 1         
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_Change            
              tvi\hItem = SendMessage_(GadgetID(0), #TVM_GETNEXTITEM, #TVGN_CARET, 0)
              hindex = SendMessage_(GadgetID(0), #TVM_MAPHTREEITEMTOACCID,tvi\hItem, 0)
              For i = 0 To item
                If Myindex(i)\index = hindex
                  Debug Myindex(i)\index
                  Debug Myindex(i)\text
                  Break
                EndIf
              Next              
          EndSelect
      EndSelect
  EndSelect
 
Until q = 1
Edit :Modified for better looking
Edit #2:More progress
Egypt my love
ozzie
Enthusiast
Enthusiast
Posts: 429
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: Add libraries (eg Music) to ExplorerTreeGadget?

Post by ozzie »

Many thanks for your help, RASHAD. I've back-tracked a bit and removed the requirement to display the sub-directories, and I'll explain why. When including the sub-directories, if I click on a sub-directory of, say, the Music library, the text returned on the 'change' event type only returns that sub-directory name, not the full path name, and I obviously don't want to display the full path name in every sub-directory entry in the tree.

By removing the display of any sub-directories from these extra entries I'm adding, I now treat these entries as shortcuts to the main tree. So in the code below, if the user clicks on the Music entry the 'change' event type will reset the tree to the actual 'Music' entry in the initial ExplorerTreeGadget list.

Here's the code, which provides the functionality I need:

Code: Select all

#TVGN_LASTVISIBLE = 10
Global tvi.TVITEM,lpis.TV_INSERTSTRUCT,buffer$

tvi\mask = #TVIF_TEXT
buffer$ = Space(#MAX_PATH)
tvi\pszText = @buffer$
tvi\cchTextMax = #MAX_PATH

Procedure AddItem(gadget.l, text.s)
  hRoot = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_LASTVISIBLE, 0)  
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_GETNEXTITEM, #TVGN_PARENT, hRoot)
  lpis\hInsertAfter = hRoot
  lpis\item\mask =  #TVIF_TEXT
  lpis\item\cchTextMax = Len(text)
  lpis\item\pszText = @text
  lpis\hParent = SendMessage_(GadgetID(gadget), #TVM_INSERTITEM, 0, @lpis)
EndProcedure

OpenWindow(0, 0, 0, 300, 350, "ExplorerTreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ExplorerTreeGadget(0, 10, 10, 280, 280, "*.*", #PB_Explorer_NoDriveRequester|#PB_Explorer_NoFiles)
SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #TVS_CHECKBOXES|#TVS_TRACKSELECT)
If OSVersion() >= #PB_OS_Windows_10
  AddItem(0,"C:\Users\Public\Music")
  AddItem(0,"C:\Users\Public\Pictures")
  AddItem(0,"C:\Users\Public\Videos")
EndIf   

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      q = 1         
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Select EventType()
            Case #PB_EventType_Change
              DirName$ = GetGadgetText(0)
              If FileSize(DirName$) = -1
                tvi\hItem = SendMessage_(GadgetID(0), #TVM_GETNEXTITEM, #TVGN_CARET, 0)
                SendMessage_(GadgetID(0), #TVM_GETITEM, 0, tvi)
                DirName$ = Trim(buffer$) + "\"
                SetGadgetText(0, DirName$)
              EndIf
              Debug DirName$
          EndSelect
      EndSelect
  EndSelect
 
Until q = 1
Edit: Removed position and flag from AddItem as they are no longer needed
Post Reply