Slide Show & Desktop Background Tutorial
In this tutorial I will try to show you how to make a slide show that lets the user select some images and then have them change in the picture box, and also we will implement an advanced feature that changes the desktop backgrounds as same as the picturebox images (this will be an advanced feature)
Again some prep on slide show (Slide Show on Wikipedia)
Let's do a basic step:
Open your IDE and create a project called 'Slide Show' (if you want)
I know you're eager to code but let's first think a bit:
So I imagined the app like this:
1. There will be a picturebox in the middle (I named it picBox)
2. An exit button under it (I named it extBtn)
3. A start button and a stop button over it (I named them startBtn and stopBtn)
4. A button to select the images above all (I named it selectImgsBtn)
5. A textbox to set the timer interval (I named it timerIntervalBox)
6. And a checkbox to select if you want to change the desktop background (I named it setAsWallpaper)
7. A button to reset the original desktop wallpaper (I named it restoreBtn)
But how are we going to realize that:
1. Well we will import some methods from 'user32.dll' to set the desktop wallpaper
2. And we will also need to have a method to get the current wallpaper
3. We would need a string array to hold the file paths, also we need two int (one to hold the total number of images and the other to be the current image counter)
Now we need to design the GUI:
So I came something like this:

I know it looks a little crowded but hey it's nice...
We will leave the methods for setting the desktop wallpaper for the end...
Declarations
So we will need to declare the variables we will be using for the project:
1. As I said we will need a string array to hold the file paths
2. An indicator to set the max number of images
3. An indicator to see what is the current image index
4. And a indicator to see what was the original wallpaper
//Declare the variables that are used in this project
//The string array to hold the file paths
private string[] _filenames;
//The max number of images
private int _maxNum;
//The current image number
private int _currNum;
//Declare a string to hold the original wallpaper
private string _originalWallpaper;
Button Events
Open Button
So now we will code the button that opens the images.
So now you need to add an openFileDialog to the project (you can do that by draging the openFileDialog control from the toolbox to the form)
NOTE: Set the filter property of the openFileDialog to
Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*
NOTE2: Set the 'Multiselect' property of the openFileDialog to true. That will allow to select multiple images as a background.
This will show just images in your dialog (kneat huh?)
Next we will show the dialog and get it's result (what button was pressed)
//Show the openFileDialog
DialogResult result = openFileDialog.ShowDialog();
Now we need to check if the user has clicked open
if (result == DialogResult.OK)
{
}
Next we need to get all the files selected and put them into our string array and set the total number of images
//Set the array file names to the files the user selected
_filenames = openFileDialog1.FileNames;
//Sets the max number of images
_maxNum = _filenames.GetLength(0);
So the code for the open button click event would be:
Spoiler
Start Button
When you click start the program should try to parse the textbox and if it succeds starts the slideshow
So first we need to limit the textbox input to numbers only:
I found a nice way to do this:
Now take a break from this program, and let's create a custom control:
We want a textBox that accepts only numbers, so the most appropriate name I can think of is numer text box. So name it and drag a textBox to the designer.
The only difference between our control and a textBox is that ours will accept only numbers. So we'll need only to add some code:
Write this in the keypress event of the textbox
Declare a local variable to hold the number (if it is a number)
And set the e.Handled to the opposite of int.TryParse(e.KeyChar.ToString(), out _isNumber)
int _isNumber = 0;
e.Handled = !int.TryParse(e.KeyChar.ToString(), out _isNumber);
Next let's do the actual code for the button click event
//Declares a local variable to hold the timer interval
int _interval;
//Tries to parse the timer interval
//If it is parsed then, if not show a message to the user
if (int.TryParse(textBox1.Text, out _interval))
{
//Sets the timer interval
timer.Interval = _interval * 1000;
//Starts the timer
timer.Start();
}
else
MessageBox.Show("First enter a correct time interval!");
I'm leaving the option that the entered string in the textbox isn't a number (although it's less likely), because the user can copy something and paste it in the textbox and that wont be processed by our previously mentioned code...
Stop Button
This one is supposed to be easy, just stop the timer
timer.Stop()
Close Button
This is also easy, just close the form
Close()
Timer Tick
Now actually comes the hardest part... (but it's not that hard)
First we need to check if there are more images to show, if not then stop the timer and pop a messagebox
if (_currNum < _maxNum)
{
//TO DO: Code Here
}
else
{
//Stop the timer
timer.Stop();
//Show the message to the user
MessageBox.Show("No more images ...!");
}
If you want to implement the desktop option later add this in the if statement, it checks if the checkbox is clicked
if (checkBox1.Checked)
{
}
Now for the image changing part:
1. We need to declare an image to hold the current image
2. We need to set the picturebox background image to the previously declared one
3. We need to increase the counter
It could be done like this:
//Image to hold the background is set to the current image Image image = Image.FromFile(_filenames.ElementAt(_currNum)); //Sets the picturebox background picBox.BackgroundImage = image; //Increases the counter _currNum++;
Note: the picturebox background image could be set in single line
picBox.BackgroundImage = Image.FromFile(_filenames.ElementAt(_currNum));
But I think it's more neat to use the above code... (It's up to you to chose how you want to use in your program)
So actually the full code would be
Spoiler
Now would be a good time to compile, build and test what have we done so far...
So do that (It shouldn't have any errors)...
Do you like that? (It's nice isn't it?
NOTE: Set the 'BackgroundImageLayout' property of the pictureBox to 'stretch' that way any image will fit the pictureBox and you don't have to do it programmaticallly.
Now comes the advanced part:
PInvoke
Now for those who don't know what platform invoke is here ya go
Quote
Question:
What is Pinvoke?
Answer:
Platform invoke is a service that enables managed code to call unmanaged functions implemented in dynamic-link libraries (DLLs), such as those in the Win32 API. It locates and invokes an exported function and marshals its arguments (integers, strings, arrays, structures, and so on) across the interoperation boundary as needed.
What is Pinvoke?
Answer:
Platform invoke is a service that enables managed code to call unmanaged functions implemented in dynamic-link libraries (DLLs), such as those in the Win32 API. It locates and invokes an exported function and marshals its arguments (integers, strings, arrays, structures, and so on) across the interoperation boundary as needed.
Source: DotNetFunda
Now told in normal language it is a service that is used to implement functions located in win32 dlls
So that we can use that we need to add the corresponding using statements to our project
using System.Runtime.InteropServices; using Microsoft.Win32;
And then we need to implement the function that changes the desktop wallpaper, but first we import the dll holding tha function (the user32.dll)
//Import the dll that holds the desktop changing method
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SystemParametersInfo(
UInt32 action, UInt32 uParam, String vParam, UInt32 winIni);
//Declare the variables used for the calling of the desktop change method
private const UInt32 SPI_SETDESKWALLPAPER = 0x14;
private const UInt32 SPIF_UPDATEINIFILE = 0x01;
private const UInt32 SPIF_SENDWININICHANGE = 0x02;
When we imported the dll we need to declare the variables that are bound to that function
For a list of pinvoke signatures see PINVOKE.NET
For a tutorial on using Win32 API Interop in C# see this tutorial
So now we need to declare our methods for getting and setting the desktop wallpaper
Our method for setting the wallpaper is:
private void SetDesktopWallpaper(String path)
{
//Call the win32 api that changes the wallpaper
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
Also we need to have a method for getting the original wallpaper (we will do this in a different way)
For this we will use the registry.
We will declare a local variable that will hold the reg key that actually holds the wallpaper path
Then we will declare a string that will hold the actual path, get the path the return it
private string GetWallpaper()
{
//Get the key that holds the wallpaper
RegistryKey wallPaper = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", false);
//Set the wallpaper path to the one in the key
string WallpaperPath = wallPaper.GetValue("WallPaper").ToString();
//Close the reg key
wallPaper.Close();
//Return the wallpaper
return WallpaperPath;
}
So now we need to code the button that will restore the original wallpaper
Form Load
As soon as the form loads we need to set the original wallpaper
So this goes in the form load event
//Set the original wallpaper to the current one
_originalWallpaper = GetWallpaper();
Restore Button
We need to set the wallpaper (using our method) to the original wallpaper
Since this is actually meddling with windows we will implement a safety mechanism... (Not that this is much of a safety mechanism HAHA!
//Try this line of code, if it throws an exception
try
{
//Restore the original wallpaper
SetDesktopWallpaper(_originalWallpaper);
}
catch (Exception ex)
{
//Catch it and show it to the user
MessageBox.Show("There was an error in setting the desktop background! " + ex.Message);
}
Now we will return to the timer tick event...
Remember the 'TO DO' we added?
Now is the time to replace it...
We will also implement a safety mechanism here also (you remember, the useless one, that just shows a message? )
So set the desktop wallpaper to the current path (from the string array of paths we set in the open button)
//Try this line of code, if it throws an exception
try
{
//Set the desktop wallpaper
SetDesktopWallpaper(_filenames.ElementAt(_currNum));
}
catch (Exception ex)
{
//Catch it and show it to the user
MessageBox.Show("There was an error in setting the desktop background! " + ex.Message);
}
Well that was the end, if you need extra source download the solution I uploaded here...
NOTE: The solution uploaded here could get outdated so I suggest you visit my GitHub
Full Code Here:
Spoiler
If you still need extra guidance please post it here so that I can help you...
Also if you find any bugs post them to the GitHub interface...
This post has been edited by Atli: 07 January 2012 - 07:12 AM





MultiQuote





|