<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Comment Feed for Channel 9 - Wallpaper Cycler</title>
	<atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler/RSS"></atom:link>
	<image>
		<url>http://ecn.channel9.msdn.com/o9/c4f/images/1067250_100.jpg</url>
		<title>Channel 9 - Wallpaper Cycler</title>
		<link></link>
	</image>
	<description>



&amp;nbsp;
This sample demonstrate simple wallpaper cycler. It expects a folder in which it will find images. Upon startup, it will change the wallpaper, and it will even modify the placement behavior based on the size of the image
 found.



Arian Kulp 
Arian Kulp&#39;s Blog

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Basic or Visual C# Express Editions
Hardware: 
Download: 

C# Download
VB Download







A number of articles ago, a simple wallpaper utility was written. I thought it would be nice to put together some of the concepts that we&#39;ve looked at recently and create a new, enhanced wallpaper changer. Specifically, this application is no longer based
 on a specific file. Instead, it expects a folder in which it will find images. Upon startup, it will change the wallpaper, and it will even modify the placement behavior based on the size of the image found. 
You can read the article now, but for added benefit download a copy of Visual Studio 2005 Express Edition for
C# or Visual Basic. These are free if downloaded during most of 2006, and provide all of the tools necessary to create great applications. After you install Visual Studio Express, download the code for this article from the links at the top. Choose from C# or
 Visual Basic, according to your personal preference—the applications are functionally identical. 
As with most recent In the Box columns, this application will start with no visible interface beyond its notification icon in the system tray. The available options will be to display the settings, change the
 wallpaper on-demand, or exit. The &amp;quot;Show Settings&amp;quot; option is in bold. This is a visual cue that if you double-click the icon, this is the action that will take place. There is no built-in support for this feature. Simply set the menu item&#39;s
Font.Bold property to &amp;quot;True&amp;quot; and create a MouseDoubleClick event handler for the
NotifyIcon control. 

Figure 1: The notification icon menu 
Scanning folders
The heart of the application is its ability to scan a folder randomly to find an image to display as the desktop background. This is surprisingly easy using the
System.IO.Directory class. Its static/shared GetFiles method returns a collection of all files in a given folder. You can optionally pass a wildcard pattern, and a recursive qualifier. It would have made sense to specify a wildcard pattern including
 extensions like .JPG and .GIF, but apparently only a single expression can be used. The third parameter takes an argument of type
System.IO.SearchOption. This is where you can specify a top-level file listing (TopDirectoryOnly), or a recursive (AllDirectories) one. 
Visual Basic 
&#39; Specify top-level or sub-folders
Dim opt As System.IO.SearchOption = _
     System.IO.SearchOption.TopDirectoryOnly

If subfoldersCheckbox.Checked Then
    opt = System.IO.SearchOption.AllDirectories

End If

&#39; Grab complete list of files
Dim files As String() = System.IO.Directory.GetFiles( _
    picturesPathTextBox.Text, &amp;quot;*&amp;quot;, opt)

Visual C# 
// Specify top-level or sub-folders
System.IO.SearchOption opt = System.IO.SearchOption.TopDirectoryOnly;
if( FsubfoldersCheckbox.Checked ) opt = 
    System.IO.SearchOption.AllDirectories;

// Grab complete list of files
string[] files = System.IO.Directory.GetFiles(
picturesPathTextBox.Text, &amp;quot;*&amp;quot;, opt);

At this point, the files object contains an array of strings. Each entry is a fully-qualified filename from within the supplied folder. It would be nice to just randomly select an entry from this collection, but recall that we were not able to filter
 based on file extension. This must be done now. Two other exclusions also apply. First, we don&#39;t want to select the file that was used last time (we save one time back). Second, we don&#39;t want to select the temporary image that we generate (discussed later).
 The following code demonstrates copying the array into a generic List collection, element by element, provided that each element meets our exacting criteria. 
Visual Basic 
&#39; Filter list to remove non-images, last image shown,
&#39; and the app-generated BMP file from a previous run.
Dim filteredFiles As New List(Of String)()

