visual-c++ - 使用 DoMessageBox 将 AfxMessageBox 转换为 CTaskDialog

标签 visual-c++ mfc messagebox taskdialog

到目前为止我已经写了这个函数:

int CMFCApplication3App::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
    CString strContent = CString(lpszPrompt);
    CString strTitle; strTitle.LoadString(AFX_IDS_APP_TITLE);
    CTaskDialog dlgTaskMessageBox(strContent, _T(""), strTitle);
    int iPixelWidth = (::GetSystemMetrics(SM_CXSCREEN) / 100) * 30;
    int iDialogUnitsWidth = MulDiv(iPixelWidth, 4, LOWORD(GetDialogBaseUnits()));
    dlgTaskMessageBox.SetDialogWidth(iDialogUnitsWidth);

    /*
    if (nType & MB_ICONINFORMATION)
        dlgTaskMessageBox.SetMainIcon(TD_INFORMATION_ICON);
    if (nType & MB_ICONERROR)
        dlgTaskMessageBox.SetMainIcon(TD_ERROR_ICON);
    if (nType & MB_ICONWARNING)
        dlgTaskMessageBox.SetMainIcon(TD_WARNING_ICON);
    if (nType & MB_ICONQUESTION)
    {
        HICON hIcon = LoadIcon(IDI_QUESTION);
        dlgTaskMessageBox.SetMainIcon(hIcon);
    }

    int iButtons = 0;
    if (nType & IDYES)
        iButtons |= TDCBF_YES_BUTTON;
    if (nType & IDNO)
        iButtons |= TDCBF_NO_BUTTON;
    if (nType & IDCANCEL)
        iButtons |= TDCBF_CANCEL_BUTTON;
    if (nType & IDOK)
        iButtons |= TDCBF_OK_BUTTON;
    if (nType & IDRETRY)
        iButtons |= TDCBF_RETRY_BUTTON;
    dlgTaskMessageBox.SetCommonButtons(iButtons);
    */

    if (nType == (MB_YESNOCANCEL | MB_ICONERROR))
    {
        dlgTaskMessageBox.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
        dlgTaskMessageBox.SetMainIcon(TD_ERROR_ICON);
    }
    if (nType == (MB_YESNOCANCEL | MB_ICONWARNING))
    {
        dlgTaskMessageBox.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
        dlgTaskMessageBox.SetMainIcon(TD_WARNING_ICON);
    }
    if (nType == (MB_YESNOCANCEL | MB_ICONINFORMATION))
    {
        dlgTaskMessageBox.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
        dlgTaskMessageBox.SetMainIcon(TD_INFORMATION_ICON);
    }
    /*
    if (nType == (MB_YESNOCANCEL | MB_ICONQUESTION))
    {
        dlgTaskMessageBox.SetCommonButtons(TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
        HICON hIcon = LoadIcon(IDI_QUESTION);
        dlgTaskMessageBox.SetMainIcon(hIcon);
    }
    */
    return dlgTaskMessageBox.DoModal();
}

我有两个问题,很高兴分成两个问题:

  1. 使用 IDI_QUESTION 导致应用程序崩溃。
  2. 有没有一种更简单的方法可以将 nType 解码为所需的各种按钮和图标?

最佳答案

Using IDI_QUESTION is causing the application to crash

那是因为 IDI_QUESTION 是一个 standard icon并且必须通过将 NULL 实例句柄传递给 ::LoadIcon 来加载,但 MFC 的 CWinApp::LoadIcon 改为传递 AfxGetResourceHandle()。下面绕过MFC,直接调用Win32 API。

HICON hIcon = ::LoadIcon(NULL, IDI_QUESTION);

Isn't there an easier way to decode nType into the various buttons and icon required?

不是很容易,但可以将它们分组以减少重复。

int nCommonButtons = 0;

switch(nType)
{
case MB_YESNOCANCEL:
    nCommonButtons |= TDCBF_CANCEL_BUTTON;
case MB_YESNO:
    nCommonButtons |= TDCBF_YES_BUTTON | TDCBF_NO_BUTTON; 
    break;

case MB_OKCANCELRETRY:
    nCommonButtons |= TDCBF_RETRY_BUTTON;
case MB_OKCANCEL:
    nCommonButtons |= TDCBF_CANCEL_BUTTON;
case MB_OK:
    nCommonButtons |= TDCBF_OK_BUTTON; 
    break;

//... etc
}

关于visual-c++ - 使用 DoMessageBox 将 AfxMessageBox 转换为 CTaskDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66013767/

相关文章:

visual-c++ - 如何解决 VS 2013 中的 'Null' is null or not an object 错误

visual-c++ - fatal error LNK1106 : invalid file or disk full: cannot seek to 0x5A57BEBC

visual-c++ - Visual Studio 2012 上的 vc++ 项目缺少 mfc110ud.dll

c++ - 第二个对话框上的C++ MFC按钮不起作用

c# - WPF 消息框显示错误消息

python - 改变 tkinter 消息框的大小

c++ - 在 MSVC 中,Operator new 在 Debug 模式下的行为与 Release 模式下的行为不同

c++ - 链接 lib 时未解析的外部符号,编译器将字母 'A' 添加到函数名称

c++ - 在 MFC 中将文本复制到剪贴板

在 Windows 7 上使用 GLUT 的 OpenGL,全屏模式不显示消息框