Jump to content

Desktop icons save and restore


ioa747
 Share

Recommended Posts

Saves the position of the icons, from the desktop, with the ability of restoring

With command line parameters  -save , it save the icons setting,   with  -restore , it restore the icons setting.
Without  command line parameters display a GUI with  save , restore buttons

DesktopIconSet.au3

; https://www.autoitscript.com/forum/topic/210688-desktop-icons-save-and-restore/
;----------------------------------------------------------------------------------------
; Title...........: DesktopIconSet.au3
; Description.....: Saves the position of the icons, from the desktop, with the ability of restoring 
; AutoIt Version..: 3.3.16.1   Author: ioa747
; Notes ..........: Tested on Windows 10 Version 22H2
;----------------------------------------------------------------------------------------
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#AutoIt3Wrapper_UseX64=y

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global Const $g_sIniPath = @ScriptDir & "\Setting.ini"
Global $g_hDesktop = _WinGetDesktopHandle()
Global $g_hDeskCtrlListView = ControlGetHandle($g_hDesktop, "", "[CLASS:SysListView32;INSTANCE:1]")

ConsoleWrite("$g_sIniPath=" & $g_sIniPath & @CRLF)
ConsoleWrite("$g_hDesktop=" & $g_hDesktop & @CRLF)
ConsoleWrite("$g_hDeskCtrlListView=" & $g_hDeskCtrlListView & @CRLF)

Global $iParams = $CmdLine[0]
;Check if $CmdLine parameters
If Not $iParams Then
    _CallGUI()
Else
    $iParams = $CmdLine
EndIf

Switch $iParams[1]
    Case "-save"
        _SaveSetting()

    Case "-restore"
        _RestoreSetting()

EndSwitch

Exit

;_SetShortcutPos("Recycle Bin", 0, 0)

;----------------------------------------------------------------------------------------
Func _CallGUI()
    GUICreate("   DeskTop shortcuts", 170, 90, -1, -1, -1, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    Local $ButtonSave = GUICtrlCreateButton("Save Setting", 10, 10, 150, 30)
    GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
    Local $ButtonRestore = GUICtrlCreateButton("Restore Setting", 10, 50, 150, 30)
    GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)

    Local $nMsg

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $ButtonSave
                _SaveSetting()
                ExitLoop

            Case $ButtonRestore
                _RestoreSetting()
                ExitLoop

        EndSwitch
    WEnd

    Exit
EndFunc   ;==>_CallGUI
;----------------------------------------------------------------------------------------
Func _SetShortcutPos($Name = "", $X = 0, $Y = 0)
    Local $iIndex = _GUICtrlListView_FindInText($g_hDeskCtrlListView, $Name)
    If $iIndex == -1 Then
        Return SetError(1, 0, "! Could not find icon: " & $Name)
    EndIf
    _GUICtrlListView_SetItemPosition($g_hDeskCtrlListView, $iIndex, $X, $Y)
    Return "- " & $Name & "=" & $X & "," & $Y
EndFunc   ;==>_SetShortcutPos
;----------------------------------------------------------------------------------------
Func _SaveSetting()
    Local $iItemCount, $sTxt, $aPos
    $iItemCount = _GUICtrlListView_GetItemCount($g_hDeskCtrlListView)
    ConsoleWrite("> Save Setting:" & @CRLF)
    ConsoleWrite("- Item Count:" & $iItemCount & @CRLF)

    $sTxt = "[Setting]" & @CRLF

    For $i = 0 To $iItemCount - 1
        $sTxt &= _GUICtrlListView_GetItemText($g_hDeskCtrlListView, $i)
        $aPos = _GUICtrlListView_GetItemPosition($g_hDeskCtrlListView, $i)
        $sTxt &= "=" & $aPos[0] & "," & $aPos[1] & @CRLF
    Next

    ConsoleWrite($sTxt & @CRLF)

    Local $hFileOpen = FileOpen($g_sIniPath, $FO_OVERWRITE + $FO_CREATEPATH + $FO_UTF8_NOBOM)
    If $hFileOpen = -1 Then
        MsgBox($MB_SYSTEMMODAL, "", "An error occurred whilst writing the txt file.")
        Return False
    EndIf

    FileWrite($hFileOpen, $sTxt)

EndFunc   ;==>_SaveSetting
;----------------------------------------------------------------------------------------
Func _RestoreSetting()
    ConsoleWrite("> Restore Setting:" & @CRLF)
    Local $aPos

    ; Read the INI section labelled 'Setting'. This will return a 2 dimensional array.
    Local $aArray = IniReadSection($g_sIniPath, "Setting")

    If Not @error Then
        ; Enumerate through the array displaying the keys and their respective values.
        For $i = 1 To $aArray[0][0]
            $aPos = StringSplit($aArray[$i][1], ",")
            If $aPos[0] = 2 Then
                ConsoleWrite(_SetShortcutPos($aArray[$i][0], $aPos[1], $aPos[2]) & @CRLF)
            EndIf
        Next
    EndIf

EndFunc   ;==>_RestoreSetting
;----------------------------------------------------------------------------------------
;  https://www.autoitscript.com/forum/topic/119783-desktop-class-workerw/#comment-903081
; <_WinGetDesktopHandle.au3>
; Function to get the Windows' Desktop Handle.
;   Since this is no longer a simple '[CLASS:Progman]' on Aero-enabled desktops, this method uses a slightly
;   more involved method to find the correct Desktop Handle.
;
; Author: Ascend4nt, credits to Valik for pointing out the Parent->Child relationship: Desktop->'SHELLDLL_DefView'
;----------------------------------------------------------------------------------------
Func _WinGetDesktopHandle()
    Local $i, $hDeskWin, $hSHELLDLL_DefView, $h_Listview_Configs, $aWinList
    ; The traditional Windows Classname for the Desktop, not always so on newer O/S's
    $hDeskWin = WinGetHandle("[CLASS:Progman]")
    ; Parent->Child relationship: Desktop->SHELLDLL_DefView
    $hSHELLDLL_DefView = ControlGetHandle($hDeskWin, '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
    ; No luck with finding the Desktop and/or child?
    If $hDeskWin = '' Or $hSHELLDLL_DefView = '' Then
        ; Look through a list of WorkerW windows - one will be the Desktop on Windows 7+ O/S's
        $aWinList = WinList("[CLASS:WorkerW]")
        For $i = 1 To $aWinList[0][0]
            $hSHELLDLL_DefView = ControlGetHandle($aWinList[$i][1], '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
            If $hSHELLDLL_DefView <> '' Then
                $hDeskWin = $aWinList[$i][1]
                ExitLoop
            EndIf
        Next
    EndIf
    ; Parent->Child relationship: Desktop->SHELDLL_DefView->SysListView32
    $h_Listview_Configs = ControlGetHandle($hSHELLDLL_DefView, '', '[CLASS:SysListView32; INSTANCE:1]')
    If $h_Listview_Configs = '' Then Return SetError(-1, 0, '')
    Return SetExtended($h_Listview_Configs, $hDeskWin)
EndFunc   ;==>_WinGetDesktopHandle
;----------------------------------------------------------------------------------------

 

:) Please, leave your comments and experiences here.

thank you very much !

Edited by ioa747
plus info

I know that I know nothing

Link to comment
Share on other sites

Looks simple/clear/good.

 

Few tips:

1) instead of Setting.ini use @ScriptName with .ini extension (here DesktopIconSet.ini)

;Global $g_sIniPath = @ScriptDir & "\Setting.ini"
Global $g_sIniPath

Global $ext = StringRight(@ScriptName, 4) ; .exe / .au3
Global $ini = StringReplace(@ScriptName,$ext,'.ini',1,1)
$g_sIniPath = @ScriptDir & "\" & $ini

2) instead of ConsoleWrite use helper function Debug()

;ConsoleWrite("$g_sIniPath=" & $g_sIniPath & @CRLF)
;ConsoleWrite("$g_hDesktop=" & $g_hDesktop & @CRLF)
;ConsoleWrite("$g_hDeskCtrlListView=" & $g_hDeskCtrlListView & @CRLF)

Debug("$g_sIniPath=" & $g_sIniPath)
Debug("$g_hDesktop=" & $g_hDesktop)
Debug("$g_hDeskCtrlListView=" & $g_hDeskCtrlListView)

Func Debug($text)
    If Not @Compiled Then ConsoleWrite($text & @CRLF)
EndFunc

3) probably there may be position conflicts when you may try to set position of icon to other with the same position ...

so maybe some simple test for that scenario and try to automatically change conflicting position to right or down ...

Edited by Zedna
Link to comment
Share on other sites

Thank you @Zedna  for the comments and tips

 

  • 1) instead of Setting.ini use @ScriptName with .ini extension (here DesktopIconSet.ini)
    I prefer it too ,  I fixed it already
    Global Const $g_sIniPath = StringTrimRight(@ScriptFullPath, 4) & ".ini"
     
  • 2) instead of ConsoleWrite use helper function Debug()
    what is it intended for?
    To gain time from something that is useless?  ( as long as it's  compiled, and you don't see the console out )
    or is it some other case?
     
  • 3) probably there may be position conflicts when you may try to set position of icon to other with the same position ...
    this is the complicated part, and it takes more time to test it
    ( I tried it but didn't go deeper, e.g. in case of restoring a different icon size than the backup. It is, so to speak, a first approach )
    And the bad thing is that the more it need, the more it will be lost, how did you say it? simple/clear  :)

 

Again thank you very much
 

I know that I know nothing

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...