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

Windows 7: New Features Explained using .NET

0.00/5 (No votes)
29 Mar 2021 3  
New Win7 features explained with simple demo applications
In this article, new Windows 7 features like Jumplist, Taskbar Progressbar, Tabbed Thumbnail, Icon Overlays, Application Restart Data Recovery, Network Management, Power Management, Task dialog, Sensor API, etc. are explained with simple demo applications

Windows7APICodePack/Windows-7-SDK.jpg

Table of Contents

Introduction

Windows 7 is Microsoft's latest version operating system. As many of you wonder what are the basic facilities that we will get which is absent in Windows Vista, or why you should go for it, basically this was also in my mind, but after I tried it, I found this is much better than the one that I was using.

Features of Windows 7

Windows now runs much faster than the other operating system (Such as Vista) while consuming lesser amount of resources. It reduces the background activities just by triggering start of important services when they are actually required. So Network Discovery service will only start when you actually connect your computer to a network, rather than going this process over and over in background. Thus services will run only when they are required and stopping them will release all the resources that it was utilizing.

The most interesting thing that I found was that not only do we need to rely this on background windows services, but we can easily configure our own service to facilitate this just by switching to Trigger Start Services or Scheduled Tasks. You can read the article, Windows Trigger Start Service, if you want to create your own Windows service using this.

In this article, we will discuss some of the exciting new features that Windows 7 brought to us which relate to User Interface look and feel, API changes, etc.

New Features of Windows 7 Exposed in API Code Pack

  1. Application Restart and Recovery API
  2. Windows 7 Taskbar Jump Lists, Icon Overlay, Progress Bar, Tabbed Thumbnails and Thumbnail Toolbars
  3. Sensor Platform APIs
  4. Windows 7 Task Dialogs
  5. Windows 7 Common File Dialogs including custom controls
  6. Explorer Browser Control
  7. Windows 7 Shell Search API Support, drag and drop functionality for shell objects, etc.
  8. Network List Manager APIs
  9. Extended Linguistic Services APIs
  10. Shell Property System
  11. Windows 7 libraries, known folders, non-file system containers
  12. Power Management APIs
  13. Direct 3D support for 11.0, 10.1/ 10.0, Direct 2D, Directwrite, Windows Imaging Component (WIC) APIs, etc.
  14. Many more...

If you want to read about all the other features that Windows introduced in this version, please follow this link.

Windows API Code Pack

In .NET 4.0, the features of Windows 7 are not (except a few) exposed properly. So we need to rely on calling API directly by creating InterOp services to them. To make these features available directly for applications, Windows published an open source project here. This project is basically a COM wrapper, so that the complexity of the code could be reduced. In this article, I am going to demonstrate most of the interesting features that Windows 7 introduced through Windows API Code Pack.

Minimum Requirement

The minimum requirement to run the sample applications is Visual Studio 2008 (preferably 2010) with .NET framework 3.5 SP1 and of course, Windows 7 Environment.

Note: All the samples are Windows Forms Application to reduce the complexity and also for those who don't know WPF applications much.

Getting Started

Before you proceed further, first extract the Windows API Code Pack and Open \WindowsAPICodePack\WindowsAPICodePack.sln in Visual Studio 2010 / Visual Studio 2008 SP1 and compile the application. This will produce DLLs inside Bin\debug folder of all the compiled projects. Now close the application, and start Visual Studio again. (Preferably, VS 2010 as I created all sample applications using it) and create a new Windows Application.

A project will be created with a blank Form in it. Now you have two options:

  1. Add reference to the WindowsAPICodePack DLLs. To do so, just right click on the Project and Add Reference, and add all the necessary DLLs that you need.

    Windows7APICodePack/GettingStarted2.jpg

  2. Directly add the projects when required. Just right click on the Solution Explorer, and go to Add Existing Project to add the respective project. Generally, we need Core to be added for all applications.

    Windows7APICodePack/GettingStarted.jpg

After you finish this, you are ready to create your first Windows 7 Application.

In all the sample applications, I have added the projects directly to the application, so while you try those, if you find error message that projects cant be loaded, Please remove them from solution and in the same way mentioned here.

