how enumerate all desktop icons (name/label) ?

Everything else that doesn't fall into one of the other PB categories.
User avatar
bingo
Enthusiast
Enthusiast
Posts: 210
Joined: Fri Apr 02, 2004 12:21 pm
Location: germany/thueringen
Contact:

how enumerate all desktop icons (name/label) ?

Post 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 ...
["1:0>1"]
ebs
Enthusiast
Enthusiast
Posts: 557
Joined: Fri Apr 25, 2003 11:08 pm

Post 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)
User avatar
bingo
Enthusiast
Enthusiast
Posts: 210
Joined: Fri Apr 02, 2004 12:21 pm
Location: germany/thueringen
Contact:

Post by bingo »

thanks :lol:
["1:0>1"]
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post 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.
ARGENTINA WORLD CHAMPION
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post by IdeasVacuum »

Nobody knows how to do this? :cry:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
idle
Always Here
Always Here
Posts: 5844
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

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

Post by idle »

you already have it, it's iCnt
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
idle
Always Here
Always Here
Posts: 5844
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

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

Post 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   

Windows 11, Manjaro, Raspberry Pi OS
Image
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

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

Post 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.
Anthony Jordan
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

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

Post 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.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

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

Post 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 ...

.
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

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

Post 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
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

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

Post 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.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

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

Post 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.

.
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
Post Reply