int MessageBoxWorker(
LPMSGBOXDATA pMsgBoxParams)
{
DWORD dwStyle = pMsgBoxParams->dwStyle;
UINT wBtnCnt;
UINT wDefButton;
UINT i;
UINT wBtnBeg;
WCHAR szErrorBuf[64];
LPWSTR apstrButton[4];
int aidButton[4];
BOOL fCancel = FALSE;
int retValue;
#ifdef DEBUG
if (dwStyle & ~MB_VALID) {
RIPMSG2(RIP_WARNING, "MessageBoxWorker: Invalid flags, %#lx & ~%#lx != 0",
dwStyle, MB_VALID);
}
#endif
/*
* MB_SERVICE_NOTIFICATION had to be redefined because
* Win95 defined MB_TOPMOST using the same value.
* So for old apps, we map it to the new value
*/
if((dwStyle & MB_TOPMOST) && (GetClientInfo()->dwExpWinVer < VER40)) {
dwStyle &= ~MB_TOPMOST;
dwStyle |= MB_SERVICE_NOTIFICATION;
pMsgBoxParams->dwStyle = dwStyle;
RIPMSG1(RIP_WARNING, "MessageBoxWorker: MB_SERVICE_NOTIFICATION flag mapped. New dwStyle:%#lx", dwStyle);
}
/*
* For backward compatiblity, use MB_SERVICE_NOTIFICATION if
* it's going to the default desktop.
*/
if (dwStyle & (MB_DEFAULT_DESKTOP_ONLY | MB_SERVICE_NOTIFICATION)) {
/*
* Allow services to put up popups without getting
* access to the current desktop.
*/
if (pMsgBoxParams->hwndOwner != NULL) {
RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "");
return 0;
}
return ServiceMessageBox(pMsgBoxParams->lpszText,
pMsgBoxParams->lpszCaption,
dwStyle & ~MB_SERVICE_NOTIFICATION,
FALSE);
}
/*
* Make sure we have a valid window handle.
*/
if (pMsgBoxParams->hwndOwner && !IsWindow(pMsgBoxParams->hwndOwner)) {
RIPERR0(ERROR_INVALID_WINDOW_HANDLE, RIP_VERBOSE, "");
return 0;
}
/*
* If lpszCaption is NULL, then use "Error!" string as the caption
* string.
* LATER: IanJa localize according to wLanguageId
*/
if (pMsgBoxParams->lpszCaption == NULL) {
if (pMsgBoxParams->wLanguageId == 0) {
pMsgBoxParams->lpszCaption = szERROR;
} else {
RtlLoadStringOrError(hmodUser,
STR_ERROR,
szErrorBuf,
sizeof(szErrorBuf)/sizeof(WCHAR),
RT_STRING,
prescalls,
pMsgBoxParams->wLanguageId);
/*
* If it didn't find the string, use the default language
*/
if (*szErrorBuf) {
pMsgBoxParams->lpszCaption = szErrorBuf;
} else {
pMsgBoxParams->lpszCaption = szERROR;
RIPMSG1(RIP_WARNING, "MessageBoxWorker: STR_ERROR string resource for language %#lx not found",
pMsgBoxParams->wLanguageId);
}
}
}
/*
* Validate the "type" of message box requested.
*/
if ((dwStyle & MB_TYPEMASK) > MB_LASTVALIDTYPE) {
RIPERR0(ERROR_INVALID_MSGBOX_STYLE, RIP_VERBOSE, "");
return 0;
}
wBtnCnt = mpTypeCcmd[dwStyle & MB_TYPEMASK] +
((dwStyle & MB_HELP) ? 1 : 0);
/*
* Set the default button value
*/
wDefButton = (dwStyle & (UINT)MB_DEFMASK) / (UINT)(MB_DEFMASK & (MB_DEFMASK >> 3));
if (wDefButton >= wBtnCnt) /* Check if valid */
wDefButton = 0; /* Set the first button if error */
/*
* Calculate the strings to use in the message box
*/
wBtnBeg = mpTypeIich[dwStyle & (UINT)MB_TYPEMASK];
for (i=0; i<wBtnCnt; i++) {
/*
* Pick up the string for the button.
*/
if (pMsgBoxParams->wLanguageId == 0) {
apstrButton<i> = GETGPSIMBPSTR(SEBbuttons[wBtnBeg + i] - SEB_OK);
} else {
WCHAR szButtonBuf[64];
// LATER is it possible to have button text greater than 64 chars
/*
* BUG: gpsi->wMaxBtnSize might be too short for the length of this string...
*/
RtlLoadStringOrError(hmodUser,
gpsi->mpAllMBbtnStringsToSTR[SEBbuttons[wBtnBeg + i] - SEB_OK],
szButtonBuf,
sizeof(szButtonBuf)/sizeof(WCHAR),
RT_STRING,
prescalls,
pMsgBoxParams->wLanguageId);
/*
* If it didn't find the string, use the default language.
*/
if (*szButtonBuf) {
apstrButton<i> = TextAlloc(szButtonBuf);
} else {
apstrButton<i> = TextAlloc(GETGPSIMBPSTR(SEBbuttons[wBtnBeg + i] - SEB_OK));
RIPMSG2(RIP_WARNING, "MessageBoxWorker: string resource %#lx for language %#lx not found",
gpsi->mpAllMBbtnStringsToSTR[SEBbuttons[wBtnBeg + i] - SEB_OK],
pMsgBoxParams->wLanguageId);
}
}
aidButton<i> = rgReturn[wBtnBeg + i];
if (aidButton<i> == IDCANCEL) {
fCancel = TRUE;
}
}
/*
* Hackery: There are some apps that use MessageBox as initial error
* indicators, such as mplay32, and we want this messagebox to be
* visible regardless of waht was specified in the StartupInfo->wShowWindow
* field. ccMail for instance starts all of its embedded objects hidden
* but on win 3.1 the error message would show because they don't have
* the startup info.
*/
NtUserSetUserStartupInfoFlags(NtUserGetUserStartupInfoFlags() & ~STARTF_USESHOWWINDOW);
pMsgBoxParams->pidButton = aidButton;
pMsgBoxParams->ppszButtonText = apstrButton;
pMsgBoxParams->DefButton = wDefButton;
pMsgBoxParams->cButtons = wBtnCnt;
pMsgBoxParams->CancelId = ((dwStyle & MB_TYPEMASK) == 0) ? IDOK : (fCancel ? IDCANCEL : 0);
retValue = SoftModalMessageBox(pMsgBoxParams);
if (pMsgBoxParams->wLanguageId != 0) {
for (i=0; i<wBtnCnt; i++)
UserLocalFree(apstrButton<i>);
}
return retValue;
}