Application Restart and Recovery API

Application Restart API introduced with Windows Vista is a unique feature to recover lost data whenever the application crash takes place or the application is terminated abruptly. Microsoft built an API Support to all its application to recover lost data. You might already been familiar with this in Vista or even in Office applications which could easily recover unsaved data during its recovery process. In Vista, if a program terminates, it opens a dialog box, regarding the problem, and before closing the application, it invokes the Recovery functionality to ensure that the data feed into the application is not lost due to this error.

Windows7APICodePack/AppRecovery.jpg

Windows 7 API supports Application Restart Recovery. We might use this feature in our own application quite easily just by registering our application to ApplicationRestartRecoveryManager.

ApplicationRestartRecoveryManager.RegisterForApplicationRestart(
               new RestartSettings("/recover", RestartRestrictions.NotOnPatch));
RecoveryData data = new RecoveryData(new RecoveryCallback(RecoverData), null);
RecoverySettings settings = new RecoverySettings(data, 0);
ApplicationRestartRecoveryManager.RegisterForApplicationRecovery(settings);

The above code registers the application to RestartRecoveryManager if the application is terminated by Windows Error Reporting. It should be noted that Windows automatically opens a crashed application with /recover command line argument. So, we are using this argument to ensure that the application is restarted after a crash.

ApplicationRestartRecoveryManager.RegisterForApplicationRestart registers the application to invoke the Restart functionality when application is restarted.

RecoveryData data = new RecoveryData(new RecoveryCallback(RecoverData), null);

By this line, we define the callback RecoverData which will be automatically called in whenever Restart Takes place. RegisterForApplicationRecovery takes an argument of RecoverySettings which actually registers the application to recovery.

To Store Data During Recovery

In the RecoverData, we write:

if(ApplicationRestartRecoveryManager.ApplicationRecoveryInProgress())
	Environment.Exit(2);
//Code to save Data
ApplicationRestartRecoveryManager.ApplicationRecoveryFinished(true);

ApplicationRecoveryInProgress returns true when active recovery of data is going on. Strangely, it returns true when user clicked Cancel button in the Recovery Manager dialog. Thus we Exit the application and don't save the Recovery Data. Otherwise, we write the code to store data and finally call ApplicationRecoveryFinished to ensure that the data is properly written.

To Retrieve Recovery Data

As I have already registered our application to pass /restart command line argument when application is restarted, we just need to find this argument and Recover the Data Accordingly.

string[] arguments = System.Environment.GetCommandLineArgs();
if(arguments.Contains<string>("/restart"))
{
      //Recover the data here. 
}

You can try the sample working application from here.

Windows 7 Taskbar Jump Lists, Icon Overlay, Progress Bar, Tabbed Thumbnails and Thumbnail Toolbars

The next interesting thing of Windows 7 that I am going to introduce is Taskbar. Windows 7 Taskbar is not similar to other windows. It has lots of functionalities like JumpLists, Icon Overlay, Progress Bar, Tabbed Thumbnails, etc. to enhance user experience. Let's create this in our own application.

ProgressBar

TaskbarManager.Instance.SetProgressValue(0, 100); TaskbarManager.Instance.SetOverlayIcon(this.Icon, "NewIcon"); If you place this in Shown Event of Form, it will produce an Icon to the Taskbar just like all other applications, and also set the progress value as 0. 100 is the maximum value that the progressbar can have. Thus to set the progress value from your program, call SetProgressValue again with appropriate value and the progress will be shown on the TaskBarButton. Just like the figure below:

Windows7APICodePack/TaskBarProgress.jpg

In addition to this, you can also set the state of Progress.

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Error);

It will define the different states of the progress:

  • NoProgress: Disables the Progressbar
  • Indeterminate: Shows Marquee Progressbar
  • Normal: Normal Green colored progressbar is displayed
  • Error: Error progressbar in Red Color is displayed
  • Paused: Paused progressbar in Yellow Color is displayed

This way, you use the progressbar extensively.

JumpList

The next important thing that comes into mind is JumpList. JumpLists are a very important feature of Windows 7 Taskbar. You can define shortcuts to common items on right click of the TaskBar Buttons using Jumplist. Say you open calculator very often during the process of running your application. You can just add the custom Jumplist to open Notepad.

In addition to tasklist, you might also enhance the jumplist to create Custom category. Let's see how the code looks like:
Windows7APICodePack/Jumplist.JPG

JumpList list = JumpList.CreateJumpList();
JumpListCustomCategory jcategory = new JumpListCustomCategory("My New Category");
list.ClearAllUserTasks();
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
jcategory.AddJumpListItems(new JumpListItem(Path.Combine(desktop, "a.abc")));
list.AddCustomCategories(jcategory);
            
string systemFolder = Environment.GetFolderPath(Environment.SpecialFolder.System);
//Add links to Tasks
list.AddUserTasks(new JumpListLink(Path.Combine(systemFolder, "notepad.exe"), 
                                                                  "Open Notepad")
{
       IconReference = new IconReference(Path.Combine(systemFolder, "notepad.exe"), 0)
});
list.AddUserTasks(new JumpListLink(Path.Combine(systemFolder, "calc.exe"), 
                                                               "Open Calculator")
{
       IconReference = new IconReference(Path.Combine(systemFolder, "calc.exe"), 0)
});
list.AddUserTasks(new JumpListSeparator()); //Acts as a separator
list.AddUserTasks(new JumpListLink(Path.Combine(systemFolder, "mspaint.exe"), 
                                                                "Open Paint")
{
       IconReference = new IconReference(Path.Combine(systemFolder, "mspaint.exe"), 0)
});

Just place the above code in Form_Shown event and get your custom Jumplist available.
We call JumpList.CreateJumpList to get the object of JumpList. JumpList holds the collection of menu items. There are few sections of Jumplist object.

  1. User Tasks: This section represents the Common Task.
  2. Recent: This section is used to display the recent files.
  3. Custom: You can also define your own Jumplist section using Custom Category.

We call AddUserTasks to add User Tasks. If you right click on the taskbar button, you will see three links will be there in Task Section. JumpListLink is used to define ListItems. We pass the path using Environment.GetFolderPath , which could be used to get special folder paths, and defined the links. The IconReference property of JumpListLink will determine the icon which will be shown just beside the link. We can also use JumpListSeparator to produce a menu separator item in the Jumplist.
To define Custom Category, we create an object of JumpListCustomCategory and call AddJumpListItems or to define in Recent list we call AddToRecent method to the Jumplist object.

Note: For both AddToRecent and JumpListCustomCategory, you need to first register your application to the custom extension that you are using to display the files. Here a.abc could only be opened if I register my application to that extension. You either create an installer to register the extension, or manually do this before running the application.

Thumbnails and Tabbed Thumbnails

Thumbnails and TabbedThumbnails are created when user hovers over a button. Place a picturebox into the form and call this in Form_Shown event, to see the thumbnail is been created.

Say I write like this:

TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip(this.Handle, New Rectangle
(pictureBox1.Location, pictureBox1.Size));

It will produce a Thumbnail of the image that is shown on the picturebox. SetThumnailClip is used to set the thumbnail preview of an image on the Thumbnail section of Taskbar. Notice, you can't see the Image that you choose, you just see the rectangle of the same size as the picture. You can produce the actual picture and show it here.

Toolbar buttons could also be easily added over the Thumbnail. You can use ThumbnailToolbarButton to define custom Toolbar buttons for the Thumbnail preview section. In the Form_Shown event, if you add:

this.thumbButtonNext = new ThumbnailToolbarButton(this.Icon, "Next");
this.thumbButtonNext.Enabled = true;
this.thumbButtonNext.Click +=
   new EventHandler<thumbnailbuttonclickedeventargs>(thumbButtonNext_Click);
this.thumbButtonPrev = new ThumbnailToolbarButton(this.Icon, "Prev");
this.thumbButtonPrev.Enabled = true;
this.thumbButtonPrev.Click += 
   new EventHandler<thumbnailbuttonclickedeventargs>(thumbButtonPrev_Click);

TaskbarManager.Instance.ThumbnailToolbars.AddButtons(this.Handle, 
                                 this.thumbButtonPrev, this.thumbButtonNext);
Taskbar thumbnail

It will produce two toolbar buttons, which has a click handler associated with it. You can see the example in the sample provided with this. Tabbed Thumbnails are used when you have multiple tabpages of the same page. You can use TaskbarManager.Instance.TabbedThumbnail.SetActiveTab to set the preview of the active tab at the center. You can preview the other windows as well.

Let's finish this here. You can find lots of articles using Taskbar feature already, so no use writing too much on this. The concept is very easy (even though it might seem very interesting to you), and you can explore this from here easily.

You can try the sample working application from here.

You can check a great application based on TaskBar features at http://www.fishbowlclient.com/.

Network List Management APIs

Detecting networks and getting network related information of the system is now very simple using Window 7 API Code pack. Network API provides a class Network which interfaces one network. NetworkCollection is the collection of all the networks. If you call NetworkListManager.GetNetworks with network type, will return you all the network the machine has installed.

You might filter networks using NetworkConnectivityLevels. If you call NetworkListManager.GetNetworks (NetworkConnectivityLevels.Connected), it will return you all the networks that the computer is connected to right now.

Network object enumerates all the properties of each network.

NetworkConnection, on the other hand, represents a Connection to a network. You might get NetworkConnectionCollection to a network using Network.Connections. You can get information like DomainType, ConnectionId, etc. from NetworkConnections easily.

NetworkCollection networks = NetworkListManager.GetNetworks(NetworkConnectivityLevels.All);
foreach (Network n in networks)
{
   string name = n.Name;
   string desc = n.Description;
   string domainType= n.DomainType.ToString();
   string isConnected = n.IsConnected.ToString();
   string netid =n.NetworkId.ToString();
   //You can use the other info too. 
   NetworkConnectionCollection connections = n.Connections;
   foreach (NetworkConnection nc in connections)
   {
         string connectionid = nc.ConnectionId;
         string domainType = nc.DomainType;
         string adapterid= nc.AdapterId;
         string connectivity= nc.Connectivity;
         // You can use this info
    }
}

You can try the sample working application from here.

Power Management API

If you are using Laptop / Tablet or any device to run your application, this should be the most exciting feature for you. Sometimes, if you are working on a service that requires long running processes, you might sometimes have to look on the battery level from your application. It is true that you could do this already using direct API calls from your devices but using Windows API Code pack, it is just going to be easiest of what you are doing.

this.lblPowerSource.Text = PowerManager.PowerSource.ToString();
if (PowerManager.IsBatteryPresent)
{
      this.prgBatteryLength.Value = PowerManager.BatteryLifePercent;
}
PowerManager.BatteryLifePercentChanged += new EventHandler
                                       (PowerManager_BatteryLifePercentChanged);

Here, lblPowerSource will show the source of power and Voltage.

void PowerManager_BatteryLifePercentChanged(object sender, EventArgs e)
{
     this.prgBatteryLength.Value = PowerManager.BatteryLifePercent;
     
}

The EventHandler will be called when BatteryLife is changed. I have changed the value of the progressbar on this event. You can easily put the logic to reduce the power consumption based on the value in this event. PowerManager also has some useful properties like IsMonitorOn or IsUpsPresent and events like IsMonitorOnChanged or PowerSourceChanged which might come in very handy.

You can try the sample working application from here.

Windows 7 Task Dialogs

Windows Task Dialog is an alternative to the old windows MessageBox. You all are familiar with MessageBox of Windows and its limitation. TaskDialog is introduced to show more enhanced version of Message. Let's see the code:

TaskDialog taskdlg = new TaskDialog();
TaskDialogStandardButtons button = TaskDialogStandardButtons.Ok | 
               TaskDialogStandardButtons.Cancel | TaskDialogStandardButtons.Retry;
taskdlg.Icon = TaskDialogStandardIcon.Shield;
taskdlg.Caption = "TaskDialogDemo Application Dialog";
taskdlg.InstructionText = "Text here goes as Instruction";
taskdlg.Text = "Text here goes as Details";
taskdlg.StandardButtons = button;
taskdlg.DetailsExpandedLabel = "Label Shown when content is expanded";
taskdlg.DetailsExpandedText = "Expanded Text";
taskdlg.ExpansionMode = TaskDialogExpandedDetailsLocation.ExpandFooter;
taskdlg.ProgressBar = new TaskDialogProgressBar("Task ProgressBar")
{
       Maximum = 100,
       Minimum = 0,
       State = TaskDialogProgressBarState.Normal,
       Value=0
};
taskdlg.Tick += new EventHandler<taskdialogtickeventargs>(taskdlg_Tick);
}
TaskDialogResult res = taskdlg.Show();

This will produce an enhanced MessageBox. The TaskDialog buttons is passed using TaskDialogStandardButtons. You can add Instruction, Text, Collapsible Panel Text and a ProgressBar which will react on an Event TaskDialog.Tick

TaskDialogProgressBar is a special progressbar which you may use to define Maximum, Minimum, State (Error, Pause, Normal, Marquee) and Value.

Windows7APICodePack/TaskDialog.jpg

In the eventhandler, I wrote:

void taskdlg_Tick(object sender, TaskDialogTickEventArgs e)
{
       TaskDialog dlg = sender as TaskDialog;
       if (dlg.ProgressBar.Value == 100)
           dlg.ProgressBar.Value = 0;
       dlg.ProgressBar.Value += 1;
}

Thus, the taskbar progressbar will continue to progress infinitely. You may do this progress to show long running process very easily.

If you are running a WPF application, please add a manifest file to the project and add the following:

<dependentAssembly>
<assemblyIdentity type="win32" 
name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
processorArchitecture="*"  publicKeyToken="6595b64144ccf1df"
language="*"  />
</dependentAssembly> 

Adding this to manifest file of your application will fix the nasty error:

TaskDialog feature needs to load Version 6 of Comctl32.dll but a different version is loaded.

Try out the working sample application from here.

A little Extension (to make the TaskDialog modal):
You might wonder why the TaskDialog which we show is not modal to the parent window. We can easily do that using the code below:

taskdlg.OwnerWindowHandle = this.Handle; 

If this is a WPF application, you should do like this :

WindowInteropHelper ohelper = new WindowInteropHelper(this);
TaskDialog.OwnerWindowHandle = ohelper.Handle; 

You might also create an extension function for ShowDialog if you wish using:

public static class TaskDialogExtension
{
        public static TaskDialogResult ShowDialog(this TaskDialog dlg)
        {
            dlg.OwnerWindowHandle = Form.ActiveForm.Handle;
            return dlg.Show();
        }
}

Just add the class to your Windows application project.

Sensor Platform API

Sensors are another amazing addition to Windows 7 API. It enables you to sense the current environment and change your application accordingly. That means your application will start reacting based on Light and Acceleration. Say you have two types of application, one is bright with high ambient light and another with low one. With Sensor API, you can easily do this.

Sensor API supports two types of Sensor:

  1. AmbientLightSensor
  2. Accelerometer3D

For the time being, I am going to discuss about AmbientLightSensor. You can easily explore Accelerometer3D sensor in almost the same way.

To play with Sensor, the first thing that you consider is SensorManager. It is a static class which manages all the sensors installed. You call GetAllSensors to get all the Sensors, GetSensorsByTypeId which will filter all the available sensors installed based on the Generic Type object passed. You can also call GetSensorBySensorId to get the exact sensor by its ID. To invoke AmbientLightSensor, we use AmbientLightSensor class. First, call in the forms constructor.

SensorManager.SensorsChanged += new SensorsChangedEventHandler(
                                               SensorManager_SensorsChanged);

This will ensure that the Data which is shown in the form reflects when the sensor changes. This event occurs when System list of sensors are changed. This is not mandatory for your application.

public void SensorManager_SensorsChanged(SensorsChangedEventArgs change)
{
            BeginInvoke(new MethodInvoker(delegate
            {
                PopulateData();
            }));
} 

Note that SensorsChanged Event doesn't comes in UI thread, so you can't call PopulateData directly, rather you need to invoke the method using MethodInvoker as this is the main method to marshall to the UI thread.

Alternatively, it is also possible to use the new concept of Invoking UI Thread using SynchronizationContext. You might use:

public void SensorManager_SensorsChanged(SensorsChangedEventArgs change)
{
    SynchronizationContext context = SynchronizationContext.Current;
    
    if(context == null)
         context = new SynchronizationContext();
    context.Send(new SendOrPostCallback( (s) => PopulateData()), null);
} 

If you want to read more about SynchronizationContext, read here.

The main Idea of Populate Data is to show the intensity of light from the available Sensor. We can easily use CurrentLuminousIntensity.Intensity which returns the current intensity of light.

this.currentSensor = new Guid("b4133ea3-c284-4626-a6e3-10bfaf50299f");
AmbientLightSensor sensor = SensorManager.GetSensorBySensorId<ambientlightsensor>(this.currentSensor);
lblSensor.Text = "SensorId = " + sensor.SensorId.ToString();
float current = sensor.CurrentLuminousIntensity.Intensity;
prgSensorProgress.Value = Math.Min((int)current, prgSensorProgress.Maximum);
// Set up automatic data report handling.
sensor.AutoUpdateDataReport = true;
sensor.DataReportChanged += new DataReportChangedEventHandler(DataReportChanged);

The DataReportChanged event is fired only when the current sensor intensity is changed. So we use it to reinitialise the value of progressbar.

public void DataReportChanged(Sensor sender, EventArgs e)
{
  AmbientLightSensor als = sender as AmbientLightSensor;
  BeginInvoke(new MethodInvoker(delegate
  {
      // report data (clamp value to progress bar maximum )
      float current = als.CurrentLuminousIntensity.Intensity;
     prgSensorProgress.Value = Math.Min((int)current, prgSensorProgress.Maximum);
  }));
}

Again the event is called in Non-UI thread, so you need to use BeginInvoke to change the value of Progressbar.

Windows7APICodePack/Sensor.jpg

If you don't have any Sensor installed in your machine, you can easily find a simulation Light sensor as mentioned here.

To try out the sample download from here.

Steps to Change an Existing Application for Windows 7

It is really hard to discuss all the enhancements in a single article, so rather than putting this article further with other concepts, let's ornament an existing WPF application with the Windows 7 features. I have already made an application which I would be using here. The application is nothing but an image management tool. I am going to replace this application to use Windows 7 features.

The main use of the article is Image Management. It allows you to add some images to itself, and you can save those files into an album with extension pkg. Other than this, the application also has the capability to search images recursively within the database.

Windows7APICodePack/sample1.JPG

When you open the window, the Browse and Search Button is enabled. The Browse button allows you to add one Package file or you may add one image file just by choosing an image file in the file open dialog box. After you select a file, the content of the folder or the files defined in the album will be loaded. You can change the Comments of each comment and Save it to the package again. The search button allows you to search an images recursively within the specified folder.

Before we enhance it to Windows 7, we first need to check if the current operating system. To check this, we add App.xaml and handle the Application.Startup event:

if (!CoreHelpers.RunningOnWin7)
{
       MessageBox.Show("You are not running in Windows 7. 
                        You need windows 7 to run this application", 
       					"Application Error", MessageBoxButton.OK, MessageBoxImage.Error);
       Environment.Exit(0);
}

The above command will ensure that the operating system is Windows 7, otherwise the application will stop running after giving you the messagebox.

To start with code, I added the Core and Shell class libraries from API Code Pack and added reference to both of them. Following are the steps:

  • Change CommonFileDialogs: The OpenFileDialog and SaveFileDialog of Microsoft.Win32 is very rigid. First, I need to get rid of them and include the ones that comes with APICodePack. I could have used ExplorerBrowser as well, to design an completely new form and place the explorer there, but I rather be using WindowsAPICodePack.Dialogs here. The code looks like:
    CommonOpenFileDialog fdlg = new CommonOpenFileDialog("Choose an Album or an Image File");
    fdlg.Filters.Add(new CommonFileDialogFilter("Picture Albums","*.pkg"));
    fdlg.Filters.Add(new CommonFileDialogFilter("Image Files", "*.jpg,*.gif,*.png,*.bmp"));
    fdlg.EnsurePathExists=true;
    fdlg.InitialDirectory= KnownFolders.Documents.Path;
    fdlg.IsFolderPicker=false;
    if(fdlg.ShowDialog() == CommonFileDialogResult.OK)
    {
        //   ...
    }

    This will open the same OpenFileDialog but with much more flexibility and cleaner approach. Similar to this, I have also changed the SaveFileDialog with CommonSaveFileDialog. One thing that you might have noticed here, I have set filedialog.InitialDirectory to KnownFolders.Documents. Actually, KnownFolders are just an enumeration that is defined in APICodePack which will allow you to access all the commonly known folders like Documents, Computer, ControlPanel, Desktop, Music, Pictures, Profiles, etc.

  • Change MessageBox with TaskDialog: Another simple thing that might come very handy to us is the TaskDialog. TaskDialog (as already discussed is just a replacement to normal messageboxes but with lots of flexibilities defined within it. So I am going to replace the MessageBox with TaskDialog, an example of which is:

     

    TaskDialog.Show("Note: It stores only metadata related to the Image, 
                     Renaming the original image will affect it.",
                     "Saved Successfully to Disk", "Operation Successful");
  • Application Restart Recovery: To add Application Restart Recovery, we take the same approach as discussed previously. I have registered the application for both Restart and Recovery. I will check the recovery by checking the command line argument passed.
    string[] args = System.Environment.GetCommandLineArgs();
     if (args.Length > 1 && args[1].Equals
        ("/recovery", StringComparison.InvariantCultureIgnoreCase))
    {
           StartRecovery("/recovery");
    }
  • TaskBar Enhancements: Finally, I must add some Taskbar enhancements to the application. Let's add thumbnail view of the selected image and also allow the user to navigate between images. To do so, I added two buttons:
     private ThumbnailToolbarButton _PreviousButton=
    new ThumbnailToolbarButton(new System.Drawing.Icon("prevArrow.ico"), "Previous Image");
     private ThumbnailToolbarButton _NextButton=
    new ThumbnailToolbarButton(new System.Drawing.Icon("nextArrow.ico"), "Next Image");
    Windows7APICodePack/taskbarimg.JPG

    The buttons would be added to the ThumbnailToolbar. To make it interact with the application, let's manipulate the Window.Loaded event and write some code:

    this._PreviousButton.Click += this.ButtonPrevious_Click;
    this._NextButton.Click += this.ButtonNext_Click;
    
    System.Drawing.Rectangle clippingRect = 
    new System.Drawing.Rectangle(new System.Drawing.Point(400, 30), 
    new System.Drawing.Size(Convert.ToInt32(Imgdisplay.ActualWidth), 
        Convert.ToInt32(Imgdisplay.ActualHeight)));
    
    WindowInteropHelper interopHelper = new WindowInteropHelper(this);
    IntPtr handle = interopHelper.Handle;
    TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip(handle, clippingRect);
    TaskbarManager.Instance.ThumbnailToolbars.AddButtons
                   (handle, this._PreviousButton, this._NextButton);

    Thus we added two Buttons in the toolbar and a clip of the image in the Thumbnail view. The eventhandlers should also be added to the buttons to handle events.

Thus, finally our new sample application is ready to go. Instead of changing the whole application and exiting the application for the users running less than Windows 7, you might also check for every step to ensure that your application runs perfectly in all the operating systems.

  • You can download the sample application from here.

Note : Taskbar Thumbnail Preview will not work in some versions of Windows 7 and also Windows 7 running in VPC.

References

To download the sample application:

Conclusion

I have tried to give the most basic usage of the classes, so that it would benefit developers while creating their applications. There are lots of other features too, which I couldn't discuss here. If you want to read more on it, you can try out the samples available with API Code Pack easily.

HISTORY

  • 28th December, 2009: Initial post
  • 30th December 2009: Second Post
  • 3rd January 2010: Third Post
  • 24th January 2010: Fourth Post

Showed how we can covert a normal application to add new features.

Finally, I am not a Windows developer, so if you find any problems with code, please let me know, and also to the benefit of all others.
Thanks for reading, your comments are welcome.

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