Skip to content

Commit cb77cc7

Browse files
committed
[USER32] Specify the font to be used for the message-box in its dialog template, using DS_SETFONT and a font point size of 0x7FFF, instead of passing a font handle and setting the font of each control manually.
Also improve the flags used in the DrawTextW() call for calculating the size to be taken by the message-box text.
1 parent ed1de71 commit cb77cc7

File tree

1 file changed

+57
-27
lines changed

1 file changed

+57
-27
lines changed

win32ss/user/user32/windows/messagebox.c

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
5757
#define MSGBOXEX_MAXBTNS (4)
5858

5959
/* Rescale logical coordinates */
60-
#define RESCALE_X(_x, _unit) (((_x) * 4 + LOWORD(_unit) - 1) / LOWORD(_unit))
61-
#define RESCALE_Y(_y, _unit) (((_y) * 8 + HIWORD(_unit) - 1) / HIWORD(_unit))
60+
#define RESCALE_X(_x, _units) (((_x) * 4 + (_units).cx - 1) / (_units).cx)
61+
#define RESCALE_Y(_y, _units) (((_y) * 8 + (_units).cy - 1) / (_units).cy)
6262

6363

6464
/* MessageBox button helpers */
@@ -103,7 +103,6 @@ typedef struct _MSGBOXINFO
103103
MSGBOXPARAMSW; // Wine passes this too.
104104
// ReactOS
105105
HICON Icon;
106-
HFONT Font;
107106
int DefBtn;
108107
int nButtons;
109108
LONG *Btns;
@@ -220,7 +219,7 @@ static INT_PTR CALLBACK MessageBoxProc(
220219
HWND hwnd, UINT message,
221220
WPARAM wParam, LPARAM lParam)
222221
{
223-
int i, Alert;
222+
int Alert;
224223
PMSGBOXINFO mbi;
225224
HELPINFO hi;
226225
HWND owner;
@@ -267,12 +266,6 @@ static INT_PTR CALLBACK MessageBoxProc(
267266
/* Send out the alert notifications. */
268267
NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd, OBJID_ALERT, Alert);
269268

270-
/* set control fonts */
271-
SendDlgItemMessageW(hwnd, MSGBOX_IDTEXT, WM_SETFONT, (WPARAM)mbi->Font, 0);
272-
for (i = 0; i < mbi->nButtons; i++)
273-
{
274-
SendDlgItemMessageW(hwnd, mbi->Btns[i], WM_SETFONT, (WPARAM)mbi->Font, 0);
275-
}
276269
switch (mbi->dwStyle & MB_TYPEMASK)
277270
{
278271
case MB_ABORTRETRYIGNORE:
@@ -372,9 +365,11 @@ MessageBoxTimeoutIndirectW(
372365
LPVOID buf;
373366
BYTE *dest;
374367
LPCWSTR caption, text;
375-
HFONT hFont;
368+
HFONT hFont, hOldFont;
376369
HICON Icon;
370+
HWND hDCWnd;
377371
HDC hDC;
372+
SIZE units;
378373
int bufsize, ret, caplen, textlen, i, btnleft, btntop, lmargin;
379374
MSGBTNINFO Buttons;
380375
LPCWSTR ButtonText[MSGBOXEX_MAXBTNS];
@@ -384,7 +379,6 @@ MessageBoxTimeoutIndirectW(
384379
SIZE btnsize;
385380
MSGBOXINFO mbi;
386381
BOOL defbtn = FALSE;
387-
DWORD units = GetDialogBaseUnits();
388382

389383
if (!lpMsgBoxParams->lpszCaption)
390384
{
@@ -470,8 +464,9 @@ MessageBoxTimeoutIndirectW(
470464

471465
/* Basic space */
472466
bufsize = sizeof(DLGTEMPLATE) +
473-
2 * sizeof(WORD) + /* menu and class */
474-
(caplen + 1) * sizeof(WCHAR); /* title */
467+
2 * sizeof(WORD) + /* menu and class */
468+
(caplen + 1) * sizeof(WCHAR) + /* title */
469+
sizeof(WORD); /* font height */
475470

476471
/* Space for icon */
477472
if (NULL != Icon)
@@ -510,18 +505,22 @@ MessageBoxTimeoutIndirectW(
510505

511506
buf = RtlAllocateHeap(GetProcessHeap(), 0, bufsize);
512507
if (!buf)
513-
{
514508
return 0;
515-
}
509+
516510
iico = itxt = NULL;
517511

518512
nclm.cbSize = sizeof(nclm);
519-
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(nclm), &nclm, 0);
513+
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(nclm), &nclm, 0);
520514
hFont = CreateFontIndirectW(&nclm.lfMessageFont);
515+
if (!hFont)
516+
{
517+
ERR("Cannot retrieve nclm.lfMessageFont!\n");
518+
goto Quit;
519+
}
521520

522521
tpl = (DLGTEMPLATE *)buf;
523522

524-
tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | DS_NOIDLEMSG;
523+
tpl->style = WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU | DS_CENTER | DS_SETFONT | DS_MODALFRAME | DS_NOIDLEMSG;
525524
tpl->dwExtendedStyle = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
526525
if (lpMsgBoxParams->dwStyle & MB_TOPMOST)
527526
tpl->dwExtendedStyle |= WS_EX_TOPMOST;
@@ -541,6 +540,13 @@ MessageBoxTimeoutIndirectW(
541540
*(WCHAR*)dest = L'\0';
542541
dest += sizeof(WCHAR);
543542

543+
/*
544+
* A font point size (height) of 0x7FFF means that we use
545+
* the message box font (NONCLIENTMETRICSW.lfMessageFont).
546+
*/
547+
*(WORD*)dest = 0x7FFF;
548+
dest += sizeof(WORD);
549+
544550
/* Create icon */
545551
if (Icon)
546552
{
@@ -585,8 +591,30 @@ MessageBoxTimeoutIndirectW(
585591
*(WORD*)dest = 0;
586592
dest += sizeof(WORD);
587593

588-
hDC = CreateCompatibleDC(0);
589-
SelectObject(hDC, hFont);
594+
hDCWnd = NULL;
595+
hDC = GetDCEx(hDCWnd, NULL, DCX_WINDOW | DCX_CACHE);
596+
if (!hDC)
597+
{
598+
/* Retry with the DC of the owner window */
599+
hDCWnd = lpMsgBoxParams->hwndOwner;
600+
hDC = GetDCEx(hDCWnd, NULL, DCX_WINDOW | DCX_CACHE);
601+
}
602+
if (!hDC)
603+
{
604+
ERR("GetDCEx() failed, bail out!\n");
605+
goto Quit;
606+
}
607+
hOldFont = SelectObject(hDC, hFont);
608+
609+
units.cx = GdiGetCharDimensions(hDC, NULL, &units.cy);
610+
if (!units.cx)
611+
{
612+
DWORD defUnits;
613+
ERR("GdiGetCharDimensions() failed, falling back to default values!\n");
614+
defUnits = GetDialogBaseUnits();
615+
units.cx = LOWORD(defUnits);
616+
units.cy = HIWORD(defUnits);
617+
}
590618

591619
/* create buttons */
592620
btnsize.cx = BTN_CX;
@@ -643,7 +671,7 @@ MessageBoxTimeoutIndirectW(
643671
txtrect.top = txtrect.left = txtrect.bottom = 0;
644672
if (textlen != 0)
645673
{
646-
DrawTextW(hDC, text, textlen, &txtrect, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);
674+
DrawTextW(hDC, text, textlen, &txtrect, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_EXPANDTABS | DT_EXTERNALLEADING | DT_EDITCONTROL | DT_CALCRECT);
647675
}
648676
else
649677
{
@@ -652,8 +680,13 @@ MessageBoxTimeoutIndirectW(
652680
}
653681
txtrect.right++;
654682

655-
if (hDC)
656-
DeleteDC(hDC);
683+
if (hOldFont)
684+
SelectObject(hDC, hOldFont);
685+
686+
ReleaseDC(hDCWnd, hDC);
687+
688+
if (hFont)
689+
DeleteObject(hFont);
657690

658691
/* calculate position and size of the icon */
659692
rc.left = rc.bottom = rc.right = 0;
@@ -739,7 +772,6 @@ MessageBoxTimeoutIndirectW(
739772

740773
/* finally show the messagebox */
741774
mbi.Icon = Icon;
742-
mbi.Font = hFont;
743775
mbi.dwContextHelpId = lpMsgBoxParams->dwContextHelpId;
744776
mbi.lpfnMsgBoxCallback = lpMsgBoxParams->lpfnMsgBoxCallback;
745777
mbi.dwStyle = lpMsgBoxParams->dwStyle;
@@ -759,9 +791,7 @@ MessageBoxTimeoutIndirectW(
759791
ret = DialogBoxIndirectParamW(lpMsgBoxParams->hInstance, tpl, lpMsgBoxParams->hwndOwner,
760792
MessageBoxProc, (LPARAM)&mbi);
761793

762-
if (hFont)
763-
DeleteObject(hFont);
764-
794+
Quit:
765795
RtlFreeHeap(GetProcessHeap(), 0, buf);
766796
return ret;
767797
}

0 commit comments

Comments
 (0)