Page 1 of 2

how enumerate all desktop icons (name/label) ?

Posted: Sun Nov 07, 2004 12:40 pm
by bingo
first:

Code: Select all

#LVM_GETTITEMCOUNT = $1000 + 4

hDesktop=GetDesktopWindow_();
hDesktop=FindWindowEx_(hDesktop, 0, "Progman", "Program Manager");
hDesktop=FindWindowEx_(hDesktop, 0, "SHELLDLL_DefView", 0);
hDesktop=FindWindowEx_(hDesktop, 0, "SysListView32", 0);
 
Debug SendMessage_(hDesktop, #LVM_GETTITEMCOUNT, 0, 0) ;count desktop icons
second: :?:

lvi.LV_ITEM
lvi\iSubItem
lvi\pszText
lvi\cchTextMax
lvi\mask = #LVIF_TEXT

SendMessage_(hDesktop, #LVM_GETITEMTEXT, iconindex, @lvi)

VirtualAllocEx ...

Posted: Tue Nov 09, 2004 5:35 pm
by ebs
For Windows NT/2000/XP.

Regards,
Eric

Code: Select all

#PROCESS_VM_OPERATION = $8
#PROCESS_VM_READ = $10
#PROCESS_VM_WRITE = $20
#PROCESS_QUERY_INFORMATION = $400
#PROCESS_VM = #PROCESS_VM_OPERATION|#PROCESS_VM_READ|#PROCESS_VM_WRITE|#PROCESS_QUERY_INFORMATION

#MEM_COMMIT = $1000
#PAGE_READWRITE  = $4
   
#MAX_PATH = 260

; get handle to listview with desktop icons
hDesktop.l = FindWindow_("ProgMan", 0)
hDesktop = GetWindow_(hDesktop, #GW_CHILD)
hDesktop = GetWindow_(hDesktop, #GW_CHILD)

; get explorer process
GetWindowThreadProcessId_(hDesktop, @explorer_pid.l)
hExplorer.l = OpenProcess_(#PROCESS_VM, #False, explorer_pid)
; allocate memory in explorer process for LV_ITEM structure and icon name buffer
ipc_lvi.l = VirtualAllocEx_(hExplorer, 0, SizeOf(LV_ITEM), #MEM_COMMIT, #PAGE_READWRITE)
ipc_buffer.l = VirtualAllocEx_(hExplorer, 0, #MAX_PATH, #MEM_COMMIT, #PAGE_READWRITE)

; set up LV_ITEM structure
lvi.LV_ITEM
lvi\iSubItem = 0
lvi\pszText = ipc_buffer
lvi\cchTextMax = #MAX_PATH
lvi\mask = #LVIF_TEXT
; copy LV_ITEM structure to explorer process
WriteProcessMemory_(hExplorer, ipc_lvi, lvi, SizeOf(LV_ITEM), 0)

; allocate string for icon name
Name.s = Space(#MAX_PATH)

; count desktop icons
NumIcons.l = SendMessage_(hDesktop, #LVM_GETITEMCOUNT, 0, 0) ;count desktop icons 
Debug NumIcons

; get icon names
For Icon.l = 0 To NumIcons-1  
  ; get icon name
  SendMessage_(hDesktop, #LVM_GETITEMTEXT, Icon, ipc_lvi) 
  ; read icon name from explorer process
  ReadProcessMemory_(hExplorer, ipc_buffer, @Name, #MAX_PATH, 0)
  Debug Name
Next

; clean up - free memory in explorer process and close handle
VirtualFreeEx_(hExplorer, ipc_lvi, 0, #MEM_RELEASE)
VirtualFreeEx_(hExplorer, ipc_buffer, 0, #MEM_RELEASE)
CloseHandle_(hExplorer)

Posted: Wed Nov 10, 2004 7:58 am
by bingo
thanks :lol:

Posted: Fri Sep 02, 2005 7:16 am
by ricardo
Just curiosity:

How does some app do to show/hide only SOME of the desktop icons?

I think they move it out of the screen, because if i rearrange it with righclick on desktop and choose to snap to the grid, they appear again.

Re: how enumerate all desktop icons (name/label) ?

Posted: Sun Dec 05, 2010 11:22 pm
by IdeasVacuum
Without any firm understanding of what the hell I'm doing, I copied this code and successfully butchered it to additionally return the position of each item on the Desktop (top left coordinates of each icon). That's great, but what I cannot do is to get the index number of each item (to later restore/move/delete icons).

Code: Select all

#PROCESS_VM_OPERATION = $8
#PROCESS_VM_READ = $10
#PROCESS_VM_WRITE = $20
#PROCESS_QUERY_INFORMATION = $400
#PROCESS_VM = #PROCESS_VM_OPERATION|#PROCESS_VM_READ|#PROCESS_VM_WRITE|#PROCESS_QUERY_INFORMATION
#MEM_COMMIT = $1000
#PAGE_READWRITE  = $4
#MAX_PATH = 260

Enumeration
#IconsFile
#iSaveIcons
#iRestoreIcons
EndEnumeration

Structure ItemIndex
Index.l
EndStructure

     sExeFullPath.s = ProgramFilename()
            sPath.s = GetPathPart(sExeFullPath)
Global sIconsFile.s = sPath + "Icons.txt"

Procedure SaveDesktopIcons()
;---------------------------

      ; Desktop is a ListView. Get handle
      hDesktop.l = FindWindow_("ProgMan", 0)
        hDesktop = GetWindow_(hDesktop, #GW_CHILD)
        hDesktop = GetWindow_(hDesktop, #GW_CHILD) ;must be repeated
     sIconName.s = Space(#MAX_PATH)

      ; get explorer process
      GetWindowThreadProcessId_(hDesktop, @explorer_pid.l)
       hExplorer.l = OpenProcess_(#PROCESS_VM, #False, explorer_pid)
      
      ; allocate memory in explorer process for LV_ITEM structure and icon name buffer
         ipc_lvi.l = VirtualAllocEx_(hExplorer, 0, SizeOf(LVITEM), #MEM_COMMIT, #PAGE_READWRITE)
      ipc_buffer.l = VirtualAllocEx_(hExplorer, 0, #MAX_PATH, #MEM_COMMIT, #PAGE_READWRITE)
      
      ; allocate memory in explorer process for POINT structure
             vPt.l = VirtualAllocEx_(hExplorer, 0, SizeOf(POINT), #MEM_COMMIT, #PAGE_READWRITE)
      
      ; allocate memory in explorer process for Index
              Id.l = VirtualAllocEx_(hExplorer, 0, SizeOf(ItemIndex), #MEM_COMMIT, #PAGE_READWRITE)
      
      ; LVITEM structure
      lvi.LVITEM
        lvi\iSubItem = 0
         lvi\pszText = ipc_buffer
      lvi\cchTextMax = #MAX_PATH
            lvi\mask = #LVIF_TEXT
      
      ; Point Structure
      Pt.POINT

      ; Index
      Idx.ItemIndex

      ; copy LV_ITEM structure to explorer process
      WriteProcessMemory_(hExplorer, ipc_lvi, lvi, SizeOf(LVITEM), 0)
      
      ; copy POINT structure to explorer process
      WriteProcessMemory_(hExplorer, vPt, Pt, SizeOf(POINT), 0)
      
      ; copy ItemIdx to explorer process
      WriteProcessMemory_(hExplorer, Id, Idx, SizeOf(ItemIndex), 0)

      ; count desktop items (icons)
             iTotalItems.l = SendMessage_(hDesktop, #LVM_GETITEMCOUNT, 0, 0)
                    iCnt.i = 0
               sIconInfo.s = Space(#MAX_PATH)
      
      If CreateFile(#IconsFile,sIconsFile)
      
            ; get info for each item (icon)
            For iCnt = 0 To (iTotalItems - 1)
            
                 ; get item index
                   SendMessage_(hDesktop, #LVM_GETNEXTITEM, iCnt, #LVNI_ALL)
                   ReadProcessMemory_(hExplorer, Id, @Idx, SizeOf(ItemIndex), 0)
            
                 ; get item name
                   SendMessage_(hDesktop, #LVM_GETITEMTEXT, iCnt, ipc_lvi)
                   ReadProcessMemory_(hExplorer, ipc_buffer, @sIconName, #MAX_PATH, 0)
            
                 ; get item location
                   SendMessage_(hDesktop, #LVM_GETITEMPOSITION, iCnt, vPt)
                   ReadProcessMemory_(hExplorer, vPt, @Pt, SizeOf(POINT), 0)
            
                   sIconInfo = sIconName + "," + Str(Idx\Index) + "," + Str(Pt\x) + "," + Str(Pt\y)
                   WriteStringN(#IconsFile,sIconInfo,#PB_UTF8)
            
            Next iCnt
      
            CloseFile(#IconsFile)
      
      EndIf
      
      ; clean up - free memory in explorer process and close handle
      VirtualFreeEx_(hExplorer, ipc_lvi, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, ipc_buffer, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, vPt, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, Id, 0, #MEM_RELEASE)
      CloseHandle_(hExplorer)

EndProcedure

SaveDesktopIcons()
Can one of the API experts put me out of my misery please?

Re: how enumerate all desktop icons (name/label) ?

Posted: Wed Dec 08, 2010 2:39 am
by IdeasVacuum
Another attempt, which tries to follow the logic used to collect the icon text. Doesn't crash, but does not collect the index number either :shock:

Code: Select all

#PROCESS_VM_OPERATION = $8
#PROCESS_VM_READ = $10
#PROCESS_VM_WRITE = $20
#PROCESS_QUERY_INFORMATION = $400
#PROCESS_VM = #PROCESS_VM_OPERATION|#PROCESS_VM_READ|#PROCESS_VM_WRITE|#PROCESS_QUERY_INFORMATION
#MEM_COMMIT = $1000
#PAGE_READWRITE  = $4
#MAX_PATH = 260

Enumeration
#IconsFile
#iSaveIcons
#iRestoreIcons
EndEnumeration

     sExeFullPath.s = ProgramFilename()
            sPath.s = GetPathPart(sExeFullPath)
Global sIconsFile.s = sPath + "Icons.txt"

Procedure SaveDesktopIcons()
;---------------------------

      ; Desktop is a ListView. Get handle
      hDesktop.l = FindWindow_("ProgMan", 0)
        hDesktop = GetWindow_(hDesktop, #GW_CHILD)
        hDesktop = GetWindow_(hDesktop, #GW_CHILD) ;must be repeated
     sIconName.s = Space(#MAX_PATH)
       IconIdx.l = 0

      ; get explorer process
      GetWindowThreadProcessId_(hDesktop, @explorer_pid.l)
       hExplorer.l = OpenProcess_(#PROCESS_VM, #False, explorer_pid)
      
      ; allocate memory in explorer process for LV_ITEM structure and icon name buffer
        ipc_name.l = VirtualAllocEx_(hExplorer, 0, SizeOf(LVITEM), #MEM_COMMIT, #PAGE_READWRITE)
      ipc_buffer.l = VirtualAllocEx_(hExplorer, 0, #MAX_PATH, #MEM_COMMIT, #PAGE_READWRITE)
      
      ; allocate memory in explorer process for POINT structure
             vPt.l = VirtualAllocEx_(hExplorer, 0, SizeOf(POINT), #MEM_COMMIT, #PAGE_READWRITE)
      
      ; allocate memory in explorer process for Index
          id_Idx.l = VirtualAllocEx_(hExplorer, 0, SizeOf(LVITEM), #MEM_COMMIT, #PAGE_READWRITE)
       id_buffer.l = VirtualAllocEx_(hExplorer, 0, SizeOf(IconIdx), #MEM_COMMIT, #PAGE_READWRITE)
      
      ; name LVITEM structure
      name.LVITEM
        name\iSubItem = 0
         name\pszText = ipc_buffer
      name\cchTextMax = #MAX_PATH
            name\mask = #LVIF_TEXT
      
      ; Point Structure
      Pt.POINT

      ; Index LVITEM structure
      Idx.LVITEM
          Idx\lparam = id_buffer
        Idx\iSubItem = 0
            Idx\mask = #LVIF_PARAM

      ; copy name LV_ITEM structure to explorer process
      WriteProcessMemory_(hExplorer, ipc_name, name, SizeOf(LVITEM), 0)
      
      ; copy POINT structure to explorer process
      WriteProcessMemory_(hExplorer, vPt, Pt, SizeOf(POINT), 0)
      
      ; copy Index LV_ITEM structure to explorer process
      WriteProcessMemory_(hExplorer, id_Idx, Idx, SizeOf(LVITEM), 0)

      ; count desktop items (icons)
             iTotalItems.l = SendMessage_(hDesktop, #LVM_GETITEMCOUNT, 0, 0)
                    iCnt.i = 0
               sIconInfo.s = Space(#MAX_PATH)
      
      If CreateFile(#IconsFile,sIconsFile)
      
            ; get info for each item (icon)
            For iCnt = 0 To (iTotalItems - 1)
            
                 ; get item index
                   SendMessage_(hDesktop, #LVM_GETITEM, iCnt, id_Idx)
                   ReadProcessMemory_(hExplorer, id_buffer, @IconIdx, SizeOf(IconIdx), 0)
            
                 ; get item name
                   SendMessage_(hDesktop, #LVM_GETITEMTEXT, iCnt, ipc_name)
                   ReadProcessMemory_(hExplorer, ipc_buffer, @sIconName, #MAX_PATH, 0)
            
                 ; get item location
                   SendMessage_(hDesktop, #LVM_GETITEMPOSITION, iCnt, vPt)
                   ReadProcessMemory_(hExplorer, vPt, @Pt, SizeOf(POINT), 0)
  
                   sIconInfo = sIconName + "," + Str(IconIdx) + "," + Str(Pt\x) + "," + Str(Pt\y)
                   WriteStringN(#IconsFile,sIconInfo,#PB_UTF8)
            
            Next iCnt
      
            CloseFile(#IconsFile)
      
      EndIf
      
      ; clean up - free memory in explorer process and close handle
      VirtualFreeEx_(hExplorer, ipc_name, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, ipc_buffer, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, vPt, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, id_Idx, 0, #MEM_RELEASE)
      VirtualFreeEx_(hExplorer, id_buffer, 0, #MEM_RELEASE)
      CloseHandle_(hExplorer)

EndProcedure

Re: how enumerate all desktop icons (name/label) ?

Posted: Fri Jan 21, 2011 4:21 am
by IdeasVacuum
Nobody knows how to do this? :cry:

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Jan 31, 2011 4:00 am
by idle
you already have it, it's iCnt

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Jan 31, 2011 5:01 am
by idle
Save and restore Icon positions
cobbled together from an example eesau did in reply to a kcc question

Code: Select all

EnableExplicit
Structure DeskInfo
  sz.i
  name.s
  pt.point
EndStructure 

Global Dim GlobalDeskinfo.DeskInfo(0)
Global Explorer 
Global GlobalLVItem 
Global GlobalBuffer

Procedure DesktopHandle()
  Static Desktop 
  If Not Desktop 
   Desktop = FindWindow_("ProgMan",#Null)
   Desktop = GetWindow_ (Desktop,#GW_CHILD)
   Desktop = GetWindow_ (Desktop,#GW_CHILD)
  EndIf  
  ProcedureReturn Desktop
EndProcedure

Procedure DesktopProcessOpen()
   Protected ExplorerID
   Protected Flags = #PROCESS_VM_OPERATION | #PROCESS_VM_READ | #PROCESS_VM_WRITE | #PROCESS_QUERY_INFORMATION
   
   GetWindowThreadProcessId_(DesktopHandle(),@ExplorerID)
   Explorer = OpenProcess_(Flags,#Null,ExplorerID)
   GlobalLVItem = VirtualAllocEx_(Explorer,#Null,SizeOf(LV_ITEM),#MEM_COMMIT,#PAGE_READWRITE )
   GlobalBuffer = VirtualAllocEx_(Explorer,#Null,#MAX_PATH,#MEM_COMMIT,#PAGE_READWRITE)

   Protected Item.LV_ITEM
   With Item
      \mask       = #LVIF_TEXT
      \iSubItem   = 0
      \pszText    = GlobalBuffer
      \cchTextMax = #MAX_PATH
   EndWith
   
   WriteProcessMemory_(Explorer,GlobalLVItem,Item,SizeOf(LV_ITEM),#Null)

EndProcedure

Procedure DesktopProcessClose ( )
   VirtualFreeEx_(Explorer,GlobalLVItem,#Null,#MEM_RELEASE)
   VirtualFreeEx_(Explorer,GlobalBuffer,#Null,#MEM_RELEASE)
   CloseHandle_(Explorer)
EndProcedure

Procedure DesktopIconCount ( )
   ProcedureReturn SendMessage_(DesktopHandle(),#LVM_GETITEMCOUNT,#Null,#Null)
EndProcedure

Procedure.s DesktopGetIconString(Index)
   Protected String$=Space(#MAX_PATH)

   SendMessage_(DesktopHandle(),#LVM_GETITEMTEXT,Index,GlobalLVItem)
   ReadProcessMemory_(Explorer,GlobalBuffer,@String$,#MAX_PATH,#Null)
   ProcedureReturn String$
   
EndProcedure

Procedure DesktopGetIconPosition(index,*pt.point)
   If SendMessage_(DesktopHandle(),#LVM_GETITEMPOSITION,index,GlobalLVItem )
      ReadProcessMemory_(Explorer,GlobalLVItem,*pt,SizeOf(Point),#Null)
      ProcedureReturn #True
   Else 
      ProcedureReturn #False
   EndIf   
EndProcedure

Procedure DesktopSetIconPos(Index,X,Y)
  ProcedureReturn SendMessage_(DesktopHandle(),#LVM_SETITEMPOSITION,Index,(Y<<16)|(X&$FFFF))
EndProcedure

Procedure SaveDesktopIconsPositions()
  
  Protected fn,Count,index,pt.point,name.s 
  
  fn = OpenFile(-1,"desk.bin")
  
  If fn 
    DesktopProcessOpen()
    Count = DesktopIconCount()
    ReDim GlobalDeskinfo.DeskInfo(count)
    
    WriteData(fn,@count,SizeOf(Integer)) 
    
    For index = 0 To Count - 1

     GlobalDeskinfo(index)\name = DesktopGetIconString(index)
     GlobalDeskinfo(index)\sz = Len(GlobalDeskinfo(index)\name) 
     
     If DesktopGetIconPosition(index,pt)
       GlobalDeskinfo(index)\pt\x = pt\x 
       GlobalDeskinfo(index)\pt\y = pt\y 
     EndIf   
     
     WriteData(fn,@GlobalDeskinfo(index)\sz,SizeOf(Integer))
     WriteData(fn,@GlobalDeskinfo(index)\name,GlobalDeskinfo(index)\sz)
     WriteData(fn,@GlobalDeskinfo(index)\pt,SizeOf(point))
   Next 
   CloseFile(fn)
  EndIf

  DesktopProcessClose()
EndProcedure 

Procedure RestoreDesktopIconsPositions()
  Protected count,*buf,name.s,len,pt.point,fn,index  
  *buf = AllocateMemory(#MAX_PATH) 
  count = ArraySize(GlobalDeskinfo())
  
  DesktopProcessOpen()
  If count > 0 
    For index = 0 To count 
      DesktopSetIconPos(index,GlobalDeskinfo(index)\pt\x,GlobalDeskinfo(index)\pt\y) 
    Next 
  Else 
    fn = ReadFile(-1,"desk.bin") 
    If fn 
      ReadData(fn,@count,SizeOf(Integer)) 
      If count > 0  
        For index = 0 To count 
          ReadData(fn,@len,SizeOf(Integer))
          ReadData(fn,*buf,len) 
          name = PeekS(*buf,len) 
          ReadData(fn,@PT,SizeOf(point)) 
          If DesktopGetIconString(index) = name 
            DesktopSetIconPos(index,pt\x,pt\y)
          EndIf 
        Next
      EndIf 
      CloseFile(fn)
    EndIf
  EndIf   
  DesktopProcessClose()
  FreeMemory(*buf) 
  
EndProcedure 

Define EV,EVG

OpenWindow(0,200,200,140,30,"desk Icons",#PB_Window_SystemMenu)

ButtonGadget(1,5,5,60,20,"save")
ButtonGadget(2,70,5,60,20,"restore") 

Repeat 
  EV = WaitWindowEvent()
  If EV 
    EVG = EventGadget() 
    If EVG = 1
      SaveDesktopIconsPositions()
    ElseIf EVG = 2 
      RestoreDesktopIconsPositions()
    EndIf 
  EndIf 
Until EV = #WM_CLOSE   


Re: how enumerate all desktop icons (name/label) ?

Posted: Tue Feb 01, 2011 3:04 pm
by akj
You may be interested in this 'Fences' program which helps to organise the desktop icons.
It is available in a free version and a slightly more comprehensive paid-for Pro version.

Author: Stardock Corporation

Downloaded: http://download.cnet.com/Fences/3000-20 ... 09535.html

Via: http://www.stardock.com/products/fences/

Fences organizes desktop icons into separate windows, either automatically or manually. Labeling these boxes helps keep programs, photos, files, and Web links together, or you might choose to group by project rather than by file type. Whatever your logic, you'll be able to drag and drop fences (and the shortcuts within them) anywhere on your desktop.

A fenced area can be moved, renamed, or deleted. (The items that were inside the fence remain on your desktop.) Double-click the desktop, and all your fences — plus any unfenced icons — disappear. (Desktop windows remain visible.) Double-click again, and everything comes back.

If you find the double-click-and-hide feature annoying, you can turn it off in Fences' configuration box. You can also control the look of the fences, back up your desktop layout (the backups are misleadingly called "snapshots"), and pick a standardized layout.

To create a fence, right-drag on the desktop.

Re: how enumerate all desktop icons (name/label) ?

Posted: Tue Feb 01, 2011 7:04 pm
by IdeasVacuum
Thank you for the info guys. As always, I am busy on several things right now but I'll get back onto this in a few days time. The 'Fences' app sounds very clever - I sort of have a poor man's version - my screen background image is divided-up with colour-coded rectangles.

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Feb 10, 2014 2:12 pm
by Thade
idle wrote:Save and restore Icon positions
cobbled together from an example eesau did in reply to a kcc question

Code: Select all

EnableExplicit
Structure DeskInfo
  sz.i
  name.s
  pt.point
EndStructure 

Global Dim GlobalDeskinfo.DeskInfo(0)
Global Explorer 
Global GlobalLVItem 
Global GlobalBuffer

Procedure DesktopHandle()
  Static Desktop 
  If Not Desktop 
   Desktop = FindWindow_("ProgMan",#Null)
   Desktop = GetWindow_ (Desktop,#GW_CHILD)
   Desktop = GetWindow_ (Desktop,#GW_CHILD)
  EndIf  
  ProcedureReturn Desktop
EndProcedure

Procedure DesktopProcessOpen()
   Protected ExplorerID
   Protected Flags = #PROCESS_VM_OPERATION | #PROCESS_VM_READ | #PROCESS_VM_WRITE | #PROCESS_QUERY_INFORMATION
   
   GetWindowThreadProcessId_(DesktopHandle(),@ExplorerID)
   Explorer = OpenProcess_(Flags,#Null,ExplorerID)
   GlobalLVItem = VirtualAllocEx_(Explorer,#Null,SizeOf(LV_ITEM),#MEM_COMMIT,#PAGE_READWRITE )
   GlobalBuffer = VirtualAllocEx_(Explorer,#Null,#MAX_PATH,#MEM_COMMIT,#PAGE_READWRITE)

   Protected Item.LV_ITEM
   With Item
      \mask       = #LVIF_TEXT
      \iSubItem   = 0
      \pszText    = GlobalBuffer
      \cchTextMax = #MAX_PATH
   EndWith
   
   WriteProcessMemory_(Explorer,GlobalLVItem,Item,SizeOf(LV_ITEM),#Null)

EndProcedure

Procedure DesktopProcessClose ( )
   VirtualFreeEx_(Explorer,GlobalLVItem,#Null,#MEM_RELEASE)
   VirtualFreeEx_(Explorer,GlobalBuffer,#Null,#MEM_RELEASE)
   CloseHandle_(Explorer)
EndProcedure

Procedure DesktopIconCount ( )
   ProcedureReturn SendMessage_(DesktopHandle(),#LVM_GETITEMCOUNT,#Null,#Null)
EndProcedure

Procedure.s DesktopGetIconString(Index)
   Protected String$=Space(#MAX_PATH)

   SendMessage_(DesktopHandle(),#LVM_GETITEMTEXT,Index,GlobalLVItem)
   ReadProcessMemory_(Explorer,GlobalBuffer,@String$,#MAX_PATH,#Null)
   ProcedureReturn String$
   
EndProcedure

Procedure DesktopGetIconPosition(index,*pt.point)
   If SendMessage_(DesktopHandle(),#LVM_GETITEMPOSITION,index,GlobalLVItem )
      ReadProcessMemory_(Explorer,GlobalLVItem,*pt,SizeOf(Point),#Null)
      ProcedureReturn #True
   Else 
      ProcedureReturn #False
   EndIf   
EndProcedure

Procedure DesktopSetIconPos(Index,X,Y)
  ProcedureReturn SendMessage_(DesktopHandle(),#LVM_SETITEMPOSITION,Index,(Y<<16)|(X&$FFFF))
EndProcedure

Procedure SaveDesktopIconsPositions()
  
  Protected fn,Count,index,pt.point,name.s 
  
  fn = OpenFile(-1,"desk.bin")
  
  If fn 
    DesktopProcessOpen()
    Count = DesktopIconCount()
    ReDim GlobalDeskinfo.DeskInfo(count)
    
    WriteData(fn,@count,SizeOf(Integer)) 
    
    For index = 0 To Count - 1

     GlobalDeskinfo(index)\name = DesktopGetIconString(index)
     GlobalDeskinfo(index)\sz = Len(GlobalDeskinfo(index)\name) 
     
     If DesktopGetIconPosition(index,pt)
       GlobalDeskinfo(index)\pt\x = pt\x 
       GlobalDeskinfo(index)\pt\y = pt\y 
     EndIf   
     
     WriteData(fn,@GlobalDeskinfo(index)\sz,SizeOf(Integer))
     WriteData(fn,@GlobalDeskinfo(index)\name,GlobalDeskinfo(index)\sz)
     WriteData(fn,@GlobalDeskinfo(index)\pt,SizeOf(point))
   Next 
   CloseFile(fn)
  EndIf

  DesktopProcessClose()
EndProcedure 

Procedure RestoreDesktopIconsPositions()
  Protected count,*buf,name.s,len,pt.point,fn,index  
  *buf = AllocateMemory(#MAX_PATH) 
  count = ArraySize(GlobalDeskinfo())
  
  DesktopProcessOpen()
  If count > 0 
    For index = 0 To count 
      DesktopSetIconPos(index,GlobalDeskinfo(index)\pt\x,GlobalDeskinfo(index)\pt\y) 
    Next 
  Else 
    fn = ReadFile(-1,"desk.bin") 
    If fn 
      ReadData(fn,@count,SizeOf(Integer)) 
      If count > 0  
        For index = 0 To count 
          ReadData(fn,@len,SizeOf(Integer))
          ReadData(fn,*buf,len) 
          name = PeekS(*buf,len) 
          ReadData(fn,@PT,SizeOf(point)) 
          If DesktopGetIconString(index) = name 
            DesktopSetIconPos(index,pt\x,pt\y)
          EndIf 
        Next
      EndIf 
      CloseFile(fn)
    EndIf
  EndIf   
  DesktopProcessClose()
  FreeMemory(*buf) 
  
EndProcedure 

Define EV,EVG

OpenWindow(0,200,200,140,30,"desk Icons",#PB_Window_SystemMenu)

ButtonGadget(1,5,5,60,20,"save")
ButtonGadget(2,70,5,60,20,"restore") 

Repeat 
  EV = WaitWindowEvent()
  If EV 
    EVG = EventGadget() 
    If EVG = 1
      SaveDesktopIconsPositions()
    ElseIf EVG = 2 
      RestoreDesktopIconsPositions()
    EndIf 
  EndIf 
Until EV = #WM_CLOSE   

This was working very well many years ever since it was kindly provided here.
I needed to restore a desktop an hour ago - but now it is not doing its job anymore. Does not restore and does not save desktops (Win7).
And I could not find out yet what the reason could be. Whether it is a change on my system or on any system ...

.

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Feb 10, 2014 4:38 pm
by Thunder93
Thade wrote:
idle wrote: This was working very well many years ever since it was kindly provided here.
I needed to restore a desktop an hour ago - but now it is not doing its job anymore. Does not restore and does not save desktops (Win7).
And I could not find out yet what the reason could be. Whether it is a change on my system or on any system ...

.
Still does. Just compile it without Unicode

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Feb 10, 2014 4:51 pm
by Thunder93
Line 93: change:

Code: Select all

GlobalDeskinfo(index)\sz = Len(GlobalDeskinfo(index)\name)
to

Code: Select all

GlobalDeskinfo(index)\sz = StringByteLength(GlobalDeskinfo(index)\name)

... should work.

Re: how enumerate all desktop icons (name/label) ?

Posted: Mon Feb 10, 2014 11:13 pm
by Thade
No, doesn't do it either.
It still produces a File which is 4 Bytes long and has an integer 0 as content.

It worked until 2014 01 21 - the File it produced was 11KB long
Next time I stored the Desktop was on 2014 01 25 and it stored the desktop as 4 Byte long File (did not recognise until today that I stored only unusable Files because I needed not to restore the Icons in its Positions until now)
And I cannot restore the Files from 2014 01 21 and before anymore. It just does nothing with the Icons at all.

I don't know which Programs I installed or deinstalled between those Dates, which updates were made.
I put this here only to have the chance to save some time. Maybe someone knows what could cause the error. Otherwise it may take me many hours to debug and check where the error is.
And of course: knowing that it is only on my system and not everywhere will help to locate the error.

Thanks for taking a look.

.