Jump to content
Sign in to follow this  
crashdemons

Another desktop positions restore script

Recommended Posts

Posted Image

Posted Image

Background

My desktop icons shift around often when I extend my screen or connect a higher resolution monitor to my laptop, or when a game crashes in an awkward resolution.

Recently I've not been having very much luck with programs and scripts that save desktop icon positions. I know there are various examples on this forum - but I've been frustrated by them as well as other options (eg: an outdated layout.dll shell extension)

For the record, I use Windows 7 64-bit ; I haven't tested this on anything else, but that was probably part of the problem. From some research it appears desktop positions can be saved in one of several different registry keys; older programs may not be searching for them all.

So, I decided to write my own crappy program that *did* search multiple locations for position settings.

TL;DR

Made a program to save desktop icon positions; checks for multiple settings before attempting.

Sauce

Anyway, here's my badly-informed bug-ridden spaghetti code that does what I need:

Note: See slightly cleaned-up code in a reply below!

#RequireAdmin
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>
Global $results[11];elements are array[5]= 0:$display_name 1:$bag_key 2:$bag 3:$valueName 4:$valueDisplayName
Global $ctrls[11][5]

Global $selected = Int(IniRead("itempos.ini", "settings", "selected", -1))
Global $uiOps = GUICreate("Desktop Position Options", 350 + 20, 100)
Global $txSel = GUICtrlCreateInput("Not Selected", 0, 0, 350, 20, $ES_READONLY)
Global $btSel = GUICtrlCreateButton("...", 350, 0, 20, 20)
Global $btSav = GUICtrlCreateButton("Save", 0, 20, 350 + 20, 40)
Global $btRes = GUICtrlCreateButton("Restore", 0, 60, 350 + 20, 40)
uiResetOptions()
Global $uiSel, $btRef
Local $hadSettings = load()
uiPopulate($results, $ctrls, $uiSel, $btRef, (Not $hadSettings));refresh if didn't cache settings
GUISetState(@SW_SHOW, $uiOps)
If (Not $hadSettings) Or $selected < 1 Then
    GUISetState(@SW_SHOW, $uiSel)
    WinActivate($uiSel)
Else
    GUISetState(@SW_HIDE, $uiSel)
    WinActivate($uiOps)
EndIf
;------------------------------------



While 1
    $amsg = GUIGetMsg(1)
    $msg = $amsg[0]
    Switch $msg
        Case $GUI_EVENT_CLOSE
            If $amsg[1] = $uiOps Then Quit()
            GUISetState(@SW_HIDE, $uiSel)
            WinActivate($uiOps)
        Case $btRef
            uiPopulate($results, $ctrls, $uiSel, $btRef)
            ContinueCase
        Case $btSel
            GUISetState(@SW_SHOW, $uiSel)
            WinActivate($uiSel)
        Case $btSav
            save()
            uiResetOptions()
        Case $btRes
            restore()
            uiResetOptions()
        Case $ctrls[0][0]
            MsgBox(0, "Position Information Locations", "This window lists system icon position settings" & @CRLF & "This selection may help if restoring settings does not work. If you do not know what to select, try `Current User`.  ")
    EndSwitch
    For $n = 1 To 10
        If $msg = $ctrls[$n][0] And $ctrls[$n][0] <> 0 Then
            uiSelect($n)
            ExitLoop
        EndIf
    Next
WEnd


;------------------------

Func load()
    Global $selected
    Global $results

    Local $hadSettings = False
    For $i = 0 To 10
        Local $entry[5]
        If IniRead("itempos.ini", "cache", $i, "") = "array" Then
            For $j = 0 To 4
                $entry[$j] = IniRead("itempos.ini", "cache", $i & '_' & $j, "")
            Next
            $results[$i] = $entry
            $hadSettings = True
        Else
            $results[$i] = IniRead("itempos.ini", "cache", $i, "")
        EndIf
    Next

    Local $n = Int(IniRead("itempos.ini", "settings", "selected", -1))
    If Not $hadSettings Then $n = -1
    uiSelect($n)

    Return $hadSettings
EndFunc   ;==>load

Func Quit()
    IniWrite("itempos.ini", "settings", "selected", $selected)
    For $i = 0 To 10
        Local $entry = $results[$i]
        If IsArray($entry) Then
            IniWrite("itempos.ini", "cache", $i, "array")
            For $j = 0 To 4
                IniWrite("itempos.ini", "cache", $i & '_' & $j, $entry[$j])
            Next
        Else
            IniWrite("itempos.ini", "cache", $i, $entry)
        EndIf
    Next
    Exit
EndFunc   ;==>quit


Func uiResetOptions()
    If $selected > 0 Then
        GUICtrlSetState($btSav, $GUI_ENABLE)
        If isSaved() Then
            GUICtrlSetState($btRes, $GUI_ENABLE)
        Else
            GUICtrlSetState($btRes, $GUI_DISABLE)
        EndIf
    Else
        GUICtrlSetState($btSav, $GUI_DISABLE)
        GUICtrlSetState($btRes, $GUI_DISABLE)
    EndIf
EndFunc   ;==>uiResetOptions

Func isSaved()
    Local $entry = $results[$selected]
    If Not IsArray($entry) Then Return False
    Return StringLen(IniRead("itempos.ini", safename($entry[0] & '-' & $entry[2] & '-' & $entry[4]), safename($entry[3]), "")) > 0
EndFunc   ;==>isSaved


Func save()
    GUICtrlSetState($btSav, $GUI_DISABLE)
    GUICtrlSetState($btRes, $GUI_DISABLE)
    WinActivate("Program Manager")
    Sleep(250)
    Send("{F5}")
    Sleep(1000)
    WinActivate($uiOps)

    Local $entry = $results[$selected]
    Local $nameSafe = safename($entry[0] & '-' & $entry[2] & '-' & $entry[4])
    Local $bag_key = $entry[1]
    Local $valueName = $entry[3]
    Local $valueNameSafe = safename($valueName)
    Local $value = RegRead($bag_key, $valueName)
    ConsoleWrite("Saving to " & $nameSafe & @CRLF)

    IniWrite("itempos.ini", $nameSafe, $valueNameSafe, $value)
EndFunc   ;==>save

Func restore()
    Local $entry = $results[$selected]
    Local $nameSafe = safename($entry[0] & '-' & $entry[2] & '-' & $entry[4])
    Local $bag_key = $entry[1]
    Local $valueName = $entry[3]
    Local $valueNameSafe = safename($valueName)
    Local $value = IniRead("itempos.ini", $nameSafe, $valueNameSafe, "")
    ConsoleWrite("Restoring from " & $nameSafe & @CRLF)

    If StringLen($value) = 0 Then Return MsgBox(0, 'Restore Error', "No data is available for this entry to be restored.")

    ProcessKill('explorer.exe')
    ProcessWaitClose('explorer.exe')
    RegWrite($bag_key, $valueName, "REG_BINARY", Binary($value))
    Run('explorer.exe')
EndFunc   ;==>restore

;--------------------------------------------------

Func uiSelect($n)
    Global $selected
    Global $results
    $selected = $n

    Local $entry = ""
    If $selected > 0 Then $entry = $results[$n]

    If IsArray($entry) Then
        GUICtrlSetData($txSel, $entry[0] & '-' & $entry[2] & '-' & $entry[4])
        If IsHWnd($uiSel) Then GUISetState(@SW_HIDE, $uiSel)
        WinActivate($uiOps)
        uiResetOptions()
        Return True
    Else
        GUICtrlSetData($txSel, "Nothing Selected")
        uiResetOptions()
        If IsHWnd($uiSel) Then GUISetState(@SW_SHOW, $uiSel)
        WinActivate($uiSel)
    EndIf
    Return False
EndFunc   ;==>uiSelect

Func uiPopulate(ByRef $results, ByRef $ctrls, ByRef $ui, ByRef $button, $doRefresh = True)
    ;results and ctrls must have the same UBound.
    ProgressOn("Refreshing...", "Refreshing...")
    ProgressSet(1, "Cleaning up...")
    Sleep(250)

    Local $x = UBound($ctrls) - 1

    GUISwitch($ui)
    GUICtrlDelete($button)
    For $n = 0 To $x
        For $i = 0 To 3
            If $ctrls[$n][$i] Then GUICtrlDelete($ctrls[$n][$i])
        Next
    Next
    If IsHWnd($ui) Then GUIDelete($ui)

    If $doRefresh Then
        For $i = 0 To UBound($results) - 1
            $results[$i] = ''
        Next
        ProgressSet(5, "Finding folder information sources...")
        searchhive($results)
    EndIf
    ProgressSet(95, "Creating User Interface...")
    Sleep(250)


    Local $count = 0
    For $n = 1 To $x
        Local $y = ($n - 1) * 20
        If IsArray($results[$n]) Then $count += 1
    Next

    $ui = GUICreate("Select system setting to use...", 450, 20 * ($count + 2) + 10)
    $ctrls[0][0] = GUICtrlCreateButton("??", 0, 0, 20, 20)
    $ctrls[0][1] = GUICtrlCreateLabel("Profile", 020, 5, 250, 20)
    $ctrls[0][2] = GUICtrlCreateLabel("Bag", 270, 5, 050, 20)
    $ctrls[0][3] = GUICtrlCreateLabel("ItemPos", 320, 5, 150, 20)
    $ctrls[0][4] = GUICtrlCreateLabel("-----------------------------------", 0, 20, 450, 5, $SS_ETCHEDHORZ)


    $count = 0
    For $n = 1 To $x
        Local $y = $n * 20 + 5
        Local $entry = $results[$n]
        If IsArray($entry) Then
            $count += 1
            $ctrls[$n][0] = GUICtrlCreateButton($count & '.', 0, $y, 20, 20)
            $y += 5
            $ctrls[$n][1] = GUICtrlCreateLabel($entry[0], 020, $y, 250, 20)
            $ctrls[$n][2] = GUICtrlCreateLabel($entry[2], 270, $y, 050, 20)
            $ctrls[$n][3] = GUICtrlCreateLabel($entry[4], 320, $y, 150, 20)
        EndIf
    Next
    $ctrls[$x][4] = GUICtrlCreateButton("Refresh", 0, 20 * ($count + 1) + 10, 450, 20)
    $button = $ctrls[$x][4]
    GUISwitch($ui)

    ProgressSet(100, "Showing off...")
    Sleep(250)
    ProgressOff()
    Return $ui
EndFunc   ;==>uiPopulate
;--------------------------------------------------------------------
Func searchhive(ByRef $results)
    ;ConsoleWrite('Current'&@CRLF)
    ProgressInitial(5)
    searchuser($results, 'HKEY_CURRENT_USER', 'Current User')
    ProgressSet(25)
    For $i = 1 To 9999
        Local $u = RegEnumKey("HKEY_USERS\", $i)
        If @error <> 0 Then ExitLoop
        ;ConsoleWrite($u&@CRLF)
        searchuser($results, "HKEY_USERS\" & $u, $u)
        ProgressSet(25 + $i * 10)
    Next
EndFunc   ;==>searchhive
Func searchuser(ByRef $results, $user_key, $display_name)
    Local $software_key[2] = ["Software\Microsoft\Windows", "Software\Classes\Local Settings\Software\Microsoft\Windows"]
    Local $shell_key[2] = ["Shell", "ShellNoRoam"]
    Local $name_suffix

    For $sw In $software_key
        $name_suffix = ""
        If StringInStr($sw, "Local") Then $name_suffix = "L"
        For $shell In $shell_key
            If StringInStr($shell, "NoRoam") Then $name_suffix &= "NR"
            Local $bags_key = $user_key & "\" & $sw & "\" & $shell & "\Bags"
            For $i = 1 To 9999
                ProgressIncrement(0.01)
                Local $bag = RegEnumKey($bags_key, $i)
                If @error <> 0 Then ExitLoop
                If StringLen($name_suffix) > 0 Then $name_suffix = "(" & $name_suffix & ")"
                searchbag($results, $bags_key, $bag, $display_name & $name_suffix)
            Next
        Next
    Next
EndFunc   ;==>searchuser
Func searchbag(ByRef $results, $bags_key, $bag, $display_name)
    Local $bag_key = $bags_key & '\' & $bag & '\Shell'
    For $i = 1 To 9999
        Local $value = RegEnumVal($bag_key, $i)
        If @error <> 0 Then ExitLoop
        If StringInStr($value, 'ItemPos') Then
            Local $entry[5] = [$display_name, $bag_key, $bag, $value, StringTrimLeft($value, 7)]
            _Array_Fixed_Push($results, $entry)
        EndIf
    Next
    $bag_key = $bags_key & '\' & $bag & '\Desktop'
    For $i = 1 To 9999
        Local $value = RegEnumVal($bag_key, $i)
        If @error <> 0 Then ExitLoop
        ;ConsoleWrite($value&@CRLF)
        If StringInStr($value, 'ItemPos') Then
            Local $entry[5] = [$display_name, $bag_key, $bag, $value, StringTrimLeft($value, 7)]
            _Array_Fixed_Push($results, $entry)
        EndIf
    Next
EndFunc   ;==>searchbag
Func _Array_Fixed_Push(ByRef $array, $value);adds an item, overwriting the oldest item | NOTE: Edited from original intent, see comments
    Local $x = UBound($array) - 1
    If $array[0] = $x Then Return False; *** decided later that overwriting sucked for systems with many profiles.
    Local $i = Mod($array[0], $x); values from 0 to x-1
    Local $n = $i + 1;(0 to x-1)+1 = 1 to x
    $array[0] = $n; this is also the nonadjusted index for the next item :)
    $array[$n] = $value
EndFunc   ;==>_Array_Fixed_Push


Func ProgressInitial($n = 0)
    Global $ProgressIncrement
    $ProgressIncrement = $n
    ProgressSet($n)
EndFunc   ;==>ProgressInitial
Func ProgressIncrement($n = 1)
    Global $ProgressIncrement
    $ProgressIncrement += $n
    ProgressSet($ProgressIncrement)
EndFunc   ;==>ProgressIncrement

Func safename($s)
    Return StringRegExpReplace($s, "[^a-zA-Z0-9_\-]", "_")
EndFunc   ;==>safename


Func ProcessKill($p); I should probably credit someone for this function
    $Kernel32 = DllOpen("kernel32.dll")
    $hproc = DllCall($Kernel32, 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', True, 'int', ProcessExists($p))
    DllCall($Kernel32, "int", "TerminateProcess", "int", $hproc[0], "dword", 1)
    DllClose($Kernel32)
EndFunc   ;==>ProcessKill

Other Notes

This only scans for settings/prompts you on the first run, it should keep that information for the next run. It also limits you to using one of the first 10 profiles the scan results in.

Sorry about having to kill/restart explorer when restoring positions - nothing else worked for me.

Clarification for the ItemPos text: from what I've read, it is <Resolution>(<Monitor>). I'm unsure how settings behave when you have icons dragged from one screen to the next and restore one of the screens.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Share this post


Link to post
Share on other sites

Here is a ZIP for the compiled executables (x86 and x64). DesktopPos.zip

Note: I encountered issues trying to run the script or compiled versions as x86 under a 64-bit platform - please choose executable and interpreter platform appropriately.

Specifically, launching explorer with Run() does not seem to have the desired effect from a 32-bit executable ran on a 64-bit OS. There could be Registry differences also that effect this program's function.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Share this post


Link to post
Share on other sites

Did some spring-cleaning on the source code:

#RequireAdmin
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>


Global Enum $UIO_HWND = 0, $UIO_TEXT, $UIO_SELECT, $UIO_SAVE, $UIO_RESTORE
Global Enum $UIS_HWND = 0, $UIS_HELP, $UIS_REFRESH = 6, $UIS_DYNAMIC = 7, $UIS_DYNCTRLS = 4, $UIS_DYNBUTTONMOD = Mod($UIS_DYNAMIC, $UIS_DYNCTRLS)


Global $ProgressIncrement

Global $bag_entries[11];elements are array[5]= 0:$display_name 1:$bag_key 2:$bag 3:$valueName 4:$valueDisplayName
Global $selected = -1


Global $uiInfo_Ops = uiCreateOptions()
uiOptions_Reset($bag_entries, $selected, $uiInfo_Ops)
Global $uiInfo_Sel[60]
Global $hadSettings = load($uiInfo_Ops, $uiInfo_Sel, $selected, $bag_entries)
uiSelector_Populate($uiInfo_Sel, $bag_entries, Not $hadSettings);refresh if didn't cache settings


GUISetState(@SW_SHOW, $uiInfo_Ops[$UIO_HWND])
If (Not $hadSettings) Or $selected < 1 Then
    GUISetState(@SW_SHOW, $uiInfo_Sel[$UIS_HWND])
    WinActivate($uiInfo_Sel[$UIS_HWND])
Else
    GUISetState(@SW_HIDE, $uiInfo_Sel[$UIS_HWND])
    WinActivate($uiInfo_Ops[$UIO_HWND])
EndIf


;------------------------------------


Global $amsg, $msg
While 1
    $amsg = GUIGetMsg(1)
    Switch $amsg[0]
        Case $GUI_EVENT_CLOSE
            If $amsg[1] = $uiInfo_Ops[$UIO_HWND] Then Quit($selected, $bag_entries)
            GUISetState(@SW_HIDE, $uiInfo_Sel[$UIS_HWND])
            WinActivate($uiInfo_Ops[$UIO_HWND])
        Case $uiInfo_Sel[$UIS_REFRESH]
            uiSelector_Populate($uiInfo_Sel, $bag_entries)
            ContinueCase
        Case $uiInfo_Ops[$UIO_SELECT]
            GUISetState(@SW_SHOW, $uiInfo_Sel[$UIS_HWND])
            WinActivate($uiInfo_Sel[$UIS_HWND])
        Case $uiInfo_Ops[$UIO_SAVE]
            uiOptions_Save($uiInfo_Ops, $bag_entries, $selected)
            uiOptions_Reset($bag_entries, $selected, $uiInfo_Ops)
        Case $uiInfo_Ops[$UIO_RESTORE]
            uiOptions_Restore($uiInfo_Ops, $bag_entries, $selected)
            uiOptions_Reset($bag_entries, $selected, $uiInfo_Ops)
        Case $uiInfo_Sel[$UIS_HELP]
            MsgBox(0, "Position Information Locations", "This window lists system icon position settings" & @CRLF & "This selection may help if restoring settings does not work. If you do not know what to select, try `Current User`.  ")
    EndSwitch
    For $i = $UIS_DYNAMIC To UBound($uiInfo_Sel) - 1
        If $amsg[0] = $uiInfo_Sel[$i] And $uiInfo_Sel[$i] <> 0 And Mod($i, $UIS_DYNCTRLS) = $UIS_DYNBUTTONMOD Then
            uiSelector_Submit(Int(GUICtrlRead($uiInfo_Sel[$i])), $uiInfo_Ops, $uiInfo_Sel, $selected, $bag_entries); the displayed count number will also be the 1-based index of the item, since they're inserted sequentially without gaps.
            ExitLoop
        EndIf
    Next
WEnd


;------------------------

Func load(ByRef $uiInfo_Options, ByRef $uiInfo_Selector, ByRef $iSelected_out, ByRef $bags)

    Local $hadSettings = False
    For $i = 0 To UBound($bags)-1
        Local $entry[5]
        If IniRead("itempos.ini", "cache", $i, "") = "array" Then
            For $j = 0 To 4
                $entry[$j] = IniRead("itempos.ini", "cache", $i & '_' & $j, "")
            Next
            $bags[$i] = $entry
            $hadSettings = True
        Else
            $bags[$i] = IniRead("itempos.ini", "cache", $i, "")
        EndIf
    Next

    Local $n = Int(IniRead("itempos.ini", "settings", "selected", -1))
    If Not $hadSettings Then $n = -1
    uiSelector_Submit($n, $uiInfo_Options, $uiInfo_Selector, $iSelected_out, $bags)

    Return $hadSettings
EndFunc   ;==>load

Func Quit(ByRef $iSelected_in, ByRef $bags_in)
    IniWrite("itempos.ini", "settings", "selected", $iSelected_in)
    For $i = 0 To UBound($bags_in)-1
        Local $entry = $bags_in[$i]
        If IsArray($entry) Then
            IniWrite("itempos.ini", "cache", $i, "array")
            For $j = 0 To 4
                IniWrite("itempos.ini", "cache", $i & '_' & $j, $entry[$j])
            Next
        Else
            IniWrite("itempos.ini", "cache", $i, $entry)
        EndIf
    Next
    Exit
EndFunc   ;==>Quit


Func isSaved(ByRef $iSelected, ByRef $bags_in)
    Local $entry = $bags_in[$iSelected]
    If Not IsArray($entry) Then Return False
    Return StringLen(IniRead("itempos.ini", safename($entry[0] & '-' & $entry[2]), safename($entry[3]), "")) > 0
EndFunc   ;==>isSaved


Func uiOptions_Save(ByRef $uiInfo_Options, ByRef $bags, ByRef $iSelected)
    GUICtrlSetState($uiInfo_Options[$UIO_SAVE], $GUI_DISABLE)
    GUICtrlSetState($uiInfo_Options[$UIO_RESTORE], $GUI_DISABLE)
    WinActivate("Program Manager")
    Sleep(250)
    Send("{F5}")
    Sleep(1000)
    WinActivate($uiInfo_Options[$UIO_HWND])

    Local $entry = $bags[$iSelected]
    Local $nameSafe = safename($entry[0] & '-' & $entry[2])
    Local $bag_key = $entry[1]
    Local $valueName = $entry[3]
    Local $valueNameSafe = safename($valueName)
    Local $value = RegRead($bag_key, $valueName)
    ConsoleWrite("Saving to " & $nameSafe & @CRLF)

    IniWrite("itempos.ini", $nameSafe, $valueNameSafe, $value)
EndFunc   ;==>uiOptions_Save

Func uiOptions_Restore(ByRef $uiInfo_Options, ByRef $bags, ByRef $iSelected)
    GUICtrlSetState($uiInfo_Options[$UIO_SAVE], $GUI_DISABLE)
    GUICtrlSetState($uiInfo_Options[$UIO_RESTORE], $GUI_DISABLE)
    Local $entry = $bags[$iSelected]
    Local $nameSafe = safename($entry[0] & '-' & $entry[2])
    Local $bag_key = $entry[1]
    Local $valueName = $entry[3]
    Local $valueNameSafe = safename($valueName)
    Local $value = IniRead("itempos.ini", $nameSafe, $valueNameSafe, "")
    ConsoleWrite("Restoring from " & $nameSafe & @CRLF)

    If StringLen($value) = 0 Then Return MsgBox(0, 'Restore Error', "No data is available for this entry to be restored.")

    ProcessKill('explorer.exe')
    ProcessWaitClose('explorer.exe')
    RegWrite($bag_key, $valueName, "REG_BINARY", Binary($value))
    Run('explorer.exe')
EndFunc   ;==>restore

;--------------------------------------------------

Func uiCreateOptions()
    Local $uiInfo[5]
    $uiInfo[0] = GUICreate("Desktop Position Options", 350 + 20, 100)
    $uiInfo[1] = GUICtrlCreateInput("Not Selected", 0, 0, 350, 20, $ES_READONLY)
    $uiInfo[2] = GUICtrlCreateButton("...", 350, 0, 20, 20)
    $uiInfo[3] = GUICtrlCreateButton("Save", 0, 20, 350 + 20, 40)
    $uiInfo[4] = GUICtrlCreateButton("Restore", 0, 60, 350 + 20, 40)
    Return $uiInfo
EndFunc   ;==>uiCreateOptions


Func uiOptions_Reset(ByRef $bags, ByRef $iSelected_in, ByRef $uiInfo_Options)
    If $iSelected_in > 0 Then
        GUICtrlSetState($uiInfo_Options[3], $GUI_ENABLE)
        If isSaved($iSelected_in, $bags) Then
            GUICtrlSetState($uiInfo_Options[4], $GUI_ENABLE)
        Else
            GUICtrlSetState($uiInfo_Options[4], $GUI_DISABLE)
        EndIf
    Else
        GUICtrlSetState($uiInfo_Options[3], $GUI_DISABLE)
        GUICtrlSetState($uiInfo_Options[4], $GUI_DISABLE)
    EndIf
EndFunc   ;==>uiOptions_Reset



Func uiSelector_Submit($n, ByRef $uiInfo_Options, ByRef $uiInfo_Selector, ByRef $iSelected, ByRef $bags_in)
    $iSelected = $n

    Local $entry = ""
    If $iSelected > 0 Then $entry = $bags_in[$n]

    If IsArray($entry) Then
        GUICtrlSetData($uiInfo_Options[1], $entry[0] & '-' & $entry[2] & '-' & $entry[4])
        If IsHWnd($uiInfo_Selector[0]) Then GUISetState(@SW_HIDE, $uiInfo_Selector[0])
        WinActivate($uiInfo_Options[$UIO_HWND])
        uiOptions_Reset($bags_in, $iSelected, $uiInfo_Options)
        Return True
    Else
        GUICtrlSetData($uiInfo_Options[1], "Nothing Selected")
        uiOptions_Reset($bags_in, $iSelected, $uiInfo_Options)
        If IsHWnd($uiInfo_Selector[0]) Then
            GUISetState(@SW_SHOW, $uiInfo_Selector[0])
            WinActivate($uiInfo_Selector[0])
        EndIf
    EndIf
    Return False
EndFunc   ;==>uiSelector_Submit

Func uiSelector_Populate(ByRef $uiInfo, ByRef $bags, $doRefresh = True);; NOTE: uiInfo must be a 60-element array (ah hell, lets just give ourselves room to develop the UI a bit, the max dynamic controls will be 4*10 at this time)
    ProgressOn("Refreshing...", "Refreshing...")
    Local $maxCtrl = UBound($uiInfo) - 1
    Local $maxBags = UBound($bags) - 1

    ;to produce a UI without alot of extra Globals, we need to dynamically create our UI. So we need to discard of the old one.  Sizing is also much easier this way.
    ProgressSet(1, "Cleaning up...")
    Sleep(250)
    For $n = 1 To $maxCtrl
        If $uiInfo[$n] Then GUICtrlDelete($uiInfo[$n])
    Next
    If IsHWnd($uiInfo[0]) Then GUIDelete($uiInfo[0])

    ;reset data
    If $doRefresh Then
        For $i = 0 To $maxBags
            $bags[$i] = ''
        Next
        ProgressSet(5, "Finding folder information sources...")
        searchhive($bags)
    EndIf
    ProgressSet(95, "Creating User Interface...")
    Sleep(250)

    ;get the count of dynamic entries so that we can determine UI dimensions.
    Local $count = 0
    For $n = 1 To $maxBags
        If IsArray($bags[$n]) Then $count += 1
    Next

    ;creating our UI and static elements first.
    $uiInfo[0] = GUICreate("Select system setting to use...", 450, 20 * ($count + 2) + 10)
    $uiInfo[1] = GUICtrlCreateButton("??", 0, 0, 20, 20)
    $uiInfo[2] = GUICtrlCreateLabel("Profile", 020, 5, 250, 20)
    $uiInfo[3] = GUICtrlCreateLabel("Bag", 270, 5, 050, 20)
    $uiInfo[4] = GUICtrlCreateLabel("ItemPos", 320, 5, 150, 20)
    $uiInfo[5] = GUICtrlCreateLabel("-----------------------------------", 0, 20, 450, 5, $SS_ETCHEDHORZ)
    $uiInfo[6] = GUICtrlCreateButton("Refresh", 0, 20 * ($count + 1) + 10, 450, 20)

    ;  creating dynamic elements
    $count = 0
    For $n = 1 To $maxBags
        Local $entry = $bags[$n]
        If IsArray($entry) Then
            Local $y = ($count + 1) * 20 + 5;back-to-back rows of 20px with an initial offset of 5
            $count += 1
            $uiInfo[07 + ($count - 1) * 4] = GUICtrlCreateButton($count & '.', 0, $y, 20, 20)
            $y += 5;offset labels slightly so that they look centered on the buttons instead of top-aligned.
            $uiInfo[08 + ($count - 1) * 4] = GUICtrlCreateLabel($entry[0], 020, $y, 250, 20)
            $uiInfo[09 + ($count - 1) * 4] = GUICtrlCreateLabel($entry[2], 270, $y, 050, 20)
            $uiInfo[10 + ($count - 1) * 4] = GUICtrlCreateLabel($entry[4], 320, $y, 150, 20)
        EndIf
    Next

    ProgressSet(100, "Showing off...")
    Sleep(250)
    GUISwitch($uiInfo[0])
    ProgressOff()
    Return $uiInfo
EndFunc   ;==>uiSelector_Populate
;--------------------------------------------------------------------
Func searchhive(ByRef $results)
    ;ConsoleWrite('Current'&@CRLF)
    ProgressInitial(5)
    searchuser($results, 'HKEY_CURRENT_USER', 'Current User')
    ProgressSet(25)
    For $i = 1 To 9999; this looks bad, but substituting a While loop creates unnecessary lines for an index variable, and introduces an exhaustive search (limited by Signed Int maximum)
        Local $u = RegEnumKey("HKEY_USERS\", $i)
        If @error <> 0 Then ExitLoop
        ;ConsoleWrite($u&@CRLF)
        searchuser($results, "HKEY_USERS\" & $u, $u)
        ProgressSet(25 + $i * 10)
    Next
EndFunc   ;==>searchhive
Func searchuser(ByRef $results, $user_key, $display_name)
    Local $software_key[2] = ["Software\Microsoft\Windows", "Software\Classes\Local Settings\Software\Microsoft\Windows"]
    Local $shell_key[2] = ["Shell", "ShellNoRoam"]
    Local $name_suffix

    For $sw In $software_key
        $name_suffix = ""
        If StringInStr($sw, "Local") Then $name_suffix = "L"
        For $shell In $shell_key
            If StringInStr($shell, "NoRoam") Then $name_suffix &= "NR"
            Local $bags_key = $user_key & "\" & $sw & "\" & $shell & "\Bags"
            For $i = 1 To 9999; this looks bad, but substituting a While loop creates unnecessary lines for an index variable, and introduces an exhaustive search (limited by Signed Int maximum)
                ProgressIncrement(0.01)
                Local $bag = RegEnumKey($bags_key, $i)
                If @error <> 0 Then ExitLoop
                If StringLen($name_suffix) > 0 Then $name_suffix = "(" & $name_suffix & ")"
                searchbag($results, $bags_key, $bag, $display_name & $name_suffix)
            Next
        Next
    Next
EndFunc   ;==>searchuser
Func searchbag(ByRef $results, $bags_key, $bag, $display_name)
    Local $bag_key = $bags_key & '\' & $bag & '\Shell'
    Local $value
    For $i = 1 To 9999; this looks bad, but substituting a While loop creates unnecessary lines for an index variable, and introduces an exhaustive search (limited by Signed Int maximum)
        $value = RegEnumVal($bag_key, $i)
        If @error <> 0 Then ExitLoop
        If StringInStr($value, 'ItemPos') Then
            Local $entry[5] = [$display_name, $bag_key, $bag, $value, StringTrimLeft($value, 7)]
            _ArrayFixed_Add($results, $entry)
        EndIf
    Next
    $bag_key = $bags_key & '\' & $bag & '\Desktop'
    For $i = 1 To 9999; this looks bad, but substituting a While loop creates unnecessary lines for an index variable, and introduces an exhaustive search (limited by Signed Int maximum)
        $value = RegEnumVal($bag_key, $i)
        If @error <> 0 Then ExitLoop
        ;ConsoleWrite($value&@CRLF)
        If StringInStr($value, 'ItemPos') Then
            Local $entry[5] = [$display_name, $bag_key, $bag, $value, StringTrimLeft($value, 7)]
            _ArrayFixed_Add($results, $entry)
        EndIf
    Next
EndFunc   ;==>searchbag
Func _ArrayFixed_Add(ByRef $array, $value);adds an item, overwriting the oldest item | NOTE: Edited from original intent, see comments
    Local $x = UBound($array) - 1
    If $array[0] = $x Then Return False; *** decided later that overwriting sucked for systems with many profiles.
    Local $i = Mod($array[0], $x); values from 0 to x-1
    Local $n = $i + 1;(0 to x-1)+1 = 1 to x
    $array[0] = $n; this is also the nonadjusted index for the next item :)
    $array[$n] = $value
EndFunc   ;==>_Array_Fixed_Push


Func ProgressInitial($n = 0)
    $ProgressIncrement = $n
    ProgressSet($n)
EndFunc   ;==>ProgressInitial
Func ProgressIncrement($n = 1)
    $ProgressIncrement += $n
    ProgressSet($ProgressIncrement)
EndFunc   ;==>ProgressIncrement

Func safename($s)
    Return StringRegExpReplace($s, "[^a-zA-Z0-9_\-]", "_")
EndFunc   ;==>safename


Func ProcessKill($p); I should probably credit someone for this function
    Local $Kernel32 = DllOpen("kernel32.dll")
    Local $hproc = DllCall($Kernel32, 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', True, 'int', ProcessExists($p))
    DllCall($Kernel32, "int", "TerminateProcess", "int", $hproc[0], "dword", 1)
    DllClose($Kernel32)
EndFunc   ;==>ProcessKill

UI Arrays were absolutely necessary to maintain conciseness while eliminating Global references.

Edited by crashdemons

My Projects - WindowDarken (Darken except the active window) Yahsmosis Chat Client (Discontinued) StarShooter Game (Red alert! All hands to battlestations!) YMSG Protocol Support (Discontinued) Circular Keyboard and OSK example. (aka Iris KB) Target Screensaver Drive Toolbar Thingy Rollup Pro (Minimize-to-Titlebar & More!) 2D Launcher physics example Ascii Screenshot AutoIt3 Quine Example ("Is a Quine" is a Quine.) USB Lock (Another system keydrive - with a toast.)

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Jahar
      Hi All,
      Please help me on how to fetch date/time of last windows 10 system restore point using autoit? Basically its about querying the last restore point.
    • By Tony007
      Hi,
      is it possible to export only the area "$idOutput" with the TEXT as a PNG?
      Thanks
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> Example() Func Example() Local $hGUI = GUICreate("Test", 700, 700, -1, -1) Local $input1 = GUICtrlCreateInput("", 10, 10, 150, 20) Local $idButtonStart = GUICtrlCreateButton("Start", 200, 10, 50, 30) Local $idButtonClear = GUICtrlCreateButton("Clear", 260, 10, 50, 30) Local $idButtonExport = GUICtrlCreateButton("Export", 320, 10, 50, 30) Local $idOutput = GUICtrlCreateLabel("TEXT", 10, 50, 500, 500, BitOR($BS_PUSHLIKE, $SS_CENTER)) GUICtrlSetFont($idOutput, 45, 800, "", "Impact") GUISetState(@SW_SHOW, $hGUI) ; Run the GUI until the dialog is closed While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButtonStart $ContentInput1 = GUICtrlRead($input1) GUICtrlSetData($idOutput, $ContentInput1) Case $idButtonClear GUICtrlSetData($input1, "") GUICtrlSetData($idOutput, "") Case $idButtonExport EndSwitch WEnd GUIDelete($hGUI) Exit EndFunc ;==>Example  
    • By newbie2019
      Cannot find example how to locate taskbar icon coordinates or position by window handle.
      I want to use PixelChecksum to check only rectangle area over specified taskbar item.
      Please help.
      What I already have found and succesfully run for whole taskbar area:
      $taskbar = WinGetHandle("[Class:Shell_TrayWnd]") $taskbarPos = WinGetPos($taskbar) $tasklistPos = ControlGetPos($taskbar, "", "[CLASS:MSTaskListWClass; INSTANCE:1]")  $iOldCheckSum = PixelChecksum($taskbarPos[0] + $tasklistPos[0], $taskbarPos[1] + $tasklistPos[1], $taskbarPos[0] + $tasklistPos[2], $taskbarPos[1] + $tasklistPos[3]);
      I know also that I can pass window handle as parameter to PixelChecksum, but don't know how to do this with taskbar icon.
       
      Also I was able to find something similar but seems outdated: WatchWindows

      __
      thanks in advance
    • By vargheseg
      I am new to AutoIT but I do use Sikuli.  Decided to use AutoIT for  this project as all  the required can be created in an .exe file, does not  need Java like Sikuli.
      Also  which can be pushed to tool bar of Windows 10 desktop.
      Our users will interact with a client/server application and normally work on dual screen. The script needs to detect the c/s application from the dual screen,  needs to do three mouse clicks based of image/pixel comparison, will need to wait till the  click object is available and then finally take screen capture  of the top 40 rows  and save the .jpeg file to  windows file share location.
      once the file save is completed,  pop up message - the screen capture is completed. Then the users can do their regular work.
      Potentially  other factor that will play are the screen resolution.
      Can anyone guide me to some relevant scripts already in the forum. In the meantime I am learning  the basics of the  tool.
       
      Appreciate feedback and any help
      George V
       
       
    • By KaFu
      ICU - Icon Configuration Utility

      Current Version: v6 (2018-Sep-16)
      Restore your desktop when the icons get "rearranged".
      Melba23 and I found we were working on very similar ideas to restore the Desktop icons to their normal place if they became "rearranged" (
      ). Vista seems to like this doing on occasion just for fun - but we all know some apps and games which change the display resolution or move icons around. This annoys "tidy" people who like their desktops arranged "just so" - I am particularly thinking of this desktop when I say that!
      We combined efforts and here is the result of our labors.
      Operation is easy - press "Save" to store a particular configuration and "Restore" to reset the icons to the saved positions in the selected configuration file. "Delete" allows you to remove unwanted configuration files from the list. There is a command line option so that the restoration can be run via HotKeys if required (that is why the script warns that it should be compiled for full functionality). You can decide what to do with any icons that have been added since you last saved the configuration file - the default is to put them in the top-left corner, but you can also banish them way off-screen or, more sensibly, specify a location for them.
      A new feature as of ICU v3.4 is the optional Desktop Contextmenu Integration (DCI) for Win7 (Win7 only because Microsoft implemented an easy way to do this through the registry as of this release).
      Version 3.3 should fix the empty save file bug
      Version 3.4 Win7: Admin rights no longer needed for DCI
      Version 5.0 Win8 compatibility for DCI
      The source and executable can be downloaded from my site: http://www.funk.eu
      Kudos to Ascend4nt, Melba23, Prog@ndy, & Valik for parts of the code.
      Please let me know if you found some piece of code in the source for which I forgot to mention a credit.
      Enjoy, let me know what you think of ICU and with Best Regards
×
×
  • Create New...