Sign in to follow this  
Followers 0
james3mg

Wallpaper slideshow

9 posts in this topic

#1 ·  Posted (edited)

OK, so this is kind of a "me too" script like ezzetabi's wallpaper changer, but with a few more controls I wanted (and honestly, I didn't realize he had written one, I just saw his function on another thread and wanted to write this). This fairly-configurable script will rotate your desktop wallpaper automatically, as often as you choose. It stores minimal config data in your user's AppData directory under Wallpaper changer. (what folders are included, what files are excluded, and time to wait between changes). This works especially well on Vista with it's nice landscape wallpapers, but I really wanted to be able to easily exclude specific pictures because some of them are quite horrendous also.

When you first fire it up, it will automatically assume you want the wallpapers under Windows\Web\Wallpapers included in the rotation, as well as any pictures that are in the same directory as your current wallpaper. It also directs you to the tray icon for further configuration. The default period is 30 minutes.

Once it's running, you can go back and forward in your "history" of wallpapers (only in the current-running instance -this data is not stored anywhere) using the menu on the Tray icon. You can also choose to never see the current picture again, pause on the current picture, change the time each picture is shown, and go to the next picture (forward if you've gone "back" in your history, otherwise, just advances to another random wallpaper ahead of schedule. You can also open up a GUI that offers slightly more complex controls - adding folders to the rotation (no, this doesn't get pictures out of subfolders, sorry) and browsing for specific pictures to exclude from rotation. All changes take place immediately.

By the way, decimal minutes work in the timing dialog - set it to .01 and get ready to have a seizure! ;-)

Let me know what you think!

:whistle:

edit: code revised to fix issue of .jpg files not working in less than Windows Vista - now XP and below only adds .bmp files to rotation (note there's only one .bmp file in a 'vanilla' XP installation in Windows\Web\Wallpaper, so be sure to add other directories as well). Also fixed the bug of erroring out of the program when all paths are deleted from the list of directories to include in the rotation. Thanks, Dethredic and AutoItR.

@Diveboy: thanks, I'm going to try your code and see if I can allow XP back into the code for including .jpg files, but I think it may be more than just refreshing the desktop that's the issue.

#include <File.au3>
#include <Array.au3>
#include <GUIConstants.au3>
#include <Constants.au3>
Opt("TrayMenuMode",1)

DirCreate(@AppDataDir&"\Wallpaper Changer")
Global $ConfigIniPath=@AppDataDir&"\Wallpaper Changer\Config.ini"
Global $Wallpapers[1]
Global $History[1]=[RegRead('HKCU\Control Panel\Desktop', 'Wallpaper')]
Global $HistoryCurrDisplay=0
Global $WaitTime=Number(IniRead($ConfigIniPath,"Config","WaitTime","1800000"))
Global $Paused=0

TraySetToolTip($History[0])

$Pause=TrayCreateItem("Pause Rotation")
$ChangeTiming=TrayCreateItem("Change time each wallpaper is shown")
$ChangeDirs=TrayCreateItem("Add/Remove pictures from rotation")
TrayCreateItem("")
$PreviousHistory=TrayCreateItem("Go back one wallpaper")
$NextHistory=TrayCreateItem("Next wallpaper")
$DontShow=TrayCreateItem("Don't show this wallpaper again")
TrayCreateItem("")
$About=TrayCreateItem("About Wallpaper Changer 2.0")
$ExitTray=TrayCreateItem("Exit")


Global $DirectoriesArray=IniReadSection($ConfigIniPath,"Directories")
If @error Then
    If StringLeft($History[0],StringInStr($History[0],"\",0,-1)-1) <> @WindowsDir&"\web\wallpaper" Then
        IniWrite($ConfigIniPath,"Directories",Random(0,99999999,1),@WindowsDir&"\web\wallpaper")
        Do
            $rand=Random(0,99999999,1)
        Until IniRead($ConfigIniPath,"Directories",$rand,"<Doesn't Exist>") = "<Doesn't Exist>"
        IniWrite($ConfigIniPath,"Directories",$rand,StringLeft($History[0],StringInStr($History[0],"\",0,-1)-1))
        TrayTip("Wallpaper Changer","You don't have any files selected for rotation."&@CRLF&@CRLF&"To get you started, the default Windows wallpapers have been added, as have all the pictures in the same directory as your current wallpaper."&@CRLF&@CRLF&"Click this tray icon for more options!",20,1)
    Else
        IniWrite($ConfigIniPath,"Directories",Random(0,99999999,1),@WindowsDir&"\web\wallpaper")
        TrayTip("Wallpaper Changer","You don't have any files selected for rotation."&@CRLF&@CRLF&"To get you started, the default Windows wallpapers have been added to the wallpaper rotation."&@CRLF&@CRLF&"To make changes to the wallpapers displayed, click the tray icon down here!",20,1)
    EndIf
    $DirectoriesArray=IniReadSection($ConfigIniPath,"Directories")
EndIf

ReloadWallpaperList()

$FilesGUI=GUICreate("Change wallpaper files in rotation",640,480)
GUICtrlCreateLabel("Directories in rotation:",5,5,300,20)
$DirsList=GUICtrlCreateList("",5,20,300,390,$LBS_NOINTEGRALHEIGHT+$LBS_NOTIFY+$WS_VSCROLL+$WS_BORDER)
$DirsDelete=GUICtrlCreateButton("Remove selected path from rotation",5,410,200,20)
$DirsInput=GUICtrlCreateInput("",5,450,150,20)
$DirsBrowse=GUICtrlCreateButton("Browse",155,450,75,20)
$DirsAdd=GUICtrlCreateButton("Add path",230,450,75,20)
$Thumbnail=GUICtrlCreatePic("",335,0,300,225)
GUICtrlCreateLabel("Files excluded from rotation:",335,230,300,20)
$FilesList=GUICtrlCreateList("",335,245,300,165,$LBS_NOINTEGRALHEIGHT+$LBS_NOTIFY+$WS_VSCROLL+$WS_BORDER)
$FilesDelete=GUICtrlCreateButton("Remove file from exclusion list",335,410,200,20)
$FilesInput=GUICtrlCreateInput("",335,450,150,20)
$FilesBrowse=GUICtrlCreateButton("Browse",485,450,75,20)
$FilesAdd=GUICtrlCreateButton("Add file",560,450,75,20)

Global $timer=TimerInit()
While 1
    If TimerDiff($timer) > $WaitTime AND NOT $Paused Then
        Do
            $rand=Random(1,UBound($Wallpapers)-1,1)
            _ChangeWallpaper($Wallpapers[$rand], 3)
        Until NOT @error
        $timer=TimerInit()
        _ArrayAdd($History,$Wallpapers[$rand])
        $HistoryCurrDisplay=UBound($History)-1
        TraySetToolTip($Wallpapers[$rand])
    EndIf
    
    $msg=TrayGetMsg()
    Switch $msg
        Case $PreviousHistory
            If $HistoryCurrDisplay <> 0 Then
                $HistoryCurrDisplay-=1
                _ChangeWallpaper($History[$HistoryCurrDisplay],3)
            EndIf
        Case $NextHistory
            If $HistoryCurrDisplay+1 = UBound($History) Then
                Do
                    $rand=Random(1,UBound($Wallpapers)-1,1)
                    _ChangeWallpaper($Wallpapers[$rand], 3)
                Until NOT @error
                $timer=TimerInit()
                _ArrayAdd($History,$Wallpapers[$rand])
                $HistoryCurrDisplay=UBound($History)-1
                TraySetToolTip($Wallpapers[$rand])
            Else
                $HistoryCurrDisplay+=1
                _ChangeWallpaper($History[$HistoryCurrDisplay],3)
            EndIf
        Case $ChangeDirs
            RebuildGUILists()
            GUISetState(@SW_SHOW,$FilesGUI)
        Case $ChangeTiming
            $tmp=Number(InputBox("Number of minutes","Please enter the number of minutes you want each wallpaper to be displayed",$WaitTime/60000))
            If NOT @error AND $tmp > 0 Then
                $WaitTime=$tmp*60000
                IniWrite($ConfigIniPath,"Config","WaitTime",$tmp*60000)
            EndIf
        Case $DontShow
            Do
                $tmp=Random(0,99999999,1)
            Until IniRead($ConfigIniPath,"NoDisplay",$tmp,"<Doesn't Exist>") = "<Doesn't Exist>"
            IniWrite($ConfigIniPath,"NoDisplay",$tmp,$History[$HistoryCurrDisplay])
            ReloadWallpaperList()
            Do
                $rand=Random(1,UBound($Wallpapers)-1,1)
                _ChangeWallpaper($Wallpapers[$rand], 3)
            Until NOT @error
            $timer=TimerInit()
            $History[UBound($History)-1]=$Wallpapers[$rand]
            TraySetToolTip($Wallpapers[$rand])
        Case $About
            MsgBox(0,"About Wallpaper Changer 2.0","Wallpaper Changer 2.0 was written by and is under copyright by Michael Garrison, 2007.  All rights are reserved")
        Case $Pause
            If $Paused Then
                $Paused=0
                TrayItemSetText($Pause,"Pause Rotation")
                $timer=TimerInit()
            Else
                $Paused=1
                TrayItemSetText($Pause,"Unpause Rotation")
            EndIf
        Case $ExitTray
            Exit
    EndSwitch
    If WinExists("Change wallpaper files in rotation") Then
        $guiMsg=GUIGetMsg()
        Switch $guiMsg
            Case $GUI_EVENT_CLOSE
                GUISetState(@SW_HIDE,$FilesGUI)
            Case $DirsDelete
                For $i=1 To $DirectoriesArray[0][0]
                    If $DirectoriesArray[$i][1]=GUICtrlRead($DirsList) Then IniDelete($ConfigIniPath,"Directories",$DirectoriesArray[$i][0])
                Next
                ReloadWallpaperList()
                RebuildGUILists()
            Case $FilesDelete
                For $i=1 To $NoDisplay[0][0]
                    If $NoDisplay[$i][1]=GUICtrlRead($FilesList) Then IniDelete($ConfigIniPath,"NoDisplay",$NoDisplay[$i][0])
                Next
                ReloadWallpaperList()
                RebuildGUILists()
            Case $DirsBrowse
                GUICtrlSetData($DirsInput,FileSelectFolder("Select a folder to include in wallpaper rotation",""))
            Case $FilesBrowse
                GUICtrlSetData($FilesInput,FileOpenDialog("File to exclude","","Wallpaper files (*.jpg;*.bmp)"))
            Case $DirsAdd
                $tmp=StringSplit(GUICtrlRead($DirsInput),"|")
                If IsArray($tmp) Then
                    For $i=1 To $tmp[0]
                        If FileExists($tmp[$i]) Then
                            Do
                                $rand=Random(0,99999999,1)
                            Until IniRead($ConfigIniPath,"Directories",$rand,"<Doesn't Exist>") = "<Doesn't Exist>"
                            IniWrite($ConfigIniPath,"Directories",$rand,$tmp[$i])
                        EndIf
                    Next
                    ReloadWallpaperList()
                    RebuildGUILists()
                EndIf
            Case $FilesAdd
                $tmp=StringSplit(GUICtrlRead($FilesInput),"|")
                If IsArray($tmp) Then
                    For $i=1 To $tmp[0]
                        If FileExists($tmp[$i]) Then
                            Do
                                $rand=Random(0,99999999,1)
                            Until IniRead($ConfigIniPath,"NoDisplay",$rand,"<Doesn't Exist>") = "<Doesn't Exist>"
                            IniWrite($ConfigIniPath,"NoDisplay",$rand,$tmp[$i])
                        EndIf
                    Next
                    ReloadWallpaperList()
                    RebuildGUILists()
                EndIf
            Case $FilesList
                GUICtrlSetImage($Thumbnail,GUICtrlRead($FilesList))
        EndSwitch
    EndIf
WEnd


Func ReloadWallpaperList()
    $DirectoriesArray=IniReadSection($ConfigIniPath,"Directories")
    If @error Then
        Dim $Wallpapers[2]
        $Wallpapers[0]=1
        $Wallpapers[1]=$History[$HistoryCurrDisplay]
        TrayItemSetState($DontShow,$TRAY_DISABLE)
        Return
    EndIf
    Dim $Wallpapers[1]
    TrayItemSetState($DontShow,$TRAY_ENABLE)
    For $i=1 To $DirectoriesArray[0][0]
        $tmp=_FileListToArray($DirectoriesArray[$i][1],"*.jpg")
        If NOT @error Then
            For $n=1 To $tmp[0]
                If @OSVersion<>"WIN_95" AND @OSVersion<>"WIN_98" AND @OSVersion<>"WIN_ME" AND @OSVersion<>"WIN_NT4" AND @OSVersion<>"WIN_2000" AND @OSVersion<>"WIN_XP" AND @OSVersion<>"WIN_2003" Then _ArrayAdd($Wallpapers,$DirectoriesArray[$i][1]&"\"&$tmp[$n])
            Next
        EndIf
        $tmp=_FileListToArray($DirectoriesArray[$i][1],"*.bmp")
        If NOT @error Then
            For $n=1 To $tmp[0]
                _ArrayAdd($Wallpapers,$DirectoriesArray[$i][1]&"\"&$tmp[$n])
            Next
        EndIf
    Next
    
    For $n=0 To UBound($Wallpapers);this would break if not for the next line exiting early - necessary because as elements are deleted, the array shrinks without updating this reference to ubound
        If $n+1 > UBound($Wallpapers) Then ExitLoop
        If $Wallpapers[$n]="" Then _ArrayDelete($Wallpapers,$n)
    Next
    
    Global $NoDisplay=IniReadSection($ConfigIniPath,"NoDisplay")
    If NOT @error Then
        For $i=1 To $NoDisplay[0][0]
            For $n=0 To UBound($Wallpapers);this would break if not for the next line exiting early - necessary because as elements are deleted, the array shrinks without updating this reference to ubound
                If $n+1 > UBound($Wallpapers) Then ExitLoop
                If $Wallpapers[$n]=$NoDisplay[$i][1] Then _ArrayDelete($Wallpapers,$n)
            Next
        Next
    EndIf
EndFunc

Func RebuildGUILists();always make sure you're working with a current file list by calling ReloadWallpaperList() just before this function
    GUICtrlSetData($DirsList,"|")
    GUICtrlSetData($FilesList,"|")
    $tmp=""
    If IsArray($DirectoriesArray) Then
        For $i=1 To $DirectoriesArray[0][0]
            $tmp&="|"&$DirectoriesArray[$i][1]
        Next
        GUICtrlSetData($DirsList,$tmp)
    EndIf
    $tmp=""
    If IsArray($NoDisplay) Then
        For $i=1 To $NoDisplay[0][0]
            $tmp&="|"&$NoDisplay[$i][1]
        Next
        GUICtrlSetData($FilesList,$tmp)
    EndIf
    GUICtrlSetImage($Thumbnail,"")
EndFunc

Func _ChangeWallpaper($sFile, $iType)
    If Not FileExists($sFile) Then
        SetError(1)
        Return -1
    EndIf
    Select
        Case $iType = 1
            RegWrite('HKCU\Control Panel\Desktop', 'TileWallpaper', 'reg_sz', '1')
            RegWrite('HKCU\Control Panel\Desktop', 'WallpaperStyle', 'reg_sz', '0')
        Case $iType = 2
            RegWrite('HKCU\Control Panel\Desktop', 'TileWallpaper', 'reg_sz', '0')
            RegWrite('HKCU\Control Panel\Desktop', 'WallpaperStyle', 'reg_sz', '0')
        Case $iType = 3
            RegWrite('HKCU\Control Panel\Desktop', 'TileWallpaper', 'reg_sz', '0')
            RegWrite('HKCU\Control Panel\Desktop', 'WallpaperStyle', 'reg_sz', '2')
        Case Else
        ;
    EndSelect
    RegWrite('HKCU\Control Panel\Desktop', 'Wallpaper', 'reg_sz', $sFile)
    DllCall("user32", "int", "SystemParametersInfo", "int", 20, "int", 0, "str", $sFile, "int", 0)
    Return 0
EndFunc
Edited by james3mg

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites



I love the idea, but can't get it to work.

The wallpapers don't change for me


"Its not about the 30 inch 1080p display, or the SLI 8800 ultras, or the DDR3 memory. It's about when you turn on your PC, does it return the favor?"Math is like sex. Sure, it may give some practical results, but that is not why we do it

Share this post


Link to post
Share on other sites

The wallpapers don't change for me

Time to start troubleshooting, huh? Dang, thought I might have one that worked first time :-)

What OS are you using?

What folder is your pre-existing wallpaper in?

When you go to Add/Remove pictures from rotation in the tray icon, what directories are listed on the left side?

This will help me get this nailed down.

Thanks


"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites

Win XP SP2 - Classic Theme

I chose some custom folders on my comp with my pics in them


"Its not about the 30 inch 1080p display, or the SLI 8800 ultras, or the DDR3 memory. It's about when you turn on your PC, does it return the favor?"Math is like sex. Sure, it may give some practical results, but that is not why we do it

Share this post


Link to post
Share on other sites

Try only picking folders with only .bmp files in them - I noticed on another of ezzetabi's posts referencing this function that ".jpg wallpapers can only be set with Active Desktop" and this dll doesn't work with Active Desktop. Seems like they've fixed that for Vista though, since it's working fine for me.

Let me know if it works with .bmp files under XP.

Thanks for your feedback/patience :">


"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites

I tried it on one XP machine I had access to with some folders with only .bmp files, and it seemed to work fine, unlike with .jpg files. Can anyone else (esp. Dethredic) confirm that? If that seems to be consistent, I'll build in a "If @osversion = Win_95 or Win_98 or Win_ME or Win_NT4 or Win_2000 or Win_XP or Win_2003" exclusion for listing the .jpg files, so that Vista and anything else that ever comes out will include the .jpg files.

Unless someone knows a call for assigning a .jpg as the desktop and refreshing it so it shows up...? :whistle:

Thanks


"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites

not really the clean answer your looking for, but we use this in a vbscript for bginfo pushed out via gpo.

c:\windows\system32\RunDll32.exe USER32.DLL,UpdatePerUserSystemParameters ,1 ,True

this will refreash the desktop when called.

Share this post


Link to post
Share on other sites

it gives me an error when i try to remove a folder from rotation! :whistle: otherwise the script is very good :P

Share this post


Link to post
Share on other sites

it gives me an error when i try to remove a folder from rotation! :whistle: otherwise the script is very good :D

Thanks! :P

Replace your code with the newly-modified code in the first post to get rid of the error! Are you running XP or Vista?


"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

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  
Followers 0