📄 messagebox.c
字号:
ibtn[i]->id = Buttons[i];
dest += sizeof(DLGITEMTEMPLATE);
*(WORD*)dest = 0xFFFF;
dest += sizeof(WORD);
*(WORD*)dest = 0x0080; /* button control */
dest += sizeof(WORD);
btnlen = strlenW(ButtonText[i]);
memcpy(dest, ButtonText[i], btnlen * sizeof(WCHAR));
dest += btnlen * sizeof(WCHAR);
*(WORD*)dest = 0;
dest += sizeof(WORD);
*(WORD*)dest = 0;
dest += sizeof(WORD);
SelectObject(hDC, hFont);
DrawTextW(hDC, ButtonText[i], btnlen, &btnrect, DT_LEFT | DT_SINGLELINE | DT_CALCRECT);
btnsize.cx = max(btnsize.cx, btnrect.right);
btnsize.cy = max(btnsize.cy, btnrect.bottom);
}
/* make first button the default button if no other is */
if(!defbtn)
{
ibtn[0]->style &= ~BS_PUSHBUTTON;
ibtn[0]->style |= BS_DEFPUSHBUTTON;
mbi.DefBtn = Buttons[0];
}
/* calculate position and size of controls */
txtrect.right = GetSystemMetrics(SM_CXSCREEN) / 5 * 4;
if(Icon)
txtrect.right -= GetSystemMetrics(SM_CXICON) + MSGBOXEX_SPACING;
txtrect.top = txtrect.left = txtrect.bottom = 0;
SelectObject(hDC, hFont);
if (textlen != 0)
{
DrawTextW(hDC, text, textlen, &txtrect, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);
}
else
{
txtrect.right = txtrect.left + 1;
txtrect.bottom = txtrect.top + 1;
}
txtrect.right++;
/* calculate position and size of the icon */
rc.left = rc.bottom = rc.right = 0;
btntop = 0;
if(iico)
{
rc.right = GetSystemMetrics(SM_CXICON);
rc.bottom = GetSystemMetrics(SM_CYICON);
#ifdef MSGBOX_ICONVCENTER
rc.top = MSGBOXEX_MARGIN + (max(txtrect.bottom, rc.bottom) / 2) - (GetSystemMetrics(SM_CYICON) / 2);
rc.top = max(MSGBOXEX_SPACING, rc.top);
#else
rc.top = MSGBOXEX_MARGIN;
#endif
btnleft = (nButtons * (btnsize.cx + MSGBOXEX_BUTTONSPACING)) - MSGBOXEX_BUTTONSPACING;
if(btnleft > txtrect.right + rc.right + MSGBOXEX_SPACING)
{
#ifdef MSGBOX_TEXTHCENTER
lmargin = MSGBOXEX_MARGIN + ((btnleft - txtrect.right - rc.right - MSGBOXEX_SPACING) / 2);
#else
lmargin = MSGBOXEX_MARGIN;
#endif
btnleft = MSGBOXEX_MARGIN;
}
else
{
lmargin = MSGBOXEX_MARGIN;
btnleft = MSGBOXEX_MARGIN + ((txtrect.right + rc.right + MSGBOXEX_SPACING) / 2) - (btnleft / 2);
}
rc.left = lmargin;
iico->x = (rc.left * 4) / LOWORD(units);
iico->y = (rc.top * 8) / HIWORD(units);
iico->cx = (rc.right * 4) / LOWORD(units);
iico->cy = (rc.bottom * 8) / HIWORD(units);
btntop = rc.top + rc.bottom + MSGBOXEX_SPACING;
rc.left += rc.right + MSGBOXEX_SPACING;
}
else
{
btnleft = (nButtons * (btnsize.cx + MSGBOXEX_BUTTONSPACING)) - MSGBOXEX_BUTTONSPACING;
if(btnleft > txtrect.right)
{
#ifdef MSGBOX_TEXTHCENTER
lmargin = MSGBOXEX_MARGIN + ((btnleft - txtrect.right) / 2);
#else
lmargin = MSGBOXEX_MARGIN;
#endif
btnleft = MSGBOXEX_MARGIN;
}
else
{
lmargin = MSGBOXEX_MARGIN;
btnleft = MSGBOXEX_MARGIN + (txtrect.right / 2) - (btnleft / 2);
}
rc.left = lmargin;
}
/* calculate position of the text */
rc.top = MSGBOXEX_MARGIN + (rc.bottom / 2) - (txtrect.bottom / 2);
rc.top = max(rc.top, MSGBOXEX_MARGIN);
/* calculate position of the buttons */
btntop = max(rc.top + txtrect.bottom + MSGBOXEX_SPACING, btntop);
for(i = 0; i < nButtons; i++)
{
ibtn[i]->x = (btnleft * 4) / LOWORD(units);
ibtn[i]->y = (btntop * 8) / HIWORD(units);
ibtn[i]->cx = (btnsize.cx * 4) / LOWORD(units);
ibtn[i]->cy = (btnsize.cy * 8) / HIWORD(units);
btnleft += btnsize.cx + MSGBOXEX_BUTTONSPACING;
}
/* calculate size and position of the messagebox window */
btnleft = max(btnleft - MSGBOXEX_BUTTONSPACING, rc.left + txtrect.right);
btnleft += MSGBOXEX_MARGIN;
btntop += btnsize.cy + MSGBOXEX_MARGIN;
/* set size and position of the message static */
itxt->x = (rc.left * 4) / LOWORD(units);
itxt->y = (rc.top * 8) / HIWORD(units);
itxt->cx = (((btnleft - rc.left - MSGBOXEX_MARGIN) * 4) / LOWORD(units));
itxt->cy = ((txtrect.bottom * 8) / HIWORD(units));
/* set size of the window */
tpl->cx = (btnleft * 4) / LOWORD(units);
tpl->cy = (btntop * 8) / HIWORD(units);
/* finally show the messagebox */
mbi.Icon = Icon;
mbi.Font = hFont;
mbi.ContextHelpId = lpMsgBoxParams->dwContextHelpId;
mbi.Callback = lpMsgBoxParams->lpfnMsgBoxCallback;
mbi.Style = lpMsgBoxParams->dwStyle;
mbi.nButtons = nButtons;
mbi.Btns = &Buttons[0];
mbi.Timeout = Timeout;
if(hDC)
DeleteDC(hDC);
ret = DialogBoxIndirectParamW(lpMsgBoxParams->hInstance, tpl, lpMsgBoxParams->hwndOwner,
MessageBoxProc, (LPARAM)&mbi);
if(hFont)
DeleteObject(hFont);
RtlFreeHeap(GetProcessHeap(), 0, buf);
return ret;
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
int
STDCALL
MessageBoxA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType)
{
return MessageBoxExA(hWnd, lpText, lpCaption, uType, LANG_NEUTRAL);
}
/*
* @implemented
*/
int
STDCALL
MessageBoxExA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType,
WORD wLanguageId)
{
MSGBOXPARAMSA msgbox;
msgbox.cbSize = sizeof(msgbox);
msgbox.hwndOwner = hWnd;
msgbox.hInstance = 0;
msgbox.lpszText = lpText;
msgbox.lpszCaption = lpCaption;
msgbox.dwStyle = uType;
msgbox.lpszIcon = NULL;
msgbox.dwContextHelpId = 0;
msgbox.lpfnMsgBoxCallback = NULL;
msgbox.dwLanguageId = wLanguageId;
return MessageBoxIndirectA(&msgbox);
}
/*
* @implemented
*/
int
STDCALL
MessageBoxExW(
HWND hWnd,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType,
WORD wLanguageId)
{
MSGBOXPARAMSW msgbox;
msgbox.cbSize = sizeof(msgbox);
msgbox.hwndOwner = hWnd;
msgbox.hInstance = 0;
msgbox.lpszText = lpText;
msgbox.lpszCaption = lpCaption;
msgbox.dwStyle = uType;
msgbox.lpszIcon = NULL;
msgbox.dwContextHelpId = 0;
msgbox.lpfnMsgBoxCallback = NULL;
msgbox.dwLanguageId = wLanguageId;
return MessageBoxTimeoutIndirectW(&msgbox, (UINT)-1);
}
/*
* @implemented
*/
int
STDCALL
MessageBoxIndirectA(
CONST MSGBOXPARAMSA *lpMsgBoxParams)
{
MSGBOXPARAMSW msgboxW;
UNICODE_STRING textW, captionW, iconW;
int ret;
if (HIWORD((UINT)lpMsgBoxParams->lpszText))
{
RtlCreateUnicodeStringFromAsciiz(&textW, (PCSZ)lpMsgBoxParams->lpszText);
/*
* UNICODE_STRING objects are always allocated with an extra byte so you
* can null-term if you want
*/
textW.Buffer[textW.Length / sizeof(WCHAR)] = L'\0';
}
else
textW.Buffer = (LPWSTR)lpMsgBoxParams->lpszText;
if (HIWORD((UINT)lpMsgBoxParams->lpszCaption))
{
RtlCreateUnicodeStringFromAsciiz(&captionW, (PCSZ)lpMsgBoxParams->lpszCaption);
/*
* UNICODE_STRING objects are always allocated with an extra byte so you
* can null-term if you want
*/
captionW.Buffer[captionW.Length / sizeof(WCHAR)] = L'\0';
}
else
captionW.Buffer = (LPWSTR)lpMsgBoxParams->lpszCaption;
if(lpMsgBoxParams->dwStyle & MB_USERICON)
{
if (HIWORD((UINT)lpMsgBoxParams->lpszIcon))
{
RtlCreateUnicodeStringFromAsciiz(&iconW, (PCSZ)lpMsgBoxParams->lpszIcon);
/*
* UNICODE_STRING objects are always allocated with an extra byte so you
* can null-term if you want
*/
iconW.Buffer[iconW.Length / sizeof(WCHAR)] = L'\0';
}
else
iconW.Buffer = (LPWSTR)lpMsgBoxParams->lpszIcon;
}
else
iconW.Buffer = NULL;
msgboxW.cbSize = sizeof(msgboxW);
msgboxW.hwndOwner = lpMsgBoxParams->hwndOwner;
msgboxW.hInstance = lpMsgBoxParams->hInstance;
msgboxW.lpszText = textW.Buffer;
msgboxW.lpszCaption = captionW.Buffer;
msgboxW.dwStyle = lpMsgBoxParams->dwStyle;
msgboxW.lpszIcon = iconW.Buffer;
msgboxW.dwContextHelpId = lpMsgBoxParams->dwContextHelpId;
msgboxW.lpfnMsgBoxCallback = lpMsgBoxParams->lpfnMsgBoxCallback;
msgboxW.dwLanguageId = lpMsgBoxParams->dwLanguageId;
ret = MessageBoxTimeoutIndirectW(&msgboxW, (UINT)-1);
if (HIWORD((UINT)lpMsgBoxParams->lpszText))
RtlFreeUnicodeString(&textW);
if (HIWORD((UINT)lpMsgBoxParams->lpszCaption))
RtlFreeUnicodeString(&captionW);
if ((lpMsgBoxParams->dwStyle & MB_USERICON) && HIWORD((UINT)iconW.Buffer))
RtlFreeUnicodeString(&iconW);
return ret;
}
/*
* @implemented
*/
int
STDCALL
MessageBoxIndirectW(
CONST MSGBOXPARAMSW *lpMsgBoxParams)
{
return MessageBoxTimeoutIndirectW(lpMsgBoxParams, (UINT)-1);
}
/*
* @implemented
*/
int
STDCALL
MessageBoxW(
HWND hWnd,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType)
{
return MessageBoxExW(hWnd, lpText, lpCaption, uType, LANG_NEUTRAL);
}
/*
* @implemented
*/
int
STDCALL
MessageBoxTimeoutA(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType,
WORD wLanguageId,
DWORD dwTime)
{
MSGBOXPARAMSW msgboxW;
UNICODE_STRING textW, captionW;
int ret;
if (HIWORD((UINT)lpText))
RtlCreateUnicodeStringFromAsciiz(&textW, (PCSZ)lpText);
else
textW.Buffer = (LPWSTR)lpText;
if (HIWORD((UINT)lpCaption))
RtlCreateUnicodeStringFromAsciiz(&captionW, (PCSZ)lpCaption);
else
captionW.Buffer = (LPWSTR)lpCaption;
msgboxW.cbSize = sizeof(msgboxW);
msgboxW.hwndOwner = hWnd;
msgboxW.hInstance = 0;
msgboxW.lpszText = textW.Buffer;
msgboxW.lpszCaption = captionW.Buffer;
msgboxW.dwStyle = uType;
msgboxW.lpszIcon = NULL;
msgboxW.dwContextHelpId = 0;
msgboxW.lpfnMsgBoxCallback = NULL;
msgboxW.dwLanguageId = wLanguageId;
ret = MessageBoxTimeoutIndirectW(&msgboxW, (UINT)dwTime);
if (HIWORD(textW.Buffer))
RtlFreeUnicodeString(&textW);
if (HIWORD(captionW.Buffer))
RtlFreeUnicodeString(&captionW);
return ret;
}
/*
* @implemented
*/
int
STDCALL
MessageBoxTimeoutW(
HWND hWnd,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType,
WORD wLanguageId,
DWORD dwTime)
{
MSGBOXPARAMSW msgbox;
msgbox.cbSize = sizeof(msgbox);
msgbox.hwndOwner = hWnd;
msgbox.hInstance = 0;
msgbox.lpszText = lpText;
msgbox.lpszCaption = lpCaption;
msgbox.dwStyle = uType;
msgbox.lpszIcon = NULL;
msgbox.dwContextHelpId = 0;
msgbox.lpfnMsgBoxCallback = NULL;
msgbox.dwLanguageId = wLanguageId;
return MessageBoxTimeoutIndirectW(&msgbox, (UINT)dwTime);
}
/*
* @unimplemented
*/
DWORD
STDCALL
SoftModalMessageBox(DWORD Unknown0)
{
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/
BOOL
STDCALL
MessageBeep(UINT uType)
{
#if 0
LPWSTR EventName;
switch(uType)
{
case 0xFFFFFFFF:
if(waveOutGetNumDevs() == 0)
return Beep(500, 100); // Beep through speaker
/* fall through */
case MB_OK:
EventName = L"SystemDefault";
break;
case MB_ICONASTERISK:
EventName = L"SystemAsterisk";
break;
case MB_ICONEXCLAMATION:
EventName = L"SystemExclamation";
break;
case MB_ICONHAND:
EventName = L"SystemHand";
break;
case MB_ICONQUESTION:
EventName = L"SystemQuestion";
break;
}
return PlaySoundW((LPCWSTR)EventName, NULL, SND_ALIAS | SND_NOWAIT | SND_NOSTOP | SND_ASYNC);
#else
return Beep(500, 100); // Beep through speaker
#endif
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -