21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_WINDOWS 25 #include "../../core/windows/SDL_windows.h" 31 #ifndef SS_EDITCONTROL 32 #define SS_EDITCONTROL 0x2000 69 DLGTEMPLATEEX* lpDialog;
76 static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
81 EndDialog(hDlg, LOWORD(wParam));
90 static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog,
size_t space)
92 size_t size = dialog->size;
97 while ((dialog->used + space) > size) {
101 if (size > dialog->size) {
109 dialog->lpDialog = (DLGTEMPLATEEX*)dialog->data;
114 static SDL_bool AlignDialogData(WIN_DialogData *dialog,
size_t size)
116 size_t padding = (dialog->used %
size);
118 if (!ExpandDialogSpace(dialog, padding)) {
122 dialog->used += padding;
127 static SDL_bool AddDialogData(WIN_DialogData *dialog,
const void *
data,
size_t size)
129 if (!ExpandDialogSpace(dialog, size)) {
133 SDL_memcpy(dialog->data+dialog->used, data, size);
134 dialog->used +=
size;
139 static SDL_bool AddDialogString(WIN_DialogData *dialog,
const char *
string)
157 for (p = wstring; *
p; ++
p) {
162 status = AddDialogData(dialog, wstring, count*
sizeof(WCHAR));
167 static int s_BaseUnitsX;
168 static int s_BaseUnitsY;
169 static void Vec2ToDLU(
short *
x,
short *
y)
173 *x = MulDiv(*x, 4, s_BaseUnitsX);
174 *y = MulDiv(*y, 8, s_BaseUnitsY);
178 static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD
type, DWORD style, DWORD exStyle,
int x,
int y,
int w,
int h,
int id,
const char *caption)
180 DLGITEMTEMPLATEEX item;
186 item.exStyle = exStyle;
193 Vec2ToDLU(&item.x, &item.y);
194 Vec2ToDLU(&item.cx, &item.cy);
196 if (!AlignDialogData(dialog,
sizeof(DWORD))) {
199 if (!AddDialogData(dialog, &item,
sizeof(item))) {
202 if (!AddDialogData(dialog, &marker,
sizeof(marker))) {
205 if (!AddDialogData(dialog, &type,
sizeof(type))) {
208 if (!AddDialogString(dialog, caption)) {
211 if (!AddDialogData(dialog, &extraData,
sizeof(extraData))) {
214 ++dialog->lpDialog->cDlgItems;
219 static SDL_bool AddDialogStatic(WIN_DialogData *dialog,
int x,
int y,
int w,
int h,
const char *
text)
221 DWORD style = WS_VISIBLE | WS_CHILD | SS_LEFT | SS_NOPREFIX | SS_EDITCONTROL;
222 return AddDialogControl(dialog, 0x0082, style, 0, x, y, w, h, -1, text);
225 static SDL_bool AddDialogButton(WIN_DialogData *dialog,
int x,
int y,
int w,
int h,
const char *
text,
int id,
SDL_bool isDefault)
227 DWORD style = WS_VISIBLE | WS_CHILD;
229 style |= BS_DEFPUSHBUTTON;
231 style |= BS_PUSHBUTTON;
233 return AddDialogControl(dialog, 0x0080, style, 0, x, y, w, h,
id, text);
236 static void FreeDialogData(WIN_DialogData *dialog)
242 static WIN_DialogData *CreateDialogData(
int w,
int h,
const char *caption)
244 WIN_DialogData *dialog;
245 DLGTEMPLATEEX dialogTemplate;
249 dialogTemplate.dlgVer = 1;
250 dialogTemplate.signature = 0xffff;
251 dialogTemplate.style = (WS_CAPTION | DS_CENTER | DS_SHELLFONT);
252 dialogTemplate.x = 0;
253 dialogTemplate.y = 0;
254 dialogTemplate.cx =
w;
255 dialogTemplate.cy =
h;
256 Vec2ToDLU(&dialogTemplate.cx, &dialogTemplate.cy);
258 dialog = (WIN_DialogData *)
SDL_calloc(1,
sizeof(*dialog));
263 if (!AddDialogData(dialog, &dialogTemplate,
sizeof(dialogTemplate))) {
264 FreeDialogData(dialog);
270 if (!AddDialogData(dialog, &WordToPass, 2)) {
271 FreeDialogData(dialog);
276 if (!AddDialogData(dialog, &WordToPass, 2)) {
277 FreeDialogData(dialog);
282 if (!AddDialogString(dialog, caption)) {
283 FreeDialogData(dialog);
294 NONCLIENTMETRICSA NCM;
295 NCM.cbSize =
sizeof(NCM);
296 SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
300 HDC ScreenDC = GetDC(
NULL);
301 int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY);
304 WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY);
305 ReleaseDC(
NULL, ScreenDC);
308 if (!AddDialogData(dialog, &WordToPass, 2)) {
309 FreeDialogData(dialog);
314 WordToPass = (WORD)NCM.lfMessageFont.lfWeight;
315 if (!AddDialogData(dialog, &WordToPass, 2)) {
316 FreeDialogData(dialog);
321 ToPass = NCM.lfMessageFont.lfItalic;
322 if (!AddDialogData(dialog, &ToPass, 1)) {
323 FreeDialogData(dialog);
328 ToPass = NCM.lfMessageFont.lfCharSet;
329 if (!AddDialogData(dialog, &ToPass, 1)) {
330 FreeDialogData(dialog);
335 if (!AddDialogString(dialog, NCM.lfMessageFont.lfFaceName)) {
336 FreeDialogData(dialog);
347 WIN_DialogData *dialog;
356 HWND ParentWindow =
NULL;
358 const int ButtonWidth = 88;
359 const int ButtonHeight = 26;
360 const int TextMargin = 16;
361 const int ButtonMargin = 12;
396 HDC FontDC = CreateCompatibleDC(0);
401 NONCLIENTMETRICS NCM;
402 NCM.cbSize =
sizeof(NCM);
403 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
404 lf = NCM.lfMessageFont;
405 DialogFont = CreateFontIndirect(&lf);
409 SelectObject(FontDC, DialogFont);
413 GetTextMetrics(FontDC, &TM);
421 GetTextExtentPoint32A(FontDC,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &extent);
422 s_BaseUnitsX = (extent.cx / 26 + 1) / 2;
425 s_BaseUnitsY = TM.tmHeight;
431 DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);
435 TextSize.bottom += 2;
442 Size.cx = TextSize.right - TextSize.left;
443 Size.cy = TextSize.bottom - TextSize.top;
444 Size.cx += TextMargin * 2;
445 Size.cy += TextMargin * 2;
448 if (Size.cx < messageboxdata->
numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
449 Size.cx = messageboxdata->
numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
452 Size.cy += ButtonHeight + TextMargin;
454 dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->
title);
459 if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->
message)) {
460 FreeDialogData(dialog);
465 x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->
numbuttons;
466 y = Size.cy - ButtonHeight - ButtonMargin;
467 for (i = messageboxdata->
numbuttons - 1; i >= 0; --i) {
475 if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, buttons[i].buttonid, isDefault)) {
476 FreeDialogData(dialog);
479 x += ButtonWidth + ButtonMargin;
484 if (messageboxdata->
window) {
488 *buttonid = (int)DialogBoxIndirect(
NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc);
490 FreeDialogData(dialog);
#define WIN_UTF8ToString(S)
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
GLfloat GLfloat GLfloat GLfloat h
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLubyte GLubyte GLubyte GLubyte w
GLint GLint GLint GLint GLint GLint y
const SDL_MessageBoxButtonData * buttons
MessageBox structure containing title, text, window, etc.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#define SDL_assert(condition)
#define SDL_OutOfMemory()
static char text[MAX_TEXT_LENGTH]
GLuint GLuint GLsizei GLenum type