Search code examples
visual-c++mfctaskdialog

Setting the main icon of a CTaskDialog as a Question?


I have this CTaskDialog that I am working on:

Task Dialog

The code is as follows:

CTaskDialog dlg(_T("How would you like to download the data?"), 
                _T("Download Schedule Information"),
                _T("Meeting Schedule Assistant"), TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON);
dlg.SetMainIcon(TD_INFORMATION_ICON);
dlg.SetFooterIcon(TD_INFORMATION_ICON);
dlg.SetFooterText(_T("All assignments for the selected weeks will be reset."));
dlg.AddRadioButton(44444, _T("Download data for all weeks"));
dlg.AddRadioButton(44445, _T("Download data for selected week"));
dlg.AddRadioButton(44446, _T("Download data for selected week and all additional weeks"));
// Set Width in dialog units (40% screen width)
int iPixelWidth = (::GetSystemMetrics(SM_CXSCREEN) / 100) * 40;
int iDialogUnitsWidth = MulDiv(iPixelWidth, 4, LOWORD(GetDialogBaseUnits()));
dlg.SetDialogWidth(iDialogUnitsWidth);

if(dlg.DoModal() == IDOK)
{
    auto iSelection = dlg.GetSelectedRadioButtonID();
}

Is it possible to set the main icon as a question? I can only see these defines in the source:

#define TD_WARNING_ICON         MAKEINTRESOURCEW(-1)
#define TD_ERROR_ICON           MAKEINTRESOURCEW(-2)
#define TD_INFORMATION_ICON     MAKEINTRESOURCEW(-3)
#define TD_SHIELD_ICON          MAKEINTRESOURCEW(-4)

Solution

  • The SetMainIcon member function is what you're looking for. Like most functions that deal with Win32 resources, it has two overloads:

    void SetMainIcon(
       HICON hMainIcon
    );
    
    void SetMainIcon(
       LPCWSTR lpszMainIcon
    );
    

    The first takes a handle to an icon resource (HICON), while the second takes a string identifying a resource from which an icon resource can be loaded.

    If you want to set the task dialog to display your application's icon, then you can simply pass in the appropriate HICON. You can also use a custom icon loaded from your application's resources.

    I'm not entirely sure, but I think what you're asking is how to use a question-mark icon. Note first that the use of such icons in message boxes has been deprecated since Windows 95, and Microsoft strongly discourages their use. It is recommended that you only use them to denote entry points to online help. Quoting from the Standard Icons section of the official Win32 style guide:

    Question mark icons

    • Use the question mark icon only for Help entry points. For more information, see the Help entry point guidelines.
    • Don't use the question mark icon to ask questions. Again, use the question mark icon only for Help entry points. There is no need to ask questions using the question mark icon anyway it's sufficient to present a main instruction as a question. Don't routinely replace question mark icons with warning icons. Replace a question mark icon with a warning icon only if the question has significant consequences. Otherwise, use no icon.

    So, this is why there's no standard question mark icon defined. These TD_*_ICON defines are straight from the Win32 headers for the Task Dialog (they're the same ones you'd use with the TASKDIALOGCONFIG structure), not part of the MFC wrapper class.

    If you absolutely must use this icon, the workaround is as follows:

    const HICON hiconQuestion = AfxGetApp()->LoadStandardIcon(IDI_QUESTION);
    dlg.SetMainIcon(hiconQuestion);
    

    (Note that the same HICON could be passed to the CTaskDialog's SetFooterIcon member function.)