display icons in listview next to file name

Windows specific forum
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Denis.

Hi all,

the folowing code will create a listview To displays files And folder from Path : C:\Windows\
Next To the names, its displays icons system.
It displays the file size And the file date And time (local time).
Files and folders are in alphabetical order with folders before files.
I use the procedure SendItemsToSort() to resequence the items
I put this procedure once before the #LVM_SORTITEMS message and once right after. A this time, i don't understand why i have to rresquence twice. If you undertsant, please tell me.

This code is OK under Win98 SE

What about W2000, ME, NT, XP ?

Thanks For theses infos.


Code: Select all

; some options#OptionsMainWindow = #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MaximizeGadget
#OptionsListFiles = #PB_ListIcon_MultiSelect | #PB_ListIcon_FullRowSelect

; some constants
#LVM_GETBKCOLOR           = $1000
#LVM_SETBKCOLOR           = $1001
#LVM_SETITEM              = $1006
#LVM_INSERTITEM           = $1007
#LVM_GETITEMTEXT          = $102D
#LVM_SETTEXTBKCOLOR       = $1026
#LVM_SETIMAGELIST         = $1003
#LVM_SORTITEMS            = $1030
#LVM_SETCOLUMN            = $101A
#LVCF_FMT                 = 1
#LVCFMT_RIGHT             = 1
#LVIF_TEXT                = 1
#LVIF_IMAGE               = 2
#LVIF_PARAM               = 4
#LVSIL_SMALL              = 1
#SHGFI_SYSICONINDEX       = $4000
#SHGFI_SMALLICON          = 1
#SHGFI_TYPENAME           = $400
#SHGFI_ATTRIBUTES         = $800
#CLR_NONE                 = $FFFFFFFF
#WM_SETFONT               = $30
#WM_CLOSE                 = $10
#BackColorListIconGadget  = $F1FCE3
#INVALID_HANDLE_VALUE     = -1
#FILE_ATTRIBUTE_DIRECTORY = $10
#MAXDWORD                 = $FFFFFFFF
#TIME_FORCE24HOURFORMAT   = 8
#FILE_ATTRIBUTE_DIRECTORY = $10


; Gadgets Ids
#GADGET_Index                   = 0
#MainWindow                     = #GADGET_Index : #GADGET_Index = #GADGET_Index+1
#Menu                           = #GADGET_Index : #GADGET_Index = #GADGET_Index+1
#MENU_Quit                      = #GADGET_Index : #GADGET_Index = #GADGET_Index+1
#ListIconGadget1                = #GADGET_Index : #GADGET_Index = #GADGET_Index+1

Global HwndListView.l, MainWindowID.l
Global CurrentFolder.s
CurrentFolder =  "C:\Windows\"

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure DisplayMenu()
  If CreateMenu(#Menu,MainWindowID)

; ------------------------ File / Fichier --------------------------
     MenuTitle("File")
     MenuItem(#MENU_Quit         , "Quit")
  EndIf   
EndProcedure 

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure.s GetFileTimeAndDate(AddrFiletime.l)

; the the local time of last modification time file
; AddrFiletime is a pointer of a WIN32_FIND_DATA structure (current file)
   Date.s="dd'/'MM'/'yyyy"
   FileDateTime.s=""
   ReturnString.s=""
   *FileInfos.WIN32_FIND_DATA = AddrFiletime

   FileTimeToLocalFileTime_(*FileInfos\[url]mailto:ftLastWriteTime,@OutPut.l[/url])

   FileTimeToSystemTime_(@[url]mailto:OutPut,@OutPutSystemTime.SYSTEMTIME[/url])

   GetDateFormat_(2048,0,@OutPutSystemTime,@Date,@ReturnString ,254)

   GetTimeFormat_(2048, #TIME_FORCE24HOURFORMAT ,@OutPutSystemTime,0,@FileDateTime,254)

   ReturnString = ReturnString +"  "+FileDateTime

   ProcedureReturn ReturnString
  
EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure SortListView(lParam1.l,lParam2.l,lParamSort.l)

; sort item in alphabetical order and put folders before files

   String1.s= Space(256)  ; initialise string1 (do not remove!)
   String2.s= Space(256)  ; initialise string1 (do not remove;)
   
; get the first Item to compare (Name of file), name in String1
   Var.LV_ITEM\mask = #LVIF_TEXT
   Var\pszText       = @String1
   Var\cchTextMax    = 256
   Var\iSubItem      = 0
   SendMessage_(HwndListView, #LVM_GETITEMTEXT, lParam1, @Var)

; get the second Item to compare (Name of file), name in String2
   Var.LV_ITEM\mask = #LVIF_TEXT
   Var\pszText       = @String2
   Var\cchTextMax    = 256
   Var\iSubItem      = 1
   Var\iSubItem      = 0
   SendMessage_(HwndListView, #LVM_GETITEMTEXT, lParam2, @Var)

; first, we test if the item is a folder or a file
; if item1 = folder and item2 = file, item1 has to be put before
; if item1 = folder and item2 = folder, we must compare by alphabetical order
; if item1 = file and item2   = folder, item2 has to be put before
; if item1 = file and item2   = file, we must compare by alphabetical order

  string1 = currentfolder + string1
  string2 = currentfolder + string2
  
  File1 = (GetFileAttributes_(@string1) & #FILE_ATTRIBUTE_DIRECTORY) 
  File2 = (GetFileAttributes_(@string2) & #FILE_ATTRIBUTE_DIRECTORY) 
; use lstrcmpi API to compare strings
; If the function succeeds and the string pointed to by lpString1 is less
; than the string pointed to by lpString2, the return value is negative;
; if the string pointed to by lpString1 is greater than the string pointed
; to by lpString2, it is positive. If the strings are equal, the return value is zero. 

  If (File1 And File2) Or ((File1  #FILE_ATTRIBUTE_DIRECTORY) And File2  #FILE_ATTRIBUTE_DIRECTORY)
     result = lstrcmpi_(@string1, @string2)
  ElseIf (File1 And (File2  #FILE_ATTRIBUTE_DIRECTORY))  ; item1 has to be before item2
     result = -1
  Else           ; item2 has to be before item1
     result = 1
  EndIf 
   ProcedureReturn result

EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure SendItemsToSort()

  NbItem = CountGadgetItems(#ListIconGadget1)
  Var.LV_ITEM\mask = #LVIF_PARAM
  Var\iSubItem = 0
  Var\iItem = 0
  
  While NbItem
    Var\lParam = Var\iItem
    SendMessage_(HwndListView,#LVM_SETITEM, 0, @Var)
    INC Var\iItem
    DEC NbItem
  Wend

EndProcedure 

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure ReadFiles()

; use Win API FindFirstFile and FindNextFile in a WHile Loop to read content of current folder
; use #LVM_INSERTITEM message to insert First Item (Name)
; use #LVM_SETITEM message to insert other text inside columns. DO not use with first column
  VarList.LV_ITEM\mask = #LVIF_TEXT | #LVIF_IMAGE | #LVIF_PARAM
  VarList\iItem = 0
  VarList\lParam = 0
  VarList\iSubItem = 0

  String1.s = CurrentFolder + "*.*"
  FirstHwnd = FindFirstFile_(@String1, @FileInfos.WIN32_FIND_DATA)
  NextFileExist = FirstHwnd
  
     If FirstHwnd  #INVALID_HANDLE_VALUE
        VarList\lParam = 0
        VarList\iItem  = 0
        While NextFileExist
           String2.s = PeekS(@FileInfos\cFileName[0])  ; entry name
           If String2  "."            
              VarList\mask = #LVIF_TEXT | #LVIF_IMAGE | #LVIF_PARAM ;| #SHGFI_PIDL 
              VarList\pszText = @FileInfos\cFileName[0]
              VarList\iSubItem = 0

;;---------- Get index of the icon within the system image list -------------------

              If String2 = ".."
                 FirstDirectory.b = 1
                 VarList\iImage = 3
              Else
                 FirstDirectory = 0
                 SHGetFileInfo_(CurrentFolder + String2, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX |#SHGFI_SMALLICON | #SHGFI_TYPENAME | #SHGFI_ATTRIBUTES)
                 VarList\iImage = InfosFile\iIcon
              EndIf  
              
;;---------- Display the item with icon ----------

              SendMessage_(HwndListView, #LVM_INSERTITEM, 0, @VarList)
              INC VarList\lParam   ; INC VarList\lParam = VarList\lParam + 1
        
              If FirstDirectory = 0
              
;;---------- Get and Display the file size ----------

                 VarList.LV_ITEM\mask = #LVIF_TEXT
                 VarList\iSubItem = 1  ; column 2
                 If ((FileInfos\dwFileAttributes & #FILE_ATTRIBUTE_DIRECTORY)  #FILE_ATTRIBUTE_DIRECTORY)
                    String1.s = Str(((#MAXDWORD*FileInfos\nFileSizeHigh)+FileInfos\nFileSizeLow))
                 Else 
                    String1 = ""  ; it's a directory
                 EndIf
                 VarList\pszText = @String1
                 SendMessage_(HwndListView, #LVM_SETITEM, 0, @VarList)

;;---------- Get and Display the File time ----------
   
                 VarList\iSubItem = 2; column 3  
                 String1 = GetFileTimeAndDate(@FileInfos\dwFileAttributes)
                 VarList\pszText = @String1
                 SendMessage_(HwndListView, #LVM_SETITEM, 0, @VarList)

             EndIf

           EndIf

           NextFileExist = FindNextFile_(FirstHwnd,@FileInfos)  

        Wend
        FindClose_(FirstHwnd)
  EndIf ; FirstHwnd  #INVALID_HANDLE_VALUE

EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure SetTextColumn2ToRight()

; set text of column 2 (size of file) to the right
  Column2 = 1
  ; align text of second column to the right side
  NewItem.LV_COLUMN\imask=#LVCF_FMT 
  NewItem\fmt = #LVCFMT_RIGHT 
  SendMessage_(HwndListView, #LVM_SETCOLUMN,Column2,@NewItem\imask)

EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure CreateImageList()

; create the image list and assign it to listview with #LVM_SETIMAGELIST message
   hImageListS.l = SHGetFileInfo_(CurrentFolder, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_SMALLICON)
   ImageList_SetBkColor_(hImageListS,#CLR_NONE)

   SendMessage_(HwndListView, #LVM_SETIMAGELIST, #LVSIL_SMALL, hImageListS)
     
EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure CreateDisplayListIconGadget()

; create the list view (3 columns, Name, Size and Date)
; Call procedure CreateImageList() to assign listview system to the listview
; You do not to use deleteObject API with the imageList to destroy it !

   HwndListView = ListIconGadget(#ListIconGadget1,0,45,594,494,"Name", 200 ,#OptionsListFiles) 
   If HwndListView
      If FontListID
         SendMessage_(HwndListView, #WM_SETFONT,FontListID,0)
      EndIf

      SendMessage_(HwndListView,#LVM_SETBKCOLOR,0,#BackColorListIconGadget)
      SendMessage_(HwndListView,#LVM_SETTEXTBKCOLOR,0,#BackColorListIconGadget)

      AddGadgetColumn(#ListIconGadget1, 1, "Size",80)
      AddGadgetColumn(#ListIconGadget1, 2, "Date and time (last modification)",320)

      CreateImageList()
   EndIf

EndProcedure

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////

Procedure Events()
  Repeat
     Select WaitWindowEvent()
       Case  #PB_Event_Menu
             Select EventGadgetID()

                Case #MENU_Quit
                  Quit = 1

             EndSelect 

       Case #WM_CLOSE
         Quit = 1
     EndSelect
  Until Quit = 1
EndProcedure 

;;//////////////////////////////////////////////////////////////////
;;//////////////////////////////////////////////////////////////////


;Main program

If OpenWindow(#MainWindow,100,100,600,500,#OptionsMainWindow," ListView Try with System Icons") 
   MainWindowID = WindowID(#MainWindow)
   If CreateGadgetList(MainWindowID)
      DisplayMenu()                 ; create and display menu
      CreateDisplayListIconGadget() ; the listview
      TextGadget(1000, 60, 10, 200, 20, "  Content of Folder :   "+ CurrentFolder,#PB_Text_Border ) 
      SetTextColumn2ToRight()
      ReadFiles()
      SendItemsToSort()
      SendMessage_(HwndListView,#LVM_SORTITEMS,0,@SortListView())
      SendItemsToSort()

      Events()
   EndIf ; creatGadgetList
EndIf ; (Mainwindow)

End


Hope it will help you


Denis
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Andre.

Have compiled the example here with PB 3.51 on Win XP SP1. It closes immediately after opening the window and displaying a text gadget (its closes too fast, to see exactly the content)...

Regards
André

*** German PureBasic Support ***
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Denis.

Hi André,

i don't know why it close immediatly, the events loop is very short and it should be waiting for eventmenu #MENU_Quit or event #WM_CLOSE.
It don't close under Win98 SE.

Certainly a pb inside the events loops.

May be a pb with #WM_CLOSE (?) or i have to put quit to 0 before loop event (?)

André, Is it possible to try with :

1) remove #WM_CLOSE of the events loop

2) set quit to 0 before calling procedure event()


Thanks.


Denis
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Denis.

just 2 Things :

This code is a piece of a more bigger one i writted.

I cleared it to send it here, but there are at least 2 mistakes :

- There is not created font, but in my code i use one. No troubles because it's inside an if.

- inside SortListView procedure, when i get string2 (2nd item), i put Var\iSubItem to 1 then immediatly after to 0. You have to delete 'Var\iSubItem = 1'

; get the second Item to compare (Name of file), name in String2
Var.LV_ITEM\mask = #LVIF_TEXT
Var\pszText = @String2
Var\cchTextMax = 256
Var\iSubItem = 1 <-- to delete
Var\iSubItem = 0
SendMessage_(HwndListView, #LVM_GETITEMTEXT, lParam2, @Var)



Denis
Post Reply