In this tutorial you will learn how to interact with the unmanaged Windows API using C# in order to set the desktop background (wallpaper), and use the registry to retrieve the current wallpaper.
While Windows Vista offers quite a nice way of setting the desktop background, how do we do about writting our own code for changing the wallpaper? This tutorial will show you how to use the unmanaged SystemParametersInfo() function in order to change the background picture for all of the latest Windows operating systems, including Windows 2000, XP, Server 2003, Server 2008 and Vista. However, it is important to note that only with Windows Vista you will be able to set a JPEG, PNG, GIF and other such pictures as the desktop background. With Windows XP and other versions of Windows the code only works with Bitmap (BMP) files.
Start by creating a new project in Visual Studio 2005 and on the form drop a PictureBox picThumbnail, a DropDownList ddlStyle containing the values “Fit To Screen”, “Center”, “Tile”, a Button btnSet and finally an OpenFileDialog named openGraphic. The drop-down list is not being used in this tutorial, however you could have it set different combinations for the WallpaperStyle and TileWallpaper registry values you’ll learn about later, in order to have the desktop background in tiles (repeat to fill the screen), stretch, maintain aspect ratio, center, and so on.
Now switch to code view and add the following using statements:
using Microsoft.Win32;
using System.Runtime.InteropServices;
Microsoft.Win32 is used for accessing the registry, while System.Runtime.InteropServices is used for accessing the unmanaged user32.dll.
Next comes the preparation of the unmanaged function SystemParametersInfo() – this should be located at the top of the class definition:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
First thing is to retrieve the current desktop wallpaper, and to do that we don’t need to use a function, but simply read a value in the Windows registry. Let’s create the method for that:
private string GetCurrentWallpaper()
{
   // The current wallpaper path is stored in the registry at HKEY_CURRENT_USER\\Control Panel\\Desktop\\WallPaper
   RegistryKey rkWallPaper = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", false);
   string WallpaperPath = rkWallPaper.GetValue("WallPaper").ToString();
   rkWallPaper.Close();
   // Return the current wallpaper path
   return WallpaperPath;
}
Next comes the definition of the method that actually sets the wallpaper, the main purpose of this tutorial. And it’s only a few lines of code:
private void SetWallpaper(string WallpaperLocation, int WallpaperStyle, int TileWallpaper)
{
   // Sets the actual wallpaper
   SystemParametersInfo(20, 0, WallpaperLocation, 0x01 | 0x02);
   // Set the wallpaper style to streched (can be changed to tile, center, maintain aspect ratio, etc.
   RegistryKey rkWallPaper = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);
   // Sets the wallpaper style
   rkWallPaper.SetValue("WallpaperStyle", WallpaperStyle);
   // Whether or not this wallpaper will be displayed as a tile
   rkWallPaper.SetValue("TileWallpaper", TileWallpaper);
   rkWallPaper.Close();
}
As you can see there are three parameters, one which is the path of the wallpaper, and the other two in different combinations can set the wallpaper as tile, stretch, centered, etc.
Now that we have the two methods in place, we can set the PictureBox to the current desktop background:
private void Form1_Load(object sender, EventArgs e)
{
   // Select the first value of the dropdown by default
   ddlStyle.SelectedIndex = 0;
   // The PictureBox image will fit but keep its aspect ratio
   picThumbnail.SizeMode = PictureBoxSizeMode.Zoom;
   // Show the current wallpaper
   picThumbnail.ImageLocation = GetCurrentWallpaper();
}
And now the final code to add is in the Click event of the btnSet button. This shows the OpenFileDialog so that the user can select a wallpaper, calls the background setting method and sets the PictureBox picture to a thumbnail of the newly picked wallpaper:
private void btnSet_Click(object sender, EventArgs e)
{
   if (openGraphic.ShowDialog() == DialogResult.OK)
   {
      // Preview the wallpaper in a PictureBox
      picThumbnail.ImageLocation = openGraphic.FileName;
      // Fit the PictureBox
      picThumbnail.SizeMode = PictureBoxSizeMode.Zoom;
      // Pass the file path, and two options to specify the wallpaper style
      SetWallpaper(openGraphic.FileName, 2, 0);
   }
}
That’s all folks! And here’s a photo from Central Park being set as the desktop wallpaper: