|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Contents
IntroductionThe program presented here allows you to build a slideshow from pictures and add background music. Everything is packed into a single executable file, so you just need to send one file to distribute your slideshow. What You Can Do with the Program
How the Program WorksThe program builds the slideshow player program using the I will talk more below about the source code of the slideshow player application, which is compiled at run time, but I want to mention one important point here: Regardless of the number of pictures and options that the user has chosen, the source code that is compiled is always the same. It gets all the information from the Code Behind the ApplicationThe BuilderRegistering the ExtensionWhen you launch the program, it associates the *.ssb extension with the program. The project files that you save will have the *.ssb extension, so when you double click them, the SlideShowBuilder will be launched showing the content of the file you have double clicked. The project files have an icon associated with them, too. A command is associated with double click and it passes the name of the file as an argument to the program. All this is accomplished with the code presented below: private void registerextension()
{
//Create necessary keys
RegistryKey RegKey = Registry.ClassesRoot.CreateSubKey(".ssb");
RegKey.SetValue("", "ssb files");
RegKey.Close();
RegKey = Registry.ClassesRoot.CreateSubKey("ssb files");
RegKey.SetValue("", "Slide Show Maker Files");
RegKey.Close();
//Create open command for ssb files
RegKey = Registry.ClassesRoot.CreateSubKey("ssb files" + "\\" + "Shell"
+ "\\" + "Open");
RegKey = RegKey.CreateSubKey("Command");
//Set the application for handling the open command and pass
//the file path as a parameter
RegKey.SetValue("",
"\"" + Application.ExecutablePath + "\"" + " \"%L\"");
RegKey.Close();
//Associate icon for ssb files
RegKey = Registry.ClassesRoot.CreateSubKey("ssb files" + "\\"
+ "DefaultIcon");
RegKey.SetValue("", Application.StartupPath+"\\icon.ico");
RegKey.Close();
}
When you double click the file, the program gets the path of the file as a command line argument. Then the program opens the file that was double clicked. static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 parent = new Form1();
if (args.Length == 1)
{
parent.createchild(args[0]);
}
Application.Run(parent);
}
Saving and Opening Project FilesIn order to save project files for future use, I used serialization again, but this time I used Binary Serialization. The reason is that it is faster and produces smaller files than other serialization techniques. To store information about the project, I have created a class called public void save(string path)
{
Stream str = File.Open(path, FileMode.Create, FileAccess.Write,
FileShare.None);
BinaryFormatter formatter = new BinaryFormatter();
//the getfile() function returns instance of ssbfile
//class for the current project
formatter.Serialize(str, getfile());
str.Close();
isdirty = false;
}
Deserializing is even easier. You only need to remember to cast the result to a proper type. Stream str = File.Open(path, FileMode.Open);
ssbfile file = null;
try
{
BinaryFormatter formatter = new BinaryFormatter();
file = formatter.Deserialize(str) as ssbfile;
}
catch (SerializationException)
{
MessageBox.Show("The file can not be opened", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
finally
{
str.Close();
if (file!=null)
{
this.setsettings(file);
}
this.exists = true;
this.Path = path;
}
Serializing OptionsWhen the build button is clicked, settings are serialized to a temporary file. Using XML serialization is easy, too. The only difference is that you need to specify the type of object you are serializing. private void Serialize(Settings set)
{
Stream stream= File.Open(Form1.temp+"\\settings.xml", FileMode.Create);
XmlSerializer formatter = new XmlSerializer(typeof(Settings));
formatter.Serialize(stream, set);
stream.Close();
}
After this, all the images are copied to a temp folder and their names are changed to 1.jpg, 2.jpg, etc. The reason for this is that the player application will access them using these names. If the names remained the same, either the source code of the player application would have to be changed dynamically or the names would have to be passed to the player, too. Apart from that, this style of naming makes it very easy to know which image comes after which. So at this point, all necessary files have been copied to the temp folder. Now it is time for compilation! Building the SlideshowAs I have already mentioned, to generate an executable file from your program you will need the private bool compile(string path)
{
bool result = false;
using (CSharpCodeProvider code=new CSharpCodeProvider())
{
// create compiler parameters
CompilerParameters compar = new CompilerParameters();
//Set the icon
string pathtoicon = "";
if( !string.IsNullOrEmpty(iconbox.ImageLocation) &&
File.Exists(iconbox.ImageLocation))
pathtoicon=iconbox.ImageLocation;
compar.CompilerOptions = "/target:winexe" + " " + "/win32icon:"
+ "\"" + pathtoicon + "\"";
compar.GenerateExecutable = true;
compar.IncludeDebugInformation = false;
//Add images, music and settings
for (int i = 1; i < filelistbox.Items.Count+1; i++)
{
compar.EmbeddedResources.Add(Form1.temp + "\\" + i.ToString() + ".jpg");
}
if (this.backmusiccheck.Checked && File.Exists(musicpath.Text))
{
compar.EmbeddedResources.Add(Form1.temp + "\\music.mp3");
}
compar.EmbeddedResources.Add(Form1.temp + "\\settings.xml");
compar.OutputAssembly = path;
compar.GenerateInMemory = false;
//Add references
compar.ReferencedAssemblies.Add("System.dll");
compar.ReferencedAssemblies.Add("System.Data.dll");
compar.ReferencedAssemblies.Add("System.Deployment.dll");
compar.ReferencedAssemblies.Add("System.Drawing.dll");
compar.ReferencedAssemblies.Add("System.Windows.Forms.dll");
compar.ReferencedAssemblies.Add("System.Xml.dll");
compar.TreatWarningsAsErrors = false;
//Finally compile it
CompilerResults res = code.CompileAssemblyFromSource(compar,
Properties.Resources.Program);
if (res.Errors.Count > 0)
{
result = false;
}
else
result = true;
}
return result;
}
This is how to build an executable file from your program. Now let's see how to run the slideshow. The PlayerSo we have successfully built the slideshow and we are going to run it. Firstly, I will describe it in general and then go into details. The player application consists of one form, one picturebox and one button. The button is under the picturebox and is not visible. You might be wondering why we need a button at all. The answer is that we need it for disabling the Escape key. The button is set as When you run the generated slideshow, settings are deserialized and various options are set according to it. After that, the slideshow begins. Deserializing OptionsIn order to deserialize options, we need a stream that contains the XML document to deserialize. As the XML document is embedded in the application itself, we can retrieve it using classes and methods in the XmlSerializer ser = new XmlSerializer(typeof(Settings));
Stream st =
Assembly.GetExecutingAssembly().GetManifestResourceStream(
"settings.xml");
set = ser.Deserialize(st) as Settings;
st.Close();
Playing MusicIf the user has added background music, then it will be extracted to temp folder. private string extractmusic()
{
string path = Environment.GetEnvironmentVariable("TEMP") + "\\music.mp3";
//Create stream from the file
Stream musicstream =
Assembly.GetExecutingAssembly().GetManifestResourceStream(
"music.mp3");
//Create necessary streams
BinaryReader read = new BinaryReader(musicstream);
FileStream fs = new FileStream(path, FileMode.Create);
BinaryWriter write = new BinaryWriter(fs);
//Read the file from stream and write to file
byte[] bt = new byte[musicstream.Length];
musicstream.Read(bt, 0, bt.Length);
write.Write(bt);
//don't forget to close the streams
musicstream.Close();
read.Close();
write.Close();
fs.Close();
return path;
}
To play the extracted file, I use this class. It allows you to loop playing very easily. private void playmusic(string path)
{
MP3Player player = new MP3Player();
player.Open((string)path);
player.Looping = set.Loopmusic;
player.Play();
}
Displaying ImagesAfter retrieving the options and setting them, the first picture is displayed. If the user has chosen to advance to the next image by a mouse click, then the application waits for it. Otherwise, after a specified time interval, the image changes automatically. Images are also retrieved using reflection and they are either stretched to full screen or they are left as they are. When a new image is shown, the application is set as private void setimage(int index)
{
Image temp =Image.FromStream(
Assembly.GetExecutingAssembly().GetManifestResourceStream(
index.ToString() + ".jpg"));
if (set.Stretchimages)
{
this.pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
else
{
if (pictureBox1.Height >= temp.Height && pictureBox1.Width >= temp.Width)
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
else
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
pictureBox1.Image = temp;
this.TopMost = true;
current = current % set.Count + 1;
}
That's all !!! Points of InterestXML serialization is quite powerful and easy to use. It helps you to exchange information between different applications. The ability to embed files in an assembly and retrieve them dynamically from the assembly itself is a powerful feature, too. What I like most about this program is that the compiled source code is the same and doesn't depend on the files and options you have chosen. History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||