Saturday, February 4, 2017

TaskDialog (Windows API Code Pack)

Several years ago I used the TaskDialog class in some desktop apps as a nice replacement for the simple MessageBox class. Following is a sample of a slightly advanced TaskDialog where you can expand extra information in the footer. You can also use "command links" instead of the standard buttons, add custom controls like check boxes and progress bars, or expand the middle of the dialog instead of the footer.



If I remember correctly, the TaskDialog class was part of the Windows API Code Pack for Microsoft .NET Framework in the MSDN code gallery, but all links now seem to be dead and it looks like the API Code Pack is no longer supported.

Luckily, web searches eventually located some copies of the API Code Pack that had been archived, and surprisingly, the whole lot downloaded and compiled cleanly. I considered extracting the TaskDialog related classes out of the large quantity of complicated Interop code, but then I discovered someone had simply turned the code into a set of NuGet packages. So it's easiest just to use the NuGet package and ignore the extra classes it contains. This is the package to reference:

Microsoft.WindowsAPICodePack.Core

The package library contains the TaskDialog class as well as dozens of other classes which use Interop as bridge to Win32 functions related to networking, power management and the Shell.

For my purposes I only needed a specific subset of the full functionality of the TaskDialog class. I wanted to use the expandable footer with links, and to use "command links" instead of the standard buttons.

Beware of the following:
  • You need an App.manifest file entry to force your application to use a modern version of the Windows common control library. See the file in the sample project.
  • You have to set the dialog's Icon and InstructionText properties in the Opened event, otherwise the dialog may be incorrectly sized. This is an irritating quirk or bug that took a bit of web searching to solve.
  • Clicking a "command link" doesn't close the dialog, you have to call Close in the link's Click handler.