本文介绍了使用 DoMessageBox 将 AfxMessageBox 转换为 CTaskDialog的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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);}*/返回 dlgTaskMessageBox.DoModal();}

我对此有两个问题,很高兴将其拆分为两个问题:

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

那是因为 IDI_QUESTION 是一个 标准图标,并且必须通过将 NULL 实例句柄传递给 ::LoadIcon,但 MFC 的 CWinApp::LoadIcon 通过 AfxGetResourceHandle() 代替.下面绕过MFC,直接调用Win32 API.

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

难道没有更简单的方法将 nType 解码为所需的各种按钮和图标吗?

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

int nCommonButtons = 0;开关(nType){案例 MB_YESNOCANCEL:nCommonButtons |= TDCBF_CANCEL_BUTTON;案例 MB_YESNO:nCommonButtons |= TDCBF_YES_BUTTON |TDCBF_NO_BUTTON;休息;案例 MB_OKCANCELRETRY:nCommonButtons |= TDCBF_RETRY_BUTTON;案例 MB_OKCANCEL:nCommonButtons |= TDCBF_CANCEL_BUTTON;案例 MB_OK:nCommonButtons |= TDCBF_OK_BUTTON;休息;//... 等等}

I have written this function so far:

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();
}

I have two issues with this and am happy to split as two questions:

  1. Using IDI_QUESTION is causing the application to crash.
  2. Isn't there an easier way to decode nType into the various buttons and icon required?
解决方案

That's because IDI_QUESTION is a standard icon and must be loaded by passing a NULL instance handle to ::LoadIcon, but MFC's CWinApp::LoadIcon passes AfxGetResourceHandle() instead. The following bypasses MFC and calls the Win32 API directly.

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

Not a lot easier, but they could be grouped to lessen the duplication.

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
}

这篇关于使用 DoMessageBox 将 AfxMessageBox 转换为 CTaskDialog的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:16