Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows 7: Taskbar Extension in Event in Time Application

0.00/5 (No votes)
12 Jan 2010 3  
Big idea with simple implementation (you use it daily)

Introduction

Because exams are at the door and for businessman events, I made this program to manage events with alarm that you choose from your computer :), and I use the features of Windows 7 in Taskbar. I love it, this shows the time left for the event.
The two buttons show time left for (next event, previous event) without opening the program.

When time left is 0,the program makes an alarm and shows the notes, then the event is deleted.

The green win_taskbar: means the event left time is more.

The yellow win_taskbar: means the event left time is less.

The red one: means the alarm will appear any time.

Background

Before explaining my application, I will explain how to use this technology in your application very easily :).
The technology: Taskbar Extension.
How??? By some steps!

  1. Add these references to your application (Microsoft.WindowsAPICodePack, Microsoft.WindowsAPICodePack.Shell)
  2. Use these namespaces in your application
    (using Microsoft.WindowsAPICodePack.Shell;
    using Microsoft.WindowsAPICodePack.Taskbar;
    )
    And you will find them in file SampleRun.zip behind the Execution file.
  3. Declare these variables at the top of your application before constructor of the form;
    private TaskbarManager win_taskbar = TaskbarManager.Instance;
    private ThumbnailToolbarButton button1;
    private ThumbnailToolbarButton button2;
  4. In the event of shown form, write this:
Button1 = new ThumbnailToolbarButton(Properties.Resources.nextArrow, "Next Event");
Button1.Click += new EventHandler<thumbnailbuttonclickedeventargs>(relatedbutton2_Click);
Button2 = new ThumbnailToolbarButton(Properties.Resources.prevArrow, "Previous Event");
Button2.Click += new EventHandler<thumbnailbuttonclickedeventargs>(relatedbutton2_Click);
TaskbarManager.Instance.ThumbnailToolbars.AddButtons(this.Handle, Button1,Button2);

I make a new instance of the buttons shown in Windows taskbar, then I relate these buttons with event click of buttons on the form to make the same functionality.
Then I add them to the taskbar. And to use loading in Windows taskbar, just do this:

win_taskbar.SetProgressValue(current Value,Maximmum value)

Finish :).

Using the Code

The class holds all data for the events and can compare it with another class, then make inheritance from the interface “IComparable<task>”, to let me make comparison, and make “public static list” to hold all tasks and let me use it from everywhere in my application.

Now go to the code:

 [Serializable]//for load and save events into file
    public class Task:IComparable<Task>
    {
        public static List<Task> CurrentQueue;
        public string Name;
        public DateTime Time;
        public string Notes;
        public DateTime now;
        public Task(string name,DateTime time,string notes)
        {
            Name = name;
            Time = time;
            Notes = notes;
            now = DateTime.Now;
        }
        public Task(string name, DateTime time)
            : this(name, time, "")
        { }
        public Task(string name)
        {
            Name = name;
        }
        public int CompareTo(Task other)
        {
            return Time.CompareTo(other.Time);
        }
   } 

Now in the "Main form":

In this section, I will explain the main form “Class Events”: In the beginning of the class, I define a list of values to hold all total minutes left for your task, and make instance from taskbar and two buttons for taskbar. In the load of the form, I make a new instance of list of tasks and call function open() to load all tasks from the file and store it in this list. Then the function LoadDataGrid() to clear the recent data in grid and fill it with the tasks that I load it from the file. The function Save() to save all current events + new events when I closed the application. And button1 for calling function LoadDataGrid() + storing the difference in time between (time now and the task time) in value list + deleting the tasks that time has gone. Timer1 is to call form of alarm and refresh value list by calling button1. combobox holds values of value list and makes progressbar and Windows taskbar run. In the event shown of the main form, I initialize the two buttons in the taskbar and relate it with two buttons in main form that make the next event and the previous event.

