Page 1 of 5

[x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 09 May 2014, 21:18
by joedf
The function was created by Rapte_Of_Suzaku.
Function to save desktop icon positions and later restore them. Designed with DynamicDesktop in mind, but will work fine on its own.
Originally posted here: http://www.autohotkey.com/board/topic/6 ... positions/
The script has been updated to work with both x64 and x86.

Code: Select all

; "DeskIcons.ahk"
; Updated to be x86 and x64 compatible by Joe DF
; Revision Date : 22:13 2014/05/09
; From : Rapte_Of_Suzaku
; http://www.autohotkey.com/board/topic/60982-deskicons-getset-desktop-icon-positions/

/*
	Save and Load desktop icon positions
	based on save/load desktop icon positions by temp01 (http://www.autohotkey.com/forum/viewtopic.php?t=49714)
	
	Example:
		; save positions
		coords := DeskIcons()
		MsgBox now move the icons around yourself
		; load positions
		DeskIcons(coords)
	
	Plans:
		handle more settings (icon sizes, sort order, etc)
			- http://msdn.microsoft.com/en-us/library/ff485961%28v=VS.85%29.aspx
	
*/
DeskIcons(coords="")
{
	Critical
	static MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x04, MEM_RELEASE := 0x8000
	static LVM_GETITEMPOSITION := 0x00001010, LVM_SETITEMPOSITION := 0x0000100F, WM_SETREDRAW := 0x000B
	
	ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
	if !hwWindow ; #D mode
		ControlGet, hwWindow, HWND,, SysListView321, A
	IfWinExist ahk_id %hwWindow% ; last-found window set
		WinGet, iProcessID, PID
	hProcess := DllCall("OpenProcess"	, "UInt",	0x438			; PROCESS-OPERATION|READ|WRITE|QUERY_INFORMATION
										, "Int",	FALSE			; inherit = false
										, "ptr",	iProcessID)
	if hwWindow and hProcess
	{	
		ControlGet, list, list,Col1			
		if !coords
		{
			VarSetCapacity(iCoord, 8)
			pItemCoord := DllCall("VirtualAllocEx", "ptr", hProcess, "ptr", 0, "UInt", 8, "UInt", MEM_COMMIT, "UInt", PAGE_READWRITE)
			Loop, Parse, list, `n
			{
				SendMessage, %LVM_GETITEMPOSITION%, % A_Index-1, %pItemCoord%
				DllCall("ReadProcessMemory", "ptr", hProcess, "ptr", pItemCoord, "UInt", &iCoord, "UInt", 8, "UIntP", cbReadWritten)
				ret .= A_LoopField ":" (NumGet(iCoord,"Int") & 0xFFFF) | ((Numget(iCoord, 4,"Int") & 0xFFFF) << 16) "`n"
			}
			DllCall("VirtualFreeEx", "ptr", hProcess, "ptr", pItemCoord, "ptr", 0, "UInt", MEM_RELEASE)
		}
		else
		{
			SendMessage, %WM_SETREDRAW%,0,0
			Loop, Parse, list, `n
				If RegExMatch(coords,"\Q" A_LoopField "\E:\K.*",iCoord_new)
					SendMessage, %LVM_SETITEMPOSITION%, % A_Index-1, %iCoord_new%
			SendMessage, %WM_SETREDRAW%,1,0
			ret := true
		}
	}
	DllCall("CloseHandle", "ptr", hProcess)
	return ret
}
Cheers

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 10 May 2014, 11:25
by geek
The obvious next evolution
Image

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 10 May 2014, 12:12
by joedf
Lool!

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 04 Sep 2014, 05:05
by drabne
This function doesn't work for me in Win 8.1 x64

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 04 Sep 2014, 20:09
by joedf
Hmm, I'll try to fix it when I get back from my trip.
Regards, ;)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 07 Sep 2014, 11:13
by xZomBie
DeskIcons doesn't work for me either...

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 07 Sep 2014, 16:37
by joedf
And what is your system, xZombie? ;)
Will be fixed when I get back. :)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 08 Sep 2014, 06:57
by xZomBie
I was about to post it in there but then I realized it was already in my signature.
Anyways, I on Win7 64bit. The example script doesn't work.
BTW, there is a script made by the original creator of DeskIcons. DesktopHomes

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 16 Sep 2014, 11:50
by joedf
I just tested it. It works fine...
Try this ;)

Code: Select all

coords := DeskIcons()
MsgBox now move the icons around yourself, PRESS OK AFTER MOVING THE ICONS
MsgBox move the icons, then press OK, ok?
; load positions
DeskIcons(coords)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 16 Sep 2014, 19:04
by huyaowen
very good.
thanks

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 17 Sep 2014, 01:19
by joedf
No problem ;)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 17 Sep 2014, 11:01
by xZomBie
:wtf: It works now... :think: Don't know why it didn't the last time... :trollface:
Edit: Some Desktop.ini(Hidden files) are detected by DeskIcon and their icon locations are recorded. Is there a way to ignore those files?

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 17 Sep 2014, 12:10
by joedf
Try this?
IconPositions:=DeskIcons("","desktop.ini")

Code: Select all

DeskIcons(coords="",IgnorefilesCSV="")
{
    Critical
    static MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x04, MEM_RELEASE := 0x8000
    static LVM_GETITEMPOSITION := 0x00001010, LVM_SETITEMPOSITION := 0x0000100F, WM_SETREDRAW := 0x000B
   
    ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
    if !hwWindow ; #D mode
        ControlGet, hwWindow, HWND,, SysListView321, A
    IfWinExist ahk_id %hwWindow% ; last-found window set
        WinGet, iProcessID, PID
    hProcess := DllCall("OpenProcess"   , "UInt",   0x438           ; PROCESS-OPERATION|READ|WRITE|QUERY_INFORMATION
                                        , "Int",    FALSE           ; inherit = false
                                        , "ptr",    iProcessID)
    if hwWindow and hProcess
    {  
        ControlGet, list, list,Col1        
        if !coords
        {
            VarSetCapacity(iCoord, 8)
            pItemCoord := DllCall("VirtualAllocEx", "ptr", hProcess, "ptr", 0, "UInt", 8, "UInt", MEM_COMMIT, "UInt", PAGE_READWRITE)
            Loop, Parse, list, `n
            {
                SendMessage, %LVM_GETITEMPOSITION%, % A_Index-1, %pItemCoord%
                DllCall("ReadProcessMemory", "ptr", hProcess, "ptr", pItemCoord, "UInt", &iCoord, "UInt", 8, "UIntP", cbReadWritten)
                ;###################################################
                if A_LoopField in %IgnorefilesCSV%
                    continue
                ;####################################################
                ret .= A_LoopField ":" (NumGet(iCoord,"Int") & 0xFFFF) | ((Numget(iCoord, 4,"Int") & 0xFFFF) << 16) "`n"
            }
            DllCall("VirtualFreeEx", "ptr", hProcess, "ptr", pItemCoord, "ptr", 0, "UInt", MEM_RELEASE)
        }
        else
        {
            SendMessage, %WM_SETREDRAW%,0,0
            Loop, Parse, list, `n
            {
                ;###################################################
                if A_LoopField in %IgnorefilesCSV%
                    continue
                ;####################################################                
                If RegExMatch(coords,"\Q" A_LoopField "\E:\K.*",iCoord_new)
                    SendMessage, %LVM_SETITEMPOSITION%, % A_Index-1, %iCoord_new%
            }
            SendMessage, %WM_SETREDRAW%,1,0
            ret := true
        }
    }
    DllCall("CloseHandle", "ptr", hProcess)
    return ret
}

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 23 Sep 2014, 10:05
by Relayer
Hi,

A natural extension of this would be to record / reset positions of icons in custom toolbars. I am not referring to application toolbars, but instead just the windows 7 toolbar facility that is part of the desktop / taskbar.

Windows keeps the icons in a folder for a particular toolbar but the folder does not reflect the position of each icon relative to the others once the toolbar is displayed.

Relayer

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positio

Posted: 23 Sep 2014, 17:46
by joedf
ill see what i can do. ;)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 09 Mar 2018, 17:06
by tempuser
I can't get consistent results from running this code.
Few times it works fine, but at some launch it stops run and this function returns empty value.
Windows 10 x64.

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 09 Mar 2018, 21:44
by joedf
Oh that’s weird... possibly broken by updates ... hmm :think:

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 09 Mar 2018, 21:48
by joedf
VirtualAllocEx or VirtualFreeEx
Might be the culprit...

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 10 Mar 2018, 13:35
by Guest_3102018
I am having the same issue. Windows 10 x64 FCU. Currently I have this script in a larger script which has #Warn enabled. As a result, when it's not working, I receive a couple errors. Both are variables without assigned values. The latter is probably caused by the former but that would be more your department ;-) Hopefully this is helpful. If you need any other info, just ask.

iProcessID in hProcess := DllCall("OpenProcess" , "UInt", 0x438, "Int", FALSE, "ptr", iProcessID)
ret in Return, ret after DllCall("CloseHandle", "ptr", hProcess)

Re: [x64 & x32 fix] DeskIcons - Get/Set Desktop Icon Positions

Posted: 10 Mar 2018, 15:11
by joedf
Are you saying OpenProcess is not working correctly either?