For Each file As String In files

    Dim ext As String = file.Substring(file.LastIndexOf(&amp;quot;.&amp;quot;))

    If &amp;quot;.jpg .bmp .gif&amp;quot;.IndexOf(ext) &amp;gt; -1 AndAlso _
        file.EndsWith(&amp;quot;coding4fun-desktop.bmp&amp;quot;) = False AndAlso _
        Not file = My.Settings.LastImageShown Then

        filteredFiles.Add(file)
    End If
Next
Visual C# 
// Filter list to remove non-images, last image shown,
// and the app-generated BMP file from a previous run.

List&amp;lt;String&amp;gt; filteredFiles = new List&amp;lt;string&amp;gt;();
foreach (string file in files)
{
    string ext = file.Substring(file.LastIndexOf(&amp;quot;.&amp;quot;));

    if (&amp;quot;.jpg .bmp .gif&amp;quot;.IndexOf(ext) &amp;gt; -1 &amp;amp;&amp;amp;

        !file.EndsWith(&amp;quot;coding4fun-desktop.bmp&amp;quot;) &amp;amp;&amp;amp;
        file != settings.LastImageShown)
    {
        filteredFiles.Add(file);
    }
}
After all of this processing, it is possible that no files remain in our collection. Perhaps the folder was empty initially, none of the files were images, or the only image found was used last time. Either nothing will be returned, or a random index will
 be generated to grab one element out of the collection. Recall that these elements are full pathnames. We will save that pathname as the
LastImageShown setting, create a Bitmap object given the pathname, then return that object. 
Visual Basic 
&#39; Make sure there are any files left
If filteredFiles.Count = 0 Then Return Nothing

&#39; Randomly grab a file
Dim filename As String = filteredFiles(rnd.Next(filteredFiles.Count))


&#39; Remember last image shown
My.Settings.LastImageShown = filename
My.Settings.Save()

&#39; Return the bitmap object from this filename
Return New Bitmap(filename)

Visual C# 
// Make sure there are any files left
if (filteredFiles.Count == 0) 
    return null;


// Randomly grab a file
string filename = filteredFiles[rnd.Next(filteredFiles.Count)];

// Remember last image shown
settings.LastImageShown = filename;
settings.Save();

// Return the bitmap object from this filename
return new Bitmap(filename);
Finally the image is saved as a BMP file in the My Pictures folder, and passed to the appropriate system API function,
SystemParametersInfo, to effect the change. Most of this is the same as in the original
In the Box column referenced above, but the original required an image to be in BMP format to begin with. As it turns out, once you have loaded an image into a
Bitmap object, saving as a BMP file format is a single line of code: 
Visual Basic 
&#39; Convert to BMP and save

img.Save(picturesPath, System.Drawing.Imaging.ImageFormat.Bmp)
Visual C# 
// Convert to BMP and save)
img.Save(picturesPath, System.Drawing.Imaging.ImageFormat.Bmp);
Study the SetDesktopBackground static/shared method in WindowsAPI.vb/.cs to see the implementation details. 
Settings 
Because the image to display can vary wildly each time, the settings dialog includes a number of behavioral settings. The first checkbox allows you to specify if sub-folders should be scanned or not. If you are pointing at a collection of home photos divided
 into sub-folders for albums, this could be useful. 
