如何解决使用 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);
}
*/
return dlgTaskMessageBox.DoModal();
}
我对此有两个问题,很高兴将其拆分为两个问题:
- 使用
IDI_QUESTION
会导致应用程序崩溃。 - 难道没有更简单的方法可以将
nType
解码为所需的各种按钮和图标吗?
解决方法
使用 IDI_QUESTION
会导致应用程序崩溃
那是因为 IDI_QUESTION
是一个 standard icon 并且必须通过将 NULL
实例句柄传递给 ::LoadIcon
来加载,但是 MFC 的 CWinApp::LoadIcon
传递 {{1} } 反而。下面绕过MFC,直接调用Win32 API。
AfxGetResourceHandle()
难道没有更简单的方法将 nType 解码为所需的各种按钮和图标吗?
不是很容易,但可以将它们分组以减少重复。
HICON hIcon = ::LoadIcon(NULL,IDI_QUESTION);
,
我想我会将此添加为附加答案。
接受已接受的答案 (@dxiv) 和下面的评论 (@sergiol):
int CMeetingScheduleAssistantApp::DoMessageBox(LPCTSTR lpszPrompt,UINT nType,UINT nIDPrompt)
{
CString strContent = CString(lpszPrompt);
CString strTitle = CString();
if (!CTaskDialog::IsSupported())
return CWinAppEx::DoMessageBox(lpszPrompt,nType,nIDPrompt);
ENSURE(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);
HICON hQuestionIcon = ::LoadIcon(nullptr,IDI_QUESTION);
// Icon
switch (nType & MB_ICONMASK)
{
case MB_ICONERROR:
dlgTaskMessageBox.SetMainIcon(TD_ERROR_ICON);
break;
case MB_ICONWARNING:
dlgTaskMessageBox.SetMainIcon(TD_WARNING_ICON);
break;
case MB_ICONINFORMATION:
dlgTaskMessageBox.SetMainIcon(TD_INFORMATION_ICON);
break;
case MB_ICONQUESTION:
dlgTaskMessageBox.SetMainIcon(hQuestionIcon);
break;
}
// Buttons
int nCommonButtons = 0;
switch (nType & MB_TYPEMASK)
{
case MB_YESNOCANCEL:
nCommonButtons |= TDCBF_CANCEL_BUTTON;
[[fallthrough]];
case MB_YESNO:
nCommonButtons |= TDCBF_YES_BUTTON | TDCBF_NO_BUTTON;
break;
case MB_RETRYCANCEL:
nCommonButtons |= TDCBF_RETRY_BUTTON | TDCBF_NO_BUTTON;
break;
case MB_OKCANCEL:
nCommonButtons |= TDCBF_CANCEL_BUTTON;
[[fallthrough]];
case MB_OK:
default:
nCommonButtons |= TDCBF_OK_BUTTON;
}
dlgTaskMessageBox.SetCommonButtons(nCommonButtons);
return static_cast<int>(dlgTaskMessageBox.DoModal());
}
我不知道这些:
MB_ICONMASK
MB_TYPEMASK
我没有考虑到的唯一情况是 MB_ABORTRETRYIGNORE
,因为我没有看到 Abort 和 Ignore 的通用按钮等效项。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。