public partial class Events : Form
    {
        List<int> values = new List<int>();
        private TaskbarManager win_taskbar = TaskbarManager.Instance;
		private int steps=0;
        private ThumbnailToolbarButton Nexttask;
        private ThumbnailToolbarButton Previoustask;
		public string filename;
        public Events()
        {
            InitializeComponent();
        }
        private void Events_Load(object sender, EventArgs e)
        {
			steps = 0;
            Task.CurrentQueue=new List<task>();
            Open();
        }
	//to open file and read all events from it and put it in list of events
        private static void Open()
        {
            Stream file = new FileStream("data.bin", FileMode.Open, FileAccess.Read);
            IFormatter formatter = new BinaryFormatter();
            Task.CurrentQueue = (List<task>)formatter.Deserialize(file);
            file.Close();
        }
		//load events in the data grid
        public void LoadDataGrid()
        {
            dataGridView1.Rows.Clear();
             for (int i = 0; i < Task.CurrentQueue.Count; i++)
            {
                if (Task.CurrentQueue[i].Time > DateTime.Now)
                {
                    dataGridView1.Rows.Add(Task.CurrentQueue[i].Name, 
			Task.CurrentQueue[i].Time, Task.CurrentQueue[i].Notes);
                }
            }
        }
	//Save events in file when the program close
        private static void Save()
        {
            // to serialize an object of any serializable class
            IFormatter formatter = new BinaryFormatter();
            Stream file = new FileStream("data.bin", FileMode.Create, FileAccess.Write);
            formatter.Serialize(file, Task.CurrentQueue);
            file.Close();
        }
        //the refresh button for load the time left in minutes to 
        //a new list and sort is Asc.
        //and delete the event that time has been gone.
        public void button1_Click(object sender, EventArgs e)
        {
            LoadDataGrid();
            values.Clear();
            for (int i = 0; i < Task.CurrentQueue.Count; i++)
            {
                TimeSpan temp = Task.CurrentQueue[i].Time-DateTime.Now;
				if (temp.TotalMinutes > 0)
				{
					values.Add((int)temp.TotalMinutes);
				}
				else
				{
					Task.CurrentQueue.RemoveAt(i);
					i--;
				}
            }
            values.Sort();
            cmbtimes.Items.Clear();
            for (int i = 0; i < values.Count; i++)
            {
                cmbtimes.Items.Add(values[i]);
            }
			if (this.cmbtimes.Items.Count > steps)
				this.cmbtimes.SelectedIndex = steps;
			else if (this.cmbtimes.Items.Count != 0)
				this.cmbtimes.SelectedIndex = steps = 0;
			else
				this.cmbtimes.Text = "";
        }
        //timer to check the time for event and make the alarm
        private void timer1_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < Task.CurrentQueue.Count; i++)
            {
                if (Task.CurrentQueue[i].Time >= 
		DateTime.Now&&Task.CurrentQueue[i].Time""new"" dif=""(int)t.TotalMinutes;"" progressbar1.value=""(int)Math.Ceiling((DateTime.Now-Task.CurrentQueue[index].now).TotalMinutes);"" progressbar1.maximum=""(int)Math.Ceiling(t.TotalMinutes);"" t=""Task.CurrentQueue[index].Time"" index=""cmbtimes.SelectedIndex;"" frmaddevent=""new"" this.opacity=""0;"" frmalarm.txtnotes.text=""Task.CurrentQueue[i].Notes;"" frmalarm.visible=""true;"" /> (dif * 3 / 4))
            {
                win_taskbar.SetProgressState(TaskbarProgressBarState.Paused);
            }
            if (progressBar1.Value > (dif * 9 / 10))
            {
                win_taskbar.SetProgressState(TaskbarProgressBarState.Error);
            }
            #endregion
        }
		//make Two button in windows taskbar
		//one for next event
		//other for previous event
		private void Events_Shown(object sender, EventArgs e)
		{
			Nexttask = new ThumbnailToolbarButton
				(Properties.Resources.nextArrow, "Next Event");
			Nexttask.Click += new EventHandler
			<thumbnailbuttonclickedeventargs>(btnNext_Click);
			Previoustask = new ThumbnailToolbarButton
				(Properties.Resources.prevArrow, "Previous Event");
			Previoustask.Click += new EventHandler
			<thumbnailbuttonclickedeventargs>(btnPrevious_Click);
			TaskbarManager.Instance.ThumbnailToolbars.AddButtons
				(this.Handle, Previoustask,Nexttask);
			button1_Click(null, null);
		}
		private void btnNext_Click(object sender, EventArgs e)
		{
			steps++;
			button1_Click(null, null);
		}
		private void btnPrevious_Click(object sender, EventArgs e)
		{
			if(steps!=0)
			steps--;
			button1_Click(null, null);
		}
		//choose file for alarm you want to hear *.wav
		private void chooseFileForAlarmToolStripMenuItem_Click
					(object sender, EventArgs e)
		{
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
			{
				filename = openFileDialog1.FileName;
			}
		}
		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Close();
		}
    }

And now the alarm form: The alarm form receives the file from the main form and if not, I store the file :) for this case to use it by default, and play the alarm when I call the form. Then show the notes of the event.

 Alarm

public partial class alarm : Form
    {
		Events form;
        public alarm(Events form)
        {
            InitializeComponent();
			this.form = form;
		}
		//this Section for playing audio file for the alarm
		#region sound
		[System.Runtime.InteropServices.DllImport
		("winmm.DLL", EntryPoint = "PlaySound", 
		SetLastError = true, CharSet = CharSet.Unicode, 
		ThrowOnUnmappableChar = true)]
        private static extern bool PlaySound(string szSound, 
		System.IntPtr hMod, PlaySoundFlags flags);

        [System.Flags] 
        public enum PlaySoundFlags : int
        {
            SND_SYNC = 0x0000,
            SND_ASYNC = 0x0001, 
            SND_NODEFAULT = 0x0002, 
            SND_LOOP = 0x0008, 
            SND_NOSTOP = 0x0010,
            SND_NOWAIT = 0x00000000, 
            SND_FILENAME = 0x00020000, 
            SND_RESOURCE = 0x00040004 
        }
		#endregion
		//Close button for Press Esc
		private void button1_Click(object sender, EventArgs e)
        {
            Events frmevents = new Events();
			form.Opacity = 100;
			form.button1_Click(this, null);
            this.Close();
        }
		//recive audio file from opendialogfile 
		private void alarm_Load(object sender, EventArgs e)
		{
			//if you don't choose :)
			if (form.filename == null)
			{
				form.filename = "audio.wav";
			}
			PlaySound(form.filename, new System.IntPtr(), 
						PlaySoundFlags.SND_SYNC);
		}
		//Event to play audio file.
		void Sp_LoadCompleted(object sender, AsyncCompletedEventArgs e)
		{
			((System.Media.SoundPlayer)sender).Play();
		}
    }

Points of Interest

My program is useful for students studying subjects in time, for developers doing tasks, and for businessman managing events. It shows in the taskbar. You can know if the event is coming without opening the program, and two buttons to show the next event and previous event in taskbar. I learnt how to work with Windows 7 features and I enjoy with it very much, and learnt Serializable to save classes in file and read it :).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here