The three ComboBox controls allow some flexibility in how images are displayed depending on their size relative to the desktop size. By default, images larger than the desktop will be stretched to fit. Now the term &amp;quot;stretched&amp;quot; is taken from the Windows
Display control panel. It&#39;s a bit of a misnomer, since what it really means is &amp;quot;stretched or shrunk&amp;quot; in either direction to exactly fill the screen. It&#39;s really ugly if you have a widescreen display and conventional (4:3) images. 
Images smaller than the screen will be centered. The final category, Tiled, is a bit more flexible. If you have very small images, you may want to tile them for a repeating pattern. Just specify how small is small (128 pixels in both directions, by default),
 specify the action (it doesn&#39;t need to be Tiled), and watch it go. I personally like the defaults, but it made some sense to allow them to be preferences so anyone can change them easily. 

Figure 2: Settings dialog 
All of the settings directly correspond to project settings defined in Visual Studio. This nifty feature lets you define settings at the user or application level, set a datatype, and even a default value. Then, to complete the coolness, you can actually
 databind these settings to the controls. All you need to do is load and save when necessary. The mechanics of copying data between controls and settings are taken care of for you! 

Figure 3: Databinding settings 
Working with the Registry 
The application must write to the registry in order to set the stretched/tiled/centered attributes. This is very easy using the
Registry object. Just use a static property, such as CurrentUser to access the HKEY_CURRENT_USER key. You can dig deeper by using a method like
OpenSubKey to open nested keys and access their values. The wallpaper cycler application also uses the registry to add itself to Windows startup. The auto-start
CheckBox control calls some shared/static methods in the WindowsAPI 
class to add and remove itself: 
Visual Basic 
&#39; Based on checkbox, call API functions to add or remove
&#39; application path from registry Run section for current user.

If autostartCheckbox.Checked Then
    WindowsAPI.AddStartupItem(&amp;quot;BackgroundCycler&amp;quot;, _ 
    System.Reflection.Assembly.GetEntryAssembly().Location)
Else
    WindowsAPI.RemoveStartupItem(&amp;quot;BackgroundCycler&amp;quot;)

End If

Visual C# 

// Based on checkbox, call API functions to add or remove
// application path from registry Run section for current user.
            if (autostartCheckbox.Checked)
            {
                WindowsAPI.AddStartupItem(&amp;quot;BackgroundCycler&amp;quot;,
                    System.Reflection.Assembly.GetEntryAssembly().Location);
            }
            else

            {
                WindowsAPI.RemoveStartupItem(&amp;quot;BackgroundCycler&amp;quot;);
            }
Notice the call to System.Reflection.Assembly class. The GetEntryAssembly
method returns a reference to the assembly that contained the startup code for the current application. The
Location property returns the assembly filename, in this case the path to the executable file. In the
AddStartupItem method, the sub-key for the current user&#39;s Run entries is opened, and a new value is added. So simple, but so powerful: 
Visual Basic 
Dim key As RegistryKey = _
    Registry.CurrentUser.OpenSubKey( _
    &amp;quot;Software\Microsoft\Windows\CurrentVersion\Run&amp;quot;, True)
key.SetValue(name, path)
Visual C# 
RegistryKey key = Registry.CurrentUser.OpenSubKey(
                @&amp;quot;Software\Microsoft\Windows\CurrentVersion\Run&amp;quot;, true);

            key.SetValue(name, path);

Potential Enhancements
The application is ready to use, and fun too! You can change wallpaper frequently, even if your images are not already in BMP format, and you don&#39;t need to go into Desktop properties to do it. It might also be fun to add an option to automatically change
 images on a timed interval. Another challenge would be to provide the ability to download images at random from URLs. You could provide a URL to an image gallery, scan the HTML for image links, then randomly select one to download, convert, and show as wallpaper.
 Lots of options! 
Conclusion
I hope this got you thinking about things to do with the Bitmap object, the
Registry object, and desktop interaction. Be sure to visit 
http://msdn.microsoft.com/vstudio/express/ to download your preferred version of Visual Studio 2005 Express Edition. Then, take a look at the source code for this project, learn, and do even more. Good luck, and best of all, have fun! 
</description>
	<link></link>
	<language>en</language>
	<pubDate>Sat, 18 May 2013 20:04:51 GMT</pubDate>
	<lastBuildDate>Sat, 18 May 2013 20:04:51 GMT</lastBuildDate>
	<generator>Rev9</generator>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>Hi Sam! Photos i send on e-mail. </p><p>Green,Hi Sam! Photos i send on e-mail. </p><p>Green</p><p>posted by Hi Sam! Photos i send on e-mail. 
Green,Green</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633130704000000000</link>
		<pubDate>Wed, 25 Apr 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633130704000000000</guid>
		<dc:creator>Hi Sam! Photos i send on e-mail. 
Green,Green</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>I am having trouble with this, I can't seem to get the wallpaper to stay. I can set a wallpaper, and sometimes it will stay the wallapaper until I log out, and sometimes it wont stay at all. By stay, I mean the wallpaper I set appears, then later its just a blue background (or whatever the default background color is). Any help is appreciated... mbmccormick@gmail.com.</p><p>posted by Matt McCormick</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633130704000000000</link>
		<pubDate>Wed, 25 Apr 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633130704000000000</guid>
		<dc:creator>Matt McCormick</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>SystemParametersInfo does not work in Windows Vista</p><p>posted by dshome</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633143664000000000</link>
		<pubDate>Thu, 10 May 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633143664000000000</guid>
		<dc:creator>dshome</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>this is very useful infomation because a made a good progran from it.</p><p>[system error]</p><p>posted by tristan corner</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633146256000000000</link>
		<pubDate>Sun, 13 May 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633146256000000000</guid>
		<dc:creator>tristan corner</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>PingBack from <a rel="nofollow" target="_new" href="http://blog.kirupa.com/?p=116">http://blog.kirupa.com/?p=116</a></p><p>posted by kirupaBlog - If it isn’t broken, take it apart and fix it!  &#187; Blog Archive   &#187; Interesting Links #3: Write Better Code, AK-47, Webcams…</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633210192000000000</link>
		<pubDate>Thu, 26 Jul 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633210192000000000</guid>
		<dc:creator>kirupaBlog - If it isn’t broken, take it apart and fix it!  &#187; Blog Archive   &#187; Interesting Links #3: Write Better Code, AK-47, Webcams…</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>PingBack from <a rel="nofollow" target="_new" href="http://msdnrss.thecoderblogs.com/2007/10/02/multiwall-wallpaper-tool-for-multiple-monitors-3/">http://msdnrss.thecoderblogs.com/2007/10/02/multiwall-wallpaper-tool-for-multiple-monitors-3/</a></p><p>posted by MSDN Blog Postings  &#187; MultiWall - Wallpaper Tool for Multiple Monitors</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</link>
		<pubDate>Tue, 02 Oct 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</guid>
		<dc:creator>MSDN Blog Postings  &#187; MultiWall - Wallpaper Tool for Multiple Monitors</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>Are you more productive with more monitors? Would you be even more productive with better wallpaper management</p><p>posted by Noticias externas</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</link>
		<pubDate>Tue, 02 Oct 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</guid>
		<dc:creator>Noticias externas</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>Are you more productive with more monitors? Would you be even more productive with better wallpaper management?</p><p>posted by Clint</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</link>
		<pubDate>Tue, 02 Oct 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633268944000000000</guid>
		<dc:creator>Clint</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>Cool! I had the same idea, and I'd like to make it in Python!</p><p>My problem is how to say to Windows XP which image to load... (API). Some suggestion?</p><p>Thanks</p><p>posted by Jack</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633282768000000000</link>
		<pubDate>Thu, 18 Oct 2007 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633282768000000000</guid>
		<dc:creator>Jack</dc:creator>
	</item>
	<item>
		<title>Re: Wallpaper Cycler</title>
		<description>
			<![CDATA[ <p>I had some issues with errors on vista and vb 2008. I made the following change and it worked:</p><p>&nbsp; &nbsp; &nbsp; &nbsp;Dim filteredFiles As New List(Of String)()</p><p>&nbsp; &nbsp; &nbsp; &nbsp;For Each file As String In files</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If file.LastIndexOf(&quot;.&quot;) &gt; 0 Then</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dim ext As String = file.Substring(file.LastIndexOf(&quot;.&quot;))</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If &quot;.jpg .bmp .gif&quot;.IndexOf(ext) &gt; -1 AndAlso _</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; file.EndsWith(&quot;coding4fun-desktop.bmp&quot;) = False AndAlso _</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Not file = My.Settings.LastImageShown Then</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;filteredFiles.Add(file)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End If</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End If</p><p>&nbsp; &nbsp; &nbsp; &nbsp;Next</p><p>posted by SlumberMachine</p>]]>
		</description>
		<link>http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633824496000000000</link>
		<pubDate>Mon, 06 Jul 2009 04:00:00 GMT</pubDate>
		<guid isPermaLink="true">http://channel9.msdn.com/coding4fun/articles/Wallpaper-Cycler#c633824496000000000</guid>
		<dc:creator>SlumberMachine</dc:creator>
	</item>
</channel>
</rss>