Visual Basic Common Dialog Routines
TaskDialog: Displaying the Vista Task Dialog from VB
     
Posted:   Tuesday September 09, 2008
Updated:   Monday December 26, 2011
     
Applies to:   VB6
Developed with:   VB6, Windows Vista
OS restrictions:   Windows Vista
Author:   VBnet - Randy Birch
     
Related: 

MessageBoxEx: Displaying an API-created Message Box
SetWindowsHookEx: Customize the API Message Box

 Prerequisites
Modified vb6.exe using the instructions at Manifests: Make the VB IDE use Windows Vista Styles.

Compared to alert messages in Vista, VB's MsgBox and Windows generic MessageBox and MessageBoxEx APIs are pretty dull. This page shows how to show the new Vista TaskDialog, together with a few interesting undocumented flags you can use to customize the out-of-the-box appearance of the TaskDialog.

Like a MsgBox or MessageBox, a basic TaskDialog has five key components:

  • a dialog title
  • a message
  • an icon
  • the selection buttons
  • a return value indicating the button selected

But there are also a number of key differences between a TaskDialog and a standard API MessageBox:

  • There is no ANSI-defined version, so all strings passed must be through StrPtr().
  • You can have two distinct messages in the dialog, what Microsoft calls the Main Instruction and the Content.  The Main Instruction is the large-type message, typically a short string to convey the important alert message. The Content is in smaller type below, and can be anything from a simple instruction, as shown in the illustration, to several hundred words of instruction.
  • Unlike MessageBoxes which increased first in width to a screen limit before wrapping text onto new lines, TaskDialogs are always the same width and grow vertically in side dependant on the Main Instruction and Content supplied.
  • Buttons are not specified as groupings (MB_OKCANCEL, MB_ABORTRETRYIGNORE,MB_YESNOCANCEL etc.) but rather as OR'd button flags.  This means you can have any combination of Yes, No, Retry, Ok, Cancel and Close buttons displayed, or even all of them if you really want to confuse the hell out of an end user.
  • The value of the button the user pressed is not returned as a result of the function call but rather as a parameter passed ByRef to the function. The return value of the call now represents success (0) or OUTOFMEMORY, INVALIDARG, or simply "FAIL".
  • The value returned following a user clicking the X button is not that of a "Close" button (8), but rather Cancel (2).
  • You can show a security shield, which Microsoft denotes is a special symbol to be used (in conscientious apps) to indicate a user's action requires an elevation in security level. But interestingly, there are a number of MS-undocumented but VB-documented flags you can pass to change some of the look of the dialog, including a couple of icons not provided for in the documented flags. (In the illustration, the differences in dialogs are the result of four different icon flags - from top to bottom - the documented TD_ERROR_ICON flag, and the next three the undocumented (and thus named by me) TD_SHIELD_ERROR_ICON, TD_SHIELD_GRADIENT_ICON and TD_SHIELD_OK_ICON.
  • There are no defbutton flags; the leftmost button always has focus when two or more are displayed (and no, you can not specify the order of the buttons during the call).

TaskDialog is a fancy MessageBox, and since Vista users have expectations as to the look and feel of applications, it makes sense to use the latest GUI features whenever possible.  If developing an app to support multiple operating systems, then you will need to be able to depreciate gracefully to MessageBox or even VB's MsgBox if the system is not Vista.  I have posted a couple of ways to determine OS versions on the site; do a search for IsVista.

TaskDialog has a big brother, one who weight lifts and is on serious steroids. TaskDialogIndirect is the brute that allows custom sizing, custom images, custom button captions, as well as other (option/check) buttons, a "don't show this again" button, and an expanding down arrow "more information" button. A series of TaskDialogIndirect demos is in development.

 BAS Module Code
None. But see the Comments section below to use this demo in a compiled state.

 Form Code
To a form containing just a command button (Command1), add the following code.  The results are output to the debug window:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'taskdialog icons defined under Vista. All text
'on white dialog background

'exclamation point in a yellow 'yield' triangle (same image as IDI_EXCLAMATION)
Private Const TD_WARNING_ICON As Long = -1

'round red circle containg 'X' (same as IDI_HAND)
Private Const TD_ERROR_ICON As Long = -2

'round blue circle containing 'i' (same image as IDI_ASTERISK)
Private Const TD_INFORMATION_ICON As Long = -3

 'Vista's security shield
Private Const TD_SHIELD_ICON As Long = -4


'icons defined under Windows that can also be used.
'Text on white dialog background

'miniature picture of an application window
Private Const IDI_APPLICATION = 32512&

'round blue circle containing '?'
Private Const IDI_QUESTION = 32514&


'other undefined icon constants that present
'the icon and dialog text in a different format (my constants)

'same image as TD_SHIELD_ICON; main message text on gradient blue background
Private Const TD_SHIELD_GRADIENT_ICON As Long = -5

'exclamation point in yellow Shield shape; main message text on gradient orange background
Private Const TD_SHIELD_WARNING_ICON As Long = -6

'X contained within Shield shape; main message text on gradient red background
Private Const TD_SHIELD_ERROR_ICON As Long = -7

'Shield shape containing green checkmark; main message text on gradient green background
Private Const TD_SHIELD_OK_ICON As Long = -8

'same image as TD_SHIELD_ICON; main message text on medium gray background
Private Const TD_SHIELD_GRAY_ICON As Long = -9

'no icon; text on white background
Private Const TD_NO_ICON As Long = 0

'taskdialog common button flags
Private Const TDCBF_OK_BUTTON As Long = &H1&      'return value 1 (IDOK)
Private Const TDCBF_YES_BUTTON As Long = &H2&     'return value 6 (IDYES)
Private Const TDCBF_NO_BUTTON As Long = &H4&      'return value 7 (IDNO)
Private Const TDCBF_CANCEL_BUTTON As Long = &H8&  'return value 2 (IDCANCEL)
Private Const TDCBF_RETRY_BUTTON As Long = &H10&  'return value 4 (IDRETRY)
Private Const TDCBF_CLOSE_BUTTON As Long = &H20&  'return value 8 (IDCLOSE)

Private Declare Function TaskDialog Lib "comctl32.dll" _
  (ByVal hwndParent As Long, _
   ByVal hInstance As Long, _
   ByVal pszWindowTitle As Long, _
   ByVal pszMainInstruction As Long, _
   ByVal pszContent As Long, _
   ByVal dwCommonButtons As Long, _
   ByVal pszIcon As Long, _
   pnButton As Long) As Long


Private Sub Command1_Click()

   Dim sDlgTitle As String
   Dim sMainPrompt As String
   Dim sContent As String
   Dim dwButtons As Long
   Dim dwIcon As Long
   Dim pnButton As Long
   Dim success As Long

   sDlgTitle = "VBnet TaskDialog Demo"
   sMainPrompt = "The license key you entered for this program was invalid. Please try again."
   sContent = "To re-enter your license key select Retry."
   dwButtons = TDCBF_RETRY_BUTTON Or TDCBF_CANCEL_BUTTON
   dwIcon = MakeIntResource(TD_ERROR_ICON)
   
   success = TaskDialog(Me.hWnd, _
                        0&, _
                        StrPtr(sDlgTitle), _
                        StrPtr(sMainPrompt), _
                        StrPtr(sContent), _
                        dwButtons, _
                        dwIcon, _
                        pnButton)
   
   Debug.Print "success = "; success
   Debug.Print "user action = "; pnButton

End Sub


Private Function MakeIntResource(ByVal dwVal As Long) As Long

   MakeIntResource = &HFFFF& And dwVal
   
End Function
 Comments
Remember that to use this dialog in a compiled application, you MUST:
  • provide (install) an external application.exe.manifest file along with the application
  • call InitCommonControls or InitCommonControlsEx with ICC_WIN95_CLASSES specified
  • make the InitCommonControls/InitCommonControlsEx call from Sub Main before Showing your form.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter