是的,你可以调试跟踪进去看代码的, 最终实现函数是: // Helper for message boxes; can work when no CWinApp can be found int CWinApp::ShowAppMessageBox(CWinApp *pApp, LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) { // disable windows for modal dialog DoEnableModeless(FALSE); HWND hWndTop; HWND hWnd = CWnd::GetSafeOwner_(NULL, &hWndTop); // re-enable the parent window, so that focus is restored // correctly when the dialog is dismissed. if (hWnd != hWndTop) EnableWindow(hWnd, TRUE); // set help context if possible DWORD* pdwContext = NULL; DWORD dwWndPid=0; GetWindowThreadProcessId(hWnd,&dwWndPid); if (hWnd != NULL && dwWndPid==GetCurrentProcessId() ) { // use app-level context or frame level context LRESULT lResult = ::SendMessage(hWnd, WM_HELPPROMPTADDR, 0, 0); if (lResult != 0) pdwContext = (DWORD*)lResult; } // for backward compatibility use app context if possible if (pdwContext == NULL && pApp != NULL) pdwContext = &pApp->m_dwPromptContext; DWORD dwOldPromptContext = 0; if (pdwContext != NULL) { // save old prompt context for restoration later dwOldPromptContext = *pdwContext; if (nIDPrompt != 0) *pdwContext = HID_BASE_PROMPT+nIDPrompt; } // determine icon based on type specified if ((nType & MB_ICONMASK) == 0) { switch (nType & MB_TYPEMASK) { case MB_OK: case MB_OKCANCEL: nType |= MB_ICONEXCLAMATION; break; case MB_YESNO: case MB_YESNOCANCEL: nType |= MB_ICONQUESTION; break; case MB_ABORTRETRYIGNORE: case MB_RETRYCANCEL: // No default icon for these types, since they are rarely used. // The caller should specify the icon. break; } }#ifdef _DEBUG if ((nType & MB_ICONMASK) == 0) TRACE(traceAppMsg, 0, "Warning: no icon specified for message box.\n"); #endif TCHAR szAppName[_MAX_PATH]; szAppName[0] = '\0'; LPCTSTR pszAppName; if (pApp != NULL) pszAppName = pApp->m_pszAppName; else { pszAppName = szAppName; DWORD dwLen = GetModuleFileName(NULL, szAppName, _MAX_PATH); if (dwLen == _MAX_PATH) szAppName[_MAX_PATH - 1] = '\0'; } int nResult = ::AfxCtxMessageBox(hWnd, lpszPrompt, pszAppName, nType); // restore prompt context if possible if (pdwContext != NULL) *pdwContext = dwOldPromptContext; // re-enable windows if (hWndTop != NULL) ::EnableWindow(hWndTop, TRUE); DoEnableModeless(TRUE); return nResult; }而AfxCtxMessageBox实际就是MessageBox
最终实现函数是:
// Helper for message boxes; can work when no CWinApp can be found
int CWinApp::ShowAppMessageBox(CWinApp *pApp, LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
// disable windows for modal dialog
DoEnableModeless(FALSE);
HWND hWndTop;
HWND hWnd = CWnd::GetSafeOwner_(NULL, &hWndTop); // re-enable the parent window, so that focus is restored
// correctly when the dialog is dismissed.
if (hWnd != hWndTop)
EnableWindow(hWnd, TRUE); // set help context if possible
DWORD* pdwContext = NULL; DWORD dwWndPid=0;
GetWindowThreadProcessId(hWnd,&dwWndPid); if (hWnd != NULL && dwWndPid==GetCurrentProcessId() )
{
// use app-level context or frame level context
LRESULT lResult = ::SendMessage(hWnd, WM_HELPPROMPTADDR, 0, 0);
if (lResult != 0)
pdwContext = (DWORD*)lResult;
}
// for backward compatibility use app context if possible
if (pdwContext == NULL && pApp != NULL)
pdwContext = &pApp->m_dwPromptContext; DWORD dwOldPromptContext = 0;
if (pdwContext != NULL)
{
// save old prompt context for restoration later
dwOldPromptContext = *pdwContext;
if (nIDPrompt != 0)
*pdwContext = HID_BASE_PROMPT+nIDPrompt;
} // determine icon based on type specified
if ((nType & MB_ICONMASK) == 0)
{
switch (nType & MB_TYPEMASK)
{
case MB_OK:
case MB_OKCANCEL:
nType |= MB_ICONEXCLAMATION;
break; case MB_YESNO:
case MB_YESNOCANCEL:
nType |= MB_ICONQUESTION;
break; case MB_ABORTRETRYIGNORE:
case MB_RETRYCANCEL:
// No default icon for these types, since they are rarely used.
// The caller should specify the icon.
break;
}
}#ifdef _DEBUG
if ((nType & MB_ICONMASK) == 0)
TRACE(traceAppMsg, 0, "Warning: no icon specified for message box.\n");
#endif TCHAR szAppName[_MAX_PATH];
szAppName[0] = '\0';
LPCTSTR pszAppName;
if (pApp != NULL)
pszAppName = pApp->m_pszAppName;
else
{
pszAppName = szAppName;
DWORD dwLen = GetModuleFileName(NULL, szAppName, _MAX_PATH);
if (dwLen == _MAX_PATH)
szAppName[_MAX_PATH - 1] = '\0';
} int nResult =
::AfxCtxMessageBox(hWnd, lpszPrompt, pszAppName, nType); // restore prompt context if possible
if (pdwContext != NULL)
*pdwContext = dwOldPromptContext; // re-enable windows
if (hWndTop != NULL)
::EnableWindow(hWndTop, TRUE);
DoEnableModeless(TRUE); return nResult;
}而AfxCtxMessageBox实际就是MessageBox
::MessageBox(hWnd, lpszPrompt, pszAppName, nType); 我也查了一下这些代码。 但是在《Windows核心编程》第4版的实例程序 22-LastMsgBoxInfo 运行时,缺没有”捕获“ AfxMessageBox,而可以捕获直接使用 MesssageBox。 不知为何?也许AfxMessageBox有多个版本?