How to add progress support to an App icon on Windows 7 Taskbar? (C#)

by Vitaly Zayko 13. May 2010 16:33

If you ever work with Windows 7, you already noticed that some Applications could show progress of a long process directly in their icon placed on Windows 7 Taskbar. Good example of this functionality is Internet Explorer when it download a file from Internet or Windows Explorer when you copy/move a file from one location to another. Before .NET Framework 4 era you have had to use external libraries to do this or implement PInvoke by yourself. Now, in your WPF 4 Applications you can use .NET 4 functionality. Here is step-by-step guideline how to do this.

1. Open your progress dialog XAML file. Create reference to Windows.TaskbarItemInfo as very top item of your dialog as shown below (lines 7-9):

1: <Window x:Class="IconProgressDemo.MainWindow" 
2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
4:         Title="MainWindow" Height="130" Width="490"> 
5:      
6:     <!-- Reference to TaskbarItemInfo: --> 
7:     <Window.TaskbarItemInfo> 
8:         <TaskbarItemInfo /> 
9:     </Window.TaskbarItemInfo> 
10:      
11:     <Grid> 
12:         <StackPanel> 
13:             <!-- Regular WPF ScrollBar: --> 
14:             <ProgressBar Name="progressBar" HorizontalAlignment="Stretch" Height="25" /> 
15:              
16:             <!-- Start long process by pushing this button: --> 
17:             <Button HorizontalAlignment="Center" Margin="0,20" Width="65" Height="25" Click="Button_Click">Start!</Button> 
18:         </StackPanel> 
19:     </Grid> 
20: </Window> 
21: 
22: 

2. Switch to code behind of this dialog. Before process start, set a process state (line #52 below). I’ll explain possible states later. Let start with Normal.

3. Pass a process value to TaskbarItemInfo at the same time as to regular progress bar (lines 65-70).

4. When process finishes toy may want to reset both progress bar and TaskbarItemInfo (lines 58-63).

5. Run this example and press Start button. You will see that Task bar icon shows green progress over it self.

TaskbarItemInfo in Normal state

Now, as promised, let see what other ProgressState values for.

TaskbarItemInfo.ProgressState could be one of the following values:

Normal. As you saw above, this value shows regular green progress on App’s icon.

None. This is default value. This is why it’s important to change this value to any other before you start the process. Otherwise you won’t see any progress on your App icon.

Error. Show red progress bar and suitable for emerging cases when, for example, a non-critical error occurs and you don’t want to interrupt the process but let customer know about such case.

Indeterminate. Shows green ‘wave’ or ‘pulse’. Good for processes when you don’t know how long they will take and have to wait until they finish.

Paused. Shows yellow progress and good for interrupted processes. But note that switching to this value doesn’t interrupt the process it self, you still have to do this manually.

The pictures below illustrate Error, Indeterminate and Paused values of ProgressState property:

Error Indeterminate Paused

And here is full code behind of this example:

1: using  System;
2: using  System.Collections.Generic;
3: using  System.Linq;
4: using  System.Text;
5: using  System.Windows;
6: using  System.Windows.Controls;
7: using  System.Windows.Data;
8: using  System.Windows.Documents;
9: using  System.Windows.Input;
10: using  System.Windows.Media;
11: using  System.Windows.Media.Imaging;
12: using  System.Windows.Navigation;
13: using  System.Windows.Shapes;
14: using  System.Threading;
15: using  System.ComponentModel;
16: 
17: namespace  IconProgressDemo
18: {
19:     /// <summary> 
20:     /// Interaction logic for MainWindow.xaml 
21:     /// </summary> 
22:     public  partial  class  MainWindow  : Window 
23:     {
24:         public  MainWindow()
25:         {
26:             InitializeComponent();
27:         }
28: 
29:         private  void  Button_Click(object  sender, RoutedEventArgs  e)
30:         {
31:             // Simulate long process by using BackgroundWorker: 
32:             using  (BackgroundWorker  bw = new  BackgroundWorker ())
33:             {
34:                 bw.WorkerReportsProgress = true ;
35: 
36:                 // Pass process data: 
37:                 bw.ProgressChanged += new  ProgressChangedEventHandler (bw_ProgressChanged);
38: 
39:                 // Reset the counter: 
40:                 bw.RunWorkerCompleted += new  RunWorkerCompletedEventHandler (bw_RunWorkerCompleted);
41: 
42:                 bw.DoWork += (p, ev) =>
43:                     {
44:                         for  (int  i = 0; i <= 100; i += 10)
45:                         {
46:                             Thread .Sleep(1000);
47:                             ((BackgroundWorker )p).ReportProgress(i);
48:                         }
49:                     };
50: 
51:                 // Set the progress state: 
52:                 TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState .Normal;
53: 
54:                 bw.RunWorkerAsync();
55:             }
56:         }
57: 
58:         void  bw_RunWorkerCompleted(object  sender, RunWorkerCompletedEventArgs  e)
59:         {
60:             // The process was finished, reset the counter: 
61:             progressBar.Value = 0;
62:             TaskbarItemInfo.ProgressValue = 0;
63:         }
64: 
65:         void  bw_ProgressChanged(object  sender, ProgressChangedEventArgs  e)
66:         {
67:             // Pass process counter to both ProgressBar and TaskbarItemInfo: 
68:             progressBar.Value = e.ProgressPercentage;
69:             TaskbarItemInfo.ProgressValue = (double )e.ProgressPercentage / 100;
70:         }
71:     }
72: }
73: 
74: 

Have fun!

Technorati Tags: ,
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: , ,

Code Snippets

Encoding a string with MD5 in C#

by Vitaly Zayko 27. March 2010 16:43

It is a common sense to keep user passwords encoded so they won't be compromised in case of hacker attack. Here is simple function doing this:

 /// <summary>
 /// Encodes a string using MD5. Don't forget to add ref. to System.Security.Cryptography
 /// </summary>
 /// <param name="password">A string to encode</param>
 /// <returns>Encoded string in Hex format</returns>
 public static string EncodeString(string password)
 {
     string md5encoded;
 
     // MD5 is disposable:
     using (MD5 md5 = new MD5CryptoServiceProvider())
         md5encoded = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(password)));
 
     // Removing dashes to shrink result length:
     return md5encoded.Replace("-", String.Empty);
 }
 

This function will return you string similar to this: E10ADC3949BA59ABBE56E057F20F883E.

Doesn't look like common MD5 string, should be like this: 4QrcOUm6Wau+VuBX8g+IPg== isn't it? To convert our result to such view we need just Bas64 it. Use this line instead of on example above:

 md5encoded = Convert.ToBase64String(md5.ComputeHash(Encoding.ASCII.GetBytes(password)));

So the whole function becoming to this:

 public static string EncodeString(string password)
 {
     string md5encoded;
 
     // MD5 is disposable:
     using (MD5 md5 = new MD5CryptoServiceProvider())
         md5encoded = Convert.ToBase64String(md5.ComputeHash(Encoding.ASCII.GetBytes(password)));
 
     // Removing dashes to shrink result length:
     return md5encoded;
 }
 

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Is Power of 2? (C#)

by Vitaly Zayko 13. March 2010 17:09

Continue playing with Integers. Here is how to determine if a number is power of 2 or not:

 /// <summary>
 /// Checks if an integer is power of 2
 /// </summary>
 /// <param name="i">An int number to check</param>
 /// <returns>true if i is power of 2, false if otherwise</returns>
 public static bool IsPower2(int i)
 {
     return (i != 0) && ((i & -i) == i);
 }
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Odd or Even? (C#)

by Vitaly Zayko 24. February 2010 21:15

How to quickly determine is given number odd or even? There are several simple methods.

Here is the first one:

 

 public bool IsEven(int i)
 {
     return (i & 1) == 0;
 }

And the second:

 public bool IsEven(int i)
 {
     return (i % 2) == 0;
 }

 

Technorati Tags:
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Another way to get path to a running assembly or how to get list of command line arguments in a non console App?

by Vitaly Zayko 23. December 2009 16:58

There is an another way how to get path to a running assembly from itself besides I mentioned here. Use this simple snippet:

string[] cmd = Environment.GetCommandLineArgs();
string path_to_assembly = cmd[0];
/* cmd[1] and above contains command line arguments is any */

Resulting array is at least one element length or longer. First element of this array always contains path to the assembly. As a side effect – you can get command line params beginning from second element.

Unfortunately doesn’t work in .NET Compact Framework.

Technorati Tags: ,
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Adding /r/n in .NET (C#)

by Vitaly Zayko 30. November 2009 16:05

When your App outputs some text, you probably will want to split your strings by adding carriage return. Of course, you can declare this as a constant string: private const string CRLF = "/r/n";

or use predefined constant from Environment: Environment.NewLine

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Using Windows 7 Jump List in Visual Studio 2010 Beta 2

by Vitaly Zayko 2. November 2009 20:48

If you are on Windows 7, you probably have noticed about new feature – Windows 7 Jump List. If you right-click on an App icon (let say – Internet Explorer) you will see additional menu items which you as a programmer can handle in your solutions. If you are on Visual Studio 2008, the only way is to use an additional Windows API Code Pack for Microsoft .NET Framework. But there is a modern way for Visual Studio 2010 (at least for WPF):

  • Open App.xaml file of your App
  • Add reference to JumpList as shown below:

<Application x:Class="WpfApplication1.App"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             StartupUri="MainWindow.xaml">

    <Application.Resources>    

    </Application.Resources>

    <!-- Add reference to JumpList here: -->

    <JumpList.JumpList>

        <JumpList ShowFrequentCategory="True" ShowRecentCategory="True">

            <JumpTask Title="Notepad"

                      Description="Open Notepad"

                      ApplicationPath="notepad.exe"

                      IconResourcePath="notepad.exe"/>

        </JumpList>

    </JumpList.JumpList>

</Application>

Technorati Tags: ,,
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: , ,

Code Snippets | Visual Studio Tip

Detect how many CPUs (or cores) available on a system? (C#)

by Vitaly Zayko 21. July 2009 11:30

Quite important to be prepared for the Parallel Computing.
This will show you how lucky your system is Smile:

int cpu = System.Environment.ProcessorCount;

Greetings!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

C#: How To Disable Windows Screensaver programmatically?

by Vitaly Zayko 18. May 2009 15:22

In some cases you may want to prevent Windows screensaver from running. For example, when a customer watch video or does VoIP call, his mouse and keyboard activities are low.

I didn’t find a managed function in .NET Framework but fortunately we can make it through PInvoke.

1. Add PInvoke namespace:

using System.Runtime.InteropServices;

2. Import SystemParametersInfo function and its enums as below:

public enum SPI : uint
{
   SPI_GETSCREENSAVEACTIVE = 0x0010,
   SPI_SETSCREENSAVEACTIVE = 0x0011
}
public enum SPIF : uint
{
   None = 0x00,
   SPIF_UPDATEINIFILE = 0x01,
   SPIF_SENDCHANGE = 0x02,
   SPIF_SENDWININICHANGE = 0x02
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref uint pvParam, SPIF fWinIni);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, uint pvParam, SPIF fWinIni);

3. You may want to check is screensaver enabled by Control panel setting or not:

uint vParam = 0;
if (SystemParametersInfo(SPI.SPI_GETSCREENSAVEACTIVE, 0, ref vParam, SPIF.None))
{
   if (vParam == 1)
       MessageBox.Show("Screensaver is enabled");
   else
        MessageBox.Show("Screensaver is disabled");
}
else
    MessageBox.Show("Error!");

4. And finally - disable it:

if (SystemParametersInfo(SPI.SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF.None))
{
   MessageBox.Show("Screensaver has been disabled");
}
else
    MessageBox.Show("Error!");

5. Don’t forget to re-enable if it was enabled initially:

SystemParametersInfo(SPI.SPI_SETSCREENSAVEACTIVE, 1, 0, SPIF.None);
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

How to send HTML e-mail with an image embedded in its body? (C#)

by Vitaly Zayko 20. February 2009 13:56

I’m trying to cover two common questions in one post:

  1. How to send an HTML message by SMTP?
  2. How to embed a picture into its body?

Follow the C# code below.

// Use AlternateView to create HTML body ("cid:image" - here we place the image):
using(AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
   "This is an <b>Html</b> e-mail message with <i>embedded image</i> below\r\n<img src='cid:image'>",
   null, "text/html"))
{
   // Create LinkedResource to specify an embedded image:
    using (LinkedResource image = new LinkedResource("c:\\IMAGE.jpg"))
   {
       // ContentId should be equals to the CID that we specified above
        image.ContentId = "image";
       htmlView.LinkedResources.Add(image);

       mail.AlternateViews.Add(htmlView);

       // Create SmtpClient as reqular:
        SmtpClient smtp = new SmtpClient("mail.zayko.net");

       // Set Credential if needed:
        smtp.Credentials = new System.Net.NetworkCredential("mailusername", "mailpassword");

       // ...and here we go:
        smtp.Send(mail);
   }
}

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Code Snippets

Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

About the author

Vitaly Zayko

Senior Software Developer / Team Lead / Product Manager

Moscow, Russia