Click here to Skip to main content
Click here to Skip to main content

TaskDialog for WinForms

By , 5 Jan 2007
 

Introduction

Vista's new TaskDialog API’s are really cool and should see lame message boxes banished from you application. We've already seen some articles on using them from C++ but they are not trivial to use from managed code, so here is some code that makes using all the features of the new Task Dialogs really easy in WinForms.

The code is C# and is StyleCop, FXCop and PreSharp clean. Usability and discoverability were given preference to performance and size, with plenty of comments that should be really useful in Intellisense as you explore what Task Dialogs can do. You don’t have to use anything with a shouted (all capitals) name and all the features of Task Dialog are exposed including the callback and actions you can perform on an active Task Dialog. If you hate the very idea of wrappers and want the raw interop declarations, they are all there too.

Using the code

The main class is TaskDialog. The simplest usage gets you MessageBox behavior:

    TaskDialog taskDialog = new TaskDialog();
    taskDialog.WindowTitle = "My Application";
    taskDialog.MainInstruction = "Do you want to do this?";
    taskDialog.CommonButtons = TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No;
    int result = taskDialog.Show();
    if (result == (int)DialogResult.Yes)
    {
        // Do it.
    }

TaskDialog with Yes No buttons

From there you can add hyperlinks for help, more structure (adding content, extended info and footer to main instruction), a checkbox for "don’t ask me again", custom button names, etc.:

    private void SampleUsageComplex()
    {
        TaskDialog taskDialog = new TaskDialog();
        taskDialog.WindowTitle = "My Application";
        taskDialog.MainInstruction = "Do you want to do this?";

        taskDialog.EnableHyperlinks = true;
        taskDialog.Content = "If you do this there could be all sorts of consequences. " +
            "If you don't there will be other consequences. " +
            "You can <A HREF=\"Learn\">learn more about those consequences </A> or more " +
            "about <A HREF=\"blah\">blah blah blah</A>.";
        taskDialog.Callback = new TaskDialogCallback(this.MyTaskDialogCallback);
 
        taskDialog.VerificationText = "Don't ask me this ever again.";
        taskDialog.VerificationFlagChecked = false;
 
        TaskDialogButton doItButton = new TaskDialogButton();
        doItButton.ButtonId = 101;
        doItButton.ButtonText = "Do It";
 
        TaskDialogButton dontDoItButton = new TaskDialogButton();
        dontDoItButton.ButtonId = 102;
        dontDoItButton.ButtonText = "Don't Do It";

        taskDialog.Buttons = new TaskDialogButton[] { doItButton, dontDoItButton };
 
        bool dontShowAgain;
        int result = taskDialog.Show(null, out dontShowAgain);
        if (dontShowAgain)
        {
            // Suppress future asks.
        }
        if (result == doItButton.ButtonId)
        {
            // Do it.
        }
    }

    private bool MyTaskDialogCallback(
        ActiveTaskDialog taskDialog, 
        TaskDialogNotificationArgs args, 
        object callbackData)
    {
        if (args.Notification == TaskDialogNotification.HyperlinkClicked)
        {
            if (args.Hyperlink.Equals("Learn", StringComparison.Ordinal))
            {
                // Show a help topic.
            }
            else if (args.Hyperlink.Equals("blah", StringComparison.Ordinal))
            {
                // Show a different help topic.
            }
        }
        return false;
    }

TaskDialog with hyperlink and verify checkbox

To get a better idea of all the things you can do with a TaskDialog download the demo, extract the TaskDialogTest.exe and TaskDialog.dll to the same directory and run TaskDialogTest.exe. You'll get a rather large dialog which, while not beautiful, will let you try out the TaskDialog and perhaps sample what different uses in your application would look like.

TaskDialog with hyperlink and verify checkbox

To make use of TaskDialog in your own solution, download the source and include the following source files in your project and adapt them as you see fit:

  • ActiveTaskDialog.cs
  • TaskDialog.cs
  • TaskDialogNotificationArgs.cs
  • UnsafeNativeMethods.cs

Alternatively you could include the TaskDialog project into you solution.

I look forward to seeing a lot fewer Message Boxes in you applications and I hope this makes it easier. Keep in mind good UI design when you're tempted to use all those features in the one dialog.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

KevinGre
Software Developer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralVote of 5memberMember 807878515 Jun '12 - 11:51 
Great article!!! Thumbs Up | :thumbsup: Thumbs Up | :thumbsup: Thumbs Up | :thumbsup:
GeneralMy vote of 5membereaviles30 Mar '12 - 8:06 
Very helpful!
QuestionFont Changing... And A QuestionmemberSaeed Masoomi7 Dec '11 - 10:39 
Hi,
I Want Change This Great TaskDialogs Fonts And Use For Example Tahoma,
Can Anyone Help Me?
 
And a question that is this work in windows XP?
 
tnx
GeneralLicensememberuser303425 Feb '11 - 0:31 
Excellent article this one !!
 
I am planning to use this source code in one of my commercial application for my company. Can I use it ? Do I need to mention your name or anything like that ?
 
I went through The Public Domain dedication. But it's quite confusing.
 
Please let me know what all should I do in order to use this source code.
 
Thanks and really appreciate your article.
GeneralCitrix and expanded infomemberStefanie Knapp17 Jul '09 - 0:57 
First of all, thanks for this great work!
 
But I have got one problem with it:
The dialog does not seem to appear on Citrix systems when it contains expanded info.
 
Anyone who has got the same problem? What can I do?
 
Thanks!
QuestionHow change the MainInstruction textmembermelnac9 Jan '09 - 11:57 
Hi,
how can change the MainInstruction text from within the CallBack function ?
 
I call the taskDialog.UpdateMainInstruction method as i use the taskDialog.SetProgressBarPosition to change the position value for the progress bar.
 
I saw that in the EmulateTaskDialog class i need to extend the WndProc to catch the message, but the MainInstruction remains always the same.
 
Can you help ?
Can you explain how to use the Callback function ?
 
Thanks in advance,
Giuseppe.
GeneralIssue in parameter to EnableButton() and EnableRadioButton() when calling from VB.NETmemberAndrewCushen18 Dec '08 - 16:58 
This is great work, and is much appreciated; I started to do this myself in VB.NET, but ran out of time and kept hitting walls with the unsafe code.
 
You may, however, wish to document that there's a minor issue in the EnableButton() and EnableRadioButton() functions in ActiveTaskDialog.CS, when you call the code from VB.NET:
 
The True/False test appears to be reversed when calling these two functions from VB.NET, so that when you pass in the button id and False, the button is enabled. This is contrary to your documentation, which states that passing in False should disable the button, and is also contrary to the behavior when calling your code from C#, where it exhibits the proper behavior.
 
I can only guess that this has to do with the differing way in which the C-based languages treat 0/1 as true/false.
 

With that in mind, there are two approaches a VB.NET user can take to work around the issue.
 
The first, and simplest, is to just remember to reverse True/False when calling the 2 functions from VB.NET.
 
The second is to actually change the code in the C# source to match the documentation. This approach is probably preferable for the VB.NET programmer if and only if they are 100% certain the code will never be called from C#.
 
For those who choose the second option, the following line in both functions:
(IntPtr)(enable ? 0 : 1 ));
 
should be changed to read:
(IntPtr)(enable ? 1 : 0 ));
 
It is extremely important that the user document whichever approach they choose; the "enable" parameter in the XML comment above the function in the source code file should be changed to indicate either that VB.NET users should reverse the Boolean logic, or that C# users should.
 
-AndrewC
GeneralShield Icon on CommandButtonmemberBYoung@OSIsoft.com13 Mar '08 - 13:04 
I'm using the TaskDialog for asking the user of my app if they want to restart the application to do the requested task because it requires elevated access, similiar to how VS 2008 asks when you try to do something that requires elevated access.
 
For the CommandButton that is for saying "Yes, elevate me", I would like to show the shield icon instead of just the standard green arrow. But I've yet to figure out how. I'm pretty sure it's possible because VS2008 does this, but who knows what VS is doing underneath the hood.
 
Have you tried to do this?
QuestionLicensing QuestionmemberThorsten Dittmar15 Nov '07 - 1:52 
Hi,
 
I'd like to use Vista TaskDialog Wrapper and Emulator (by Hedley Muscroft) in commercial applications and asked him for permission to use his code.
 
While he allowed me to use his code, he also pointed out that his code uses part of your code and suggested that I should double check with you for licensing questions.
 
So: Is there a special license agreement I have to obey when using your code or am I allowed to use and/or modify your code as I need in both free and commercial applications?
 
Thanks for information,
Thorsten
GeneralWrapper and Emulator for pre-VistamemberHedley Muscroft12 Nov '07 - 11:49 
Hi Kevin,
 
Just to let you know, I recently posted an article which builds on your superb project by including an 'emulator' so that the TaskDialog can be used pre-Vista too. I've given you full credit for this excellent article though, and included links to it from my article. I hope that's ok.
 
Thanks again.
 
http://www.codeproject.com/useritems/Vista_TaskDialog_Wrapper.asp
 
Hedley Muscroft

QuestionHow to change the Button-TextmemberRekire31 Oct '07 - 13:43 
Hi,
how can I change the text of a button in the callback function?
Maybe it is possible to work with the handle, but I've got no idea how to do it.
AnswerRe: How to change the Button-TextmemberKevinGre31 Oct '07 - 14:02 
You can't. If you look at the MSDN documentation for TaskDialog (link below) you can see that TaskDialog does not support updating the text of buttons (which is often a poor experience for your users anyway). You might consider having two buttons and using enable and disable, or if you want complete control creating your own dialog. Remember, TaskDialog is designed to meet a lot of requirements and save you creating custom dialogs for most common tasks but it is not the answer to all needs. Technically you could use the window handle of the active TaskDialog to get the window handle of buttons and change their text but that would be pretty evil and probably technically unsupported which means it might break on future versions (adjust layout correctly etc).
 
http://msdn2.microsoft.com/en-us/library/bb762715.aspx[^]
Generalerror [modified]memberpravin parmar27 Oct '07 - 4:35 
i m getting error like: "Unable to find an entry point named 'TaskDialogIndirect' in DLL 'ComCtl32'.".
 
application shows me this message: "Requires OS Version 6.0.5243 or later" near the "Show Task Dialog" button.
 
pls help.thanks.
 

-- modified at 10:46 Saturday 27th October, 2007
 
Pravin Parmar,
PravinParmar.ce@gmail.com

GeneralThanks for the effortmemberrykk..15 Feb '07 - 17:42 
Very good - code was very helpful
Question.net 3.0 support for task dialogs, custom Windows XP SP2 support ?memberChris Richner9 Feb '07 - 0:59 
Hi,
 
I'm wondering why .net 3.0 framework has no managed way to use task dialogs. When does MS extend .net to provide managed support for vista platform features?
 
Anybody tought about an legacy implementation of ITaskDialog for task dialogs in .net 2.0 running on windows xp sp2. Maybe there could be something like a migration path for code running currently on xp using custom task dialog implementations today but will run with slightly changes on a future .net framework for vista system.
 
myMsg.BehindDaKeys = "Chris Richner";

AnswerRe: .net 3.0 support for task dialogs, custom Windows XP SP2 support ?memberJonas Nordlund2 Sep '07 - 22:42 
Agreed; I would love to have a pretty and functional fallback using a custom form for Windows XP. I simply cannot use the new TaskDialog if the dialogs on the OS with the currently still major user base will have reduced functionality. A legacy implementation, using the "real" API under Vista, would be most welcome here, although I understand if there is some effort involved in achieving that...
GeneralRe: .net 3.0 support for task dialogs, custom Windows XP SP2 support ? [modified]memberChris Richner3 Sep '07 - 6:43 
Seems like we have to find someone to write that Wink | ;)
 
btw: Paint.net makes use of the new concept and provides custom task dialogs (.net 2.0)
 
-- modified at 12:48 Monday 3rd September, 2007
 

GeneralRe: .net 3.0 support for task dialogs, custom Windows XP SP2 support ? [modified]memberJonas Nordlund3 Oct '07 - 23:39 
- http://www.naughter.com/xtaskdialog.html
- http://www.codeproject.com/useritems/taskdialogs.asp
 
Edit: Oh and here's CodeJock's component! Here:
http://www.codejock.com/downloads/samples/controls.asp#controls_vistataskdialog
 
Scroll to the bottom of that page, and download the sample application they made. I think the last one is a commercial component, but it looks pretty good and I could not even distinguish the difference easily, at least when running the app on Vista and comparing it with the native mode box. (I believe the control suppports some flag that tells if it should use the native TaskDialog API if available)
GeneralRe: .net 3.0 support for task dialogs, custom Windows XP SP2 support ?memberHedley Muscroft12 Nov '07 - 11:47 
Here's a C# TaskDialog wrapper and emulator which does what you're asking :-
 
http://www.codeproject.com/useritems/Vista_TaskDialog_Wrapper.asp
 
Regards
 
Hedley Muscroft

GeneralRe: .net 3.0 support for task dialogs, custom Windows XP SP2 support ?memberJonas Nordlund26 Mar '08 - 15:30 
Yes, that one is indeed just perfect and what I think we were looking for. Thanks! Smile | :)
QuestionArgumentException in 64bit version?memberMember #10918077 Feb '07 - 1:59 
Hello, there's a problem when I run the TaskDialog in the source code example.
I think that it may be because of 64 bit edition.
 
The message is:
 
System.ArgumentException: El valor no está dentro del intervalo esperado.
en Microsoft.Samples.UnsafeNativeMethods.TaskDialogIndirect(TASKDIALOGCONFIG& pTaskConfig, Int32& pnButton, Int32& pnRadioButton, Boolean& pfVerificationFlagChecked)
en Microsoft.Samples.TaskDialog.PrivateShow(IntPtr hwndOwner, Boolean& verificationFlagChecked, Int32& radioButtonResult)
en Microsoft.Samples.TaskDialog.Show(IWin32Window owner, Boolean& verificationFlagChecked, Int32& radioButtonResult)
en FormPlay.Form1.TaskDialogButton_Click(Object sender, EventArgs e)
en System.Windows.Forms.Control.OnClick(EventArgs e)
en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
en System.Windows.Forms.Control.WndProc(Message& m)
en System.Windows.Forms.ButtonBase.WndProc(Message& m)
en System.Windows.Forms.Button.WndProc(Message& m)
en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
en System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

AnswerRe: ArgumentException in 64bit version?memberKevinGre7 Feb '07 - 7:58 
Oops. That's embarasing. It needs Pack=1 on the interop structures. In UnsafeNativeMethods.cs change line 309 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
internal struct TASKDIALOGCONFIG
 
and TaskDialog.cs line 212 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct TaskDialogButton
 
I'll update the original code and resubmit.
GeneralRe: ArgumentException in 64bit version?memberBrian C. Hart, Ph.D.21 Oct '09 - 7:52 
KevinGre wrote:
Oops. That's embarasing. It needs Pack=1 on the interop structures. In UnsafeNativeMethods.cs change line 309 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
internal struct TASKDIALOGCONFIG
 
and TaskDialog.cs line 212 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct TaskDialogButton
 
I'll update the original code and resubmit.

 
I don't mean to be nag but 2010 is upon us and it looks like you wrote this article (very good btw! thanks!) in 2007....I downloaded the source and got the ArgumentException error discussed in this thread....looks like the update still has not been posted....thanks for posting it!
 
Sincerely Yours,
Brian Hart

GeneralRe: ArgumentException in 64bit version?memberBrian C. Hart, Ph.D.21 Oct '09 - 7:55 
KevinGre wrote:
Oops. That's embarasing. It needs Pack=1 on the interop structures. In UnsafeNativeMethods.cs change line 309 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
internal struct TASKDIALOGCONFIG
 
and TaskDialog.cs line 212 to be:
 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
public struct TaskDialogButton
 
I'll update the original code and resubmit.

 
I changed my downloaded code thusly and ran, and the task dialog popped up fine so long as I do not use Command Links. If I do, then all goes to hell once again.
 
Sincerely Yours,
Brian Hart

GeneralI see it as a MessageBox replacement/extensionmemberreddog_aw9 Jan '07 - 1:05 
> I look forward to seeing a lot fewer Message Boxes in you applications and I hope this makes it easier.
 
Perhaps I'm mistaken but Task Dialog's seem more like a potential MessageBox replacement (let's face it, no matter how hard you try you always end up with one of the pesky buggers in your UI anyway).
 
My thoughts are that perhaps this library would be useful in creating "standardised" MessageBox helper functions perhaps with some logic for platform detection to display either a MessageBox if we're in a non-vista executing environment or TaskDialog's with all the nice bell's and whistles if we are in Vista.
 
Anyone else's thoughts? Does anyone know of similar implementations?
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 5 Jan 2007
Article Copyright 2007 by KevinGre
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid