src/video/windows/SDL_windowsmessagebox.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 07 Oct 2016 16:19:50 -0700
changeset 10478 30302a3c5df7
parent 9998 f67cf37e9cd4
child 10737 3406a0f8b041
permissions -rw-r--r--
Fixed bug 2832 - Inverted arrow-key navigation in MessageBox

Jan Hellwig

On Windows, you are able to navigate between the buttons on a MessageBox that was created using SDL_ShowMessageBox using the arrow keys. However, if you press the left arrow key, the selection jumps to the button on the right of the currently selected one (and vice versa).

This can be fixed by reversing the order in which the buttons are added to the dialog.

The attached patch files fixes this problem. However the first press of an arrow key leads to the selection of the leftmost or rightmost button on the MessageBox, not to the selection of the button left/right of the one that is selected by default.
slouken@6620
     1
/*
slouken@6620
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
slouken@6620
     4
slouken@6620
     5
  This software is provided 'as-is', without any express or implied
slouken@6620
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@6620
     7
  arising from the use of this software.
slouken@6620
     8
slouken@6620
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@6620
    10
  including commercial applications, and to alter it and redistribute it
slouken@6620
    11
  freely, subject to the following restrictions:
slouken@6620
    12
slouken@6620
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@6620
    14
     claim that you wrote the original software. If you use this software
slouken@6620
    15
     in a product, an acknowledgment in the product documentation would be
slouken@6620
    16
     appreciated but is not required.
slouken@6620
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@6620
    18
     misrepresented as being the original software.
slouken@6620
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@6620
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@6620
    22
slouken@6620
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6620
    24
slouken@7828
    25
#include "../../core/windows/SDL_windows.h"
slouken@7828
    26
slouken@7828
    27
#include "SDL_assert.h"
slouken@6620
    28
#include "SDL_windowsvideo.h"
slouken@6620
    29
slouken@6620
    30
slouken@7030
    31
#ifndef SS_EDITCONTROL
slouken@7030
    32
#define SS_EDITCONTROL  0x2000
slouken@7030
    33
#endif
slouken@7030
    34
slouken@6620
    35
/* Display a Windows message box */
slouken@6620
    36
slouken@7028
    37
#pragma pack(push, 1)
slouken@7028
    38
slouken@6620
    39
typedef struct
slouken@6620
    40
{
slouken@7191
    41
    WORD dlgVer;
slouken@7191
    42
    WORD signature;
slouken@7191
    43
    DWORD helpID;
slouken@7191
    44
    DWORD exStyle;
slouken@7191
    45
    DWORD style;
slouken@7191
    46
    WORD cDlgItems;
slouken@7191
    47
    short x;
slouken@7191
    48
    short y;
slouken@7191
    49
    short cx;
slouken@7191
    50
    short cy;
slouken@7028
    51
} DLGTEMPLATEEX;
slouken@7028
    52
slouken@7028
    53
typedef struct
slouken@7028
    54
{
slouken@7191
    55
    DWORD helpID;
slouken@7191
    56
    DWORD exStyle;
slouken@7191
    57
    DWORD style;
slouken@7191
    58
    short x;
slouken@7191
    59
    short y;
slouken@7191
    60
    short cx;
slouken@7191
    61
    short cy;
slouken@7191
    62
    DWORD id;
slouken@7028
    63
} DLGITEMTEMPLATEEX;
slouken@7028
    64
slouken@7028
    65
#pragma pack(pop)
slouken@7028
    66
slouken@7028
    67
typedef struct
slouken@7028
    68
{
slouken@7028
    69
    DLGTEMPLATEEX* lpDialog;
slouken@6620
    70
    Uint8 *data;
slouken@6620
    71
    size_t size;
slouken@6620
    72
    size_t used;
slouken@6620
    73
} WIN_DialogData;
slouken@6620
    74
slouken@6620
    75
slouken@6620
    76
static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
slouken@6620
    77
{
slouken@6620
    78
    switch ( iMessage ) {
slouken@6620
    79
    case WM_COMMAND:
slouken@6620
    80
        /* Return the ID of the button that was pushed */
slouken@7191
    81
        EndDialog(hDlg, LOWORD(wParam));
slouken@6620
    82
        return TRUE;
slouken@6620
    83
slouken@6620
    84
    default:
slouken@6620
    85
        break;
slouken@6620
    86
    }
slouken@6620
    87
    return FALSE;
slouken@6620
    88
}
slouken@6620
    89
slouken@6620
    90
static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
slouken@6620
    91
{
slouken@6620
    92
    size_t size = dialog->size;
slouken@6620
    93
slouken@6620
    94
    if (size == 0) {
slouken@6620
    95
        size = space;
slouken@6620
    96
    } else {
slouken@6620
    97
        while ((dialog->used + space) > size) {
slouken@6620
    98
            size *= 2;
slouken@6620
    99
        }
slouken@6620
   100
    }
slouken@6620
   101
    if (size > dialog->size) {
slouken@6620
   102
        void *data = SDL_realloc(dialog->data, size);
slouken@6620
   103
        if (!data) {
slouken@6620
   104
            SDL_OutOfMemory();
slouken@6620
   105
            return SDL_FALSE;
slouken@6620
   106
        }
slouken@6620
   107
        dialog->data = data;
slouken@6620
   108
        dialog->size = size;
slouken@7028
   109
        dialog->lpDialog = (DLGTEMPLATEEX*)dialog->data;
slouken@6620
   110
    }
slouken@6620
   111
    return SDL_TRUE;
slouken@6620
   112
}
slouken@7191
   113
slouken@6620
   114
static SDL_bool AlignDialogData(WIN_DialogData *dialog, size_t size)
slouken@6620
   115
{
slouken@6620
   116
    size_t padding = (dialog->used % size);
slouken@6620
   117
slouken@6620
   118
    if (!ExpandDialogSpace(dialog, padding)) {
slouken@6620
   119
        return SDL_FALSE;
slouken@6620
   120
    }
slouken@6620
   121
slouken@6620
   122
    dialog->used += padding;
slouken@6620
   123
slouken@6620
   124
    return SDL_TRUE;
slouken@6620
   125
}
slouken@6620
   126
slouken@6620
   127
static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
slouken@6620
   128
{
slouken@6620
   129
    if (!ExpandDialogSpace(dialog, size)) {
slouken@6620
   130
        return SDL_FALSE;
slouken@6620
   131
    }
slouken@6620
   132
slouken@6620
   133
    SDL_memcpy(dialog->data+dialog->used, data, size);
slouken@6620
   134
    dialog->used += size;
slouken@6620
   135
slouken@6620
   136
    return SDL_TRUE;
slouken@6620
   137
}
slouken@6620
   138
slouken@6620
   139
static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
slouken@6620
   140
{
slouken@6620
   141
    WCHAR *wstring;
slouken@6620
   142
    WCHAR *p;
slouken@6620
   143
    size_t count;
slouken@6620
   144
    SDL_bool status;
slouken@6620
   145
slouken@6620
   146
    if (!string) {
slouken@6620
   147
        string = "";
slouken@6620
   148
    }
slouken@6620
   149
slouken@6620
   150
    wstring = WIN_UTF8ToString(string);
slouken@6620
   151
    if (!wstring) {
slouken@6620
   152
        return SDL_FALSE;
slouken@6620
   153
    }
slouken@6620
   154
slouken@6620
   155
    /* Find out how many characters we have, including null terminator */
slouken@6620
   156
    count = 0;
slouken@6620
   157
    for (p = wstring; *p; ++p) {
slouken@6620
   158
        ++count;
slouken@6620
   159
    }
slouken@6620
   160
    ++count;
slouken@6620
   161
slouken@6620
   162
    status = AddDialogData(dialog, wstring, count*sizeof(WCHAR));
slouken@6620
   163
    SDL_free(wstring);
slouken@6620
   164
    return status;
slouken@6620
   165
}
slouken@6620
   166
slouken@7028
   167
static int s_BaseUnitsX;
slouken@7028
   168
static int s_BaseUnitsY;
icculus@7052
   169
static void Vec2ToDLU(short *x, short *y)
slouken@7028
   170
{
slouken@7191
   171
    SDL_assert(s_BaseUnitsX != 0); /* we init in WIN_ShowMessageBox(), which is the only public function... */
slouken@7028
   172
slouken@7028
   173
    *x = MulDiv(*x, 4, s_BaseUnitsX);
slouken@7028
   174
    *y = MulDiv(*y, 8, s_BaseUnitsY);
slouken@7028
   175
}
slouken@7028
   176
slouken@7028
   177
slouken@6620
   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)
slouken@6620
   179
{
slouken@7028
   180
    DLGITEMTEMPLATEEX item;
slouken@6620
   181
    WORD marker = 0xFFFF;
slouken@6620
   182
    WORD extraData = 0;
slouken@6620
   183
slouken@6620
   184
    SDL_zero(item);
slouken@6620
   185
    item.style = style;
slouken@7028
   186
    item.exStyle = exStyle;
slouken@6620
   187
    item.x = x;
slouken@6620
   188
    item.y = y;
slouken@6620
   189
    item.cx = w;
slouken@6620
   190
    item.cy = h;
slouken@6620
   191
    item.id = id;
slouken@6620
   192
slouken@7028
   193
    Vec2ToDLU(&item.x, &item.y);
slouken@7028
   194
    Vec2ToDLU(&item.cx, &item.cy);
slouken@7028
   195
slouken@6620
   196
    if (!AlignDialogData(dialog, sizeof(DWORD))) {
slouken@6620
   197
        return SDL_FALSE;
slouken@6620
   198
    }
slouken@6620
   199
    if (!AddDialogData(dialog, &item, sizeof(item))) {
slouken@6620
   200
        return SDL_FALSE;
slouken@6620
   201
    }
slouken@6620
   202
    if (!AddDialogData(dialog, &marker, sizeof(marker))) {
slouken@6620
   203
        return SDL_FALSE;
slouken@6620
   204
    }
slouken@6620
   205
    if (!AddDialogData(dialog, &type, sizeof(type))) {
slouken@6620
   206
        return SDL_FALSE;
slouken@6620
   207
    }
slouken@6620
   208
    if (!AddDialogString(dialog, caption)) {
slouken@6620
   209
        return SDL_FALSE;
slouken@6620
   210
    }
slouken@6620
   211
    if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
slouken@6620
   212
        return SDL_FALSE;
slouken@6620
   213
    }
slouken@7028
   214
    ++dialog->lpDialog->cDlgItems;
slouken@6620
   215
slouken@6620
   216
    return SDL_TRUE;
slouken@6620
   217
}
slouken@6620
   218
slouken@6620
   219
static SDL_bool AddDialogStatic(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
slouken@6620
   220
{
slouken@7028
   221
    DWORD style = WS_VISIBLE | WS_CHILD | SS_LEFT | SS_NOPREFIX | SS_EDITCONTROL;
slouken@6620
   222
    return AddDialogControl(dialog, 0x0082, style, 0, x, y, w, h, -1, text);
slouken@6620
   223
}
slouken@6620
   224
slouken@6620
   225
static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, SDL_bool isDefault)
slouken@6620
   226
{
slouken@6620
   227
    DWORD style = WS_VISIBLE | WS_CHILD;
slouken@6620
   228
    if (isDefault) {
slouken@6620
   229
        style |= BS_DEFPUSHBUTTON;
slouken@6620
   230
    } else {
slouken@6620
   231
        style |= BS_PUSHBUTTON;
slouken@6620
   232
    }
slouken@6620
   233
    return AddDialogControl(dialog, 0x0080, style, 0, x, y, w, h, id, text);
slouken@6620
   234
}
slouken@6620
   235
slouken@6620
   236
static void FreeDialogData(WIN_DialogData *dialog)
slouken@6620
   237
{
slouken@7719
   238
    SDL_free(dialog->data);
slouken@6620
   239
    SDL_free(dialog);
slouken@6620
   240
}
slouken@6620
   241
slouken@6620
   242
static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
slouken@6620
   243
{
slouken@6620
   244
    WIN_DialogData *dialog;
slouken@7028
   245
    DLGTEMPLATEEX dialogTemplate;
slouken@7028
   246
    WORD WordToPass;
slouken@6620
   247
slouken@6620
   248
    SDL_zero(dialogTemplate);
slouken@7028
   249
    dialogTemplate.dlgVer = 1;
slouken@7028
   250
    dialogTemplate.signature = 0xffff;
slouken@7028
   251
    dialogTemplate.style = (WS_CAPTION | DS_CENTER | DS_SHELLFONT);
slouken@6620
   252
    dialogTemplate.x = 0;
slouken@6620
   253
    dialogTemplate.y = 0;
slouken@6620
   254
    dialogTemplate.cx = w;
slouken@6620
   255
    dialogTemplate.cy = h;
slouken@7028
   256
    Vec2ToDLU(&dialogTemplate.cx, &dialogTemplate.cy);
slouken@6620
   257
slouken@6620
   258
    dialog = (WIN_DialogData *)SDL_calloc(1, sizeof(*dialog));
slouken@6620
   259
    if (!dialog) {
slouken@6620
   260
        return NULL;
slouken@6620
   261
    }
slouken@6620
   262
slouken@6620
   263
    if (!AddDialogData(dialog, &dialogTemplate, sizeof(dialogTemplate))) {
slouken@6620
   264
        FreeDialogData(dialog);
slouken@6620
   265
        return NULL;
slouken@6620
   266
    }
slouken@6620
   267
slouken@7191
   268
    /* No menu */
slouken@7028
   269
    WordToPass = 0;
slouken@7028
   270
    if (!AddDialogData(dialog, &WordToPass, 2)) {
slouken@6620
   271
        FreeDialogData(dialog);
slouken@6620
   272
        return NULL;
slouken@6620
   273
    }
slouken@6620
   274
slouken@7191
   275
    /* No custom class */
slouken@7028
   276
    if (!AddDialogData(dialog, &WordToPass, 2)) {
slouken@7028
   277
        FreeDialogData(dialog);
slouken@7028
   278
        return NULL;
slouken@7028
   279
    }
slouken@7028
   280
slouken@7191
   281
    /* title */
slouken@6620
   282
    if (!AddDialogString(dialog, caption)) {
slouken@6620
   283
        FreeDialogData(dialog);
slouken@6620
   284
        return NULL;
slouken@6620
   285
    }
slouken@6620
   286
slouken@7191
   287
    /* Font stuff */
slouken@7028
   288
    {
slouken@7191
   289
        /*
slouken@7191
   290
         * We want to use the system messagebox font.
slouken@7191
   291
         */
slouken@7028
   292
        BYTE ToPass;
slouken@7191
   293
slouken@7028
   294
        NONCLIENTMETRICSA NCM;
slouken@7028
   295
        NCM.cbSize = sizeof(NCM);
slouken@7028
   296
        SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
slouken@7191
   297
slouken@7191
   298
        /* Font size - convert to logical font size for dialog parameter. */
slouken@7028
   299
        {
slouken@9863
   300
            HDC ScreenDC = GetDC(NULL);
slouken@9863
   301
            int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY);
slouken@9863
   302
            if (!LogicalPixelsY) /* This can happen if the application runs out of GDI handles */
slouken@9863
   303
                LogicalPixelsY = 72;
slouken@9863
   304
            WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY);
slouken@9863
   305
            ReleaseDC(NULL, ScreenDC);
slouken@7028
   306
        }
slouken@7028
   307
slouken@7028
   308
        if (!AddDialogData(dialog, &WordToPass, 2)) {
slouken@7028
   309
            FreeDialogData(dialog);
slouken@7028
   310
            return NULL;
slouken@7028
   311
        }
slouken@7028
   312
slouken@7191
   313
        /* Font weight */
slouken@7028
   314
        WordToPass = (WORD)NCM.lfMessageFont.lfWeight;
slouken@7028
   315
        if (!AddDialogData(dialog, &WordToPass, 2)) {
slouken@7028
   316
            FreeDialogData(dialog);
slouken@7028
   317
            return NULL;
slouken@7028
   318
        }
slouken@7028
   319
slouken@7191
   320
        /* italic? */
slouken@7028
   321
        ToPass = NCM.lfMessageFont.lfItalic;
slouken@7028
   322
        if (!AddDialogData(dialog, &ToPass, 1)) {
slouken@7028
   323
            FreeDialogData(dialog);
slouken@7028
   324
            return NULL;
slouken@7028
   325
        }
slouken@7028
   326
slouken@7191
   327
        /* charset? */
slouken@7028
   328
        ToPass = NCM.lfMessageFont.lfCharSet;
slouken@7028
   329
        if (!AddDialogData(dialog, &ToPass, 1)) {
slouken@7028
   330
            FreeDialogData(dialog);
slouken@7028
   331
            return NULL;
slouken@7028
   332
        }
slouken@7028
   333
slouken@7191
   334
        /* font typeface. */
slouken@7028
   335
        if (!AddDialogString(dialog, NCM.lfMessageFont.lfFaceName)) {
slouken@7028
   336
            FreeDialogData(dialog);
slouken@7028
   337
            return NULL;
slouken@7028
   338
        }
slouken@7028
   339
    }
slouken@7028
   340
slouken@6620
   341
    return dialog;
slouken@6620
   342
}
slouken@6620
   343
slouken@6620
   344
int
slouken@6620
   345
WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
slouken@6620
   346
{
slouken@6620
   347
    WIN_DialogData *dialog;
slouken@7870
   348
    int i, x, y;
slouken@7870
   349
    UINT_PTR which;
slouken@6620
   350
    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
slouken@7028
   351
    HFONT DialogFont;
slouken@7028
   352
    SIZE Size;
slouken@7028
   353
    RECT TextSize;
slouken@7028
   354
    wchar_t* wmessage;
slouken@7028
   355
    TEXTMETRIC TM;
slouken@7028
   356
slouken@7028
   357
slouken@7028
   358
    const int ButtonWidth = 88;
slouken@7028
   359
    const int ButtonHeight = 26;
slouken@7028
   360
    const int TextMargin = 16;
slouken@7028
   361
    const int ButtonMargin = 12;
slouken@6620
   362
slouken@7028
   363
slouken@7191
   364
    /* Jan 25th, 2013 - dant@fleetsa.com
slouken@7191
   365
     *
slouken@7191
   366
     *
slouken@7191
   367
     * I've tried to make this more reasonable, but I've run in to a lot
slouken@7191
   368
     * of nonsense.
slouken@7191
   369
     *
slouken@7191
   370
     * The original issue is the code was written in pixels and not
slouken@7191
   371
     * dialog units (DLUs). All DialogBox functions use DLUs, which
slouken@7191
   372
     * vary based on the selected font (yay).
slouken@7191
   373
     *
slouken@7191
   374
     * According to MSDN, the most reliable way to convert is via
slouken@7191
   375
     * MapDialogUnits, which requires an HWND, which we don't have
slouken@7191
   376
     * at time of template creation.
slouken@7191
   377
     *
slouken@7191
   378
     * We do however have:
slouken@7191
   379
     *  The system font (DLU width 8 for me)
slouken@7191
   380
     *  The font we select for the dialog (DLU width 6 for me)
slouken@7191
   381
     *
slouken@7191
   382
     * Based on experimentation, *neither* of these return the value
slouken@7191
   383
     * actually used. Stepping in to MapDialogUnits(), the conversion
slouken@7191
   384
     * is fairly clear, and uses 7 for me.
slouken@7191
   385
     *
slouken@7191
   386
     * As a result, some of this is hacky to ensure the sizing is
slouken@7191
   387
     * somewhat correct.
slouken@7191
   388
     *
slouken@7191
   389
     * Honestly, a long term solution is to use CreateWindow, not CreateDialog.
slouken@7191
   390
     *
slouken@7191
   391
slouken@7191
   392
     *
slouken@7191
   393
     * In order to get text dimensions we need to have a DC with the desired font.
slouken@7191
   394
     * I'm assuming a dialog box in SDL is rare enough we can to the create.
slouken@7191
   395
     */
slouken@7028
   396
    HDC FontDC = CreateCompatibleDC(0);
slouken@7191
   397
slouken@7028
   398
    {
slouken@7191
   399
        /* Create a duplicate of the font used in system message boxes. */
slouken@7028
   400
        LOGFONT lf;
slouken@7028
   401
        NONCLIENTMETRICS NCM;
slouken@7028
   402
        NCM.cbSize = sizeof(NCM);
slouken@7028
   403
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
slouken@7028
   404
        lf = NCM.lfMessageFont;
slouken@7028
   405
        DialogFont = CreateFontIndirect(&lf);
slouken@7028
   406
    }
slouken@7028
   407
slouken@7191
   408
    /* Select the font in to our DC */
slouken@7028
   409
    SelectObject(FontDC, DialogFont);
slouken@7028
   410
slouken@7028
   411
    {
slouken@7191
   412
        /* Get the metrics to try and figure our DLU conversion. */
slouken@7028
   413
        GetTextMetrics(FontDC, &TM);
slouken@7028
   414
        s_BaseUnitsX = TM.tmAveCharWidth + 1;
slouken@7028
   415
        s_BaseUnitsY = TM.tmHeight;
slouken@7028
   416
    }
slouken@7191
   417
slouken@7191
   418
    /* Measure the *pixel* size of the string. */
slouken@7028
   419
    wmessage = WIN_UTF8ToString(messageboxdata->message);
slouken@7028
   420
    SDL_zero(TextSize);
slouken@7028
   421
    Size.cx = DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);
slouken@7028
   422
slouken@7191
   423
    /* Add some padding for hangs, etc. */
slouken@7028
   424
    TextSize.right += 2;
slouken@7028
   425
    TextSize.bottom += 2;
slouken@7028
   426
slouken@7191
   427
    /* Done with the DC, and the string */
slouken@7028
   428
    DeleteDC(FontDC);
slouken@7028
   429
    SDL_free(wmessage);
slouken@7028
   430
slouken@7191
   431
    /* Increase the size of the dialog by some border spacing around the text. */
slouken@7028
   432
    Size.cx = TextSize.right - TextSize.left;
slouken@7028
   433
    Size.cy = TextSize.bottom - TextSize.top;
slouken@7028
   434
    Size.cx += TextMargin * 2;
slouken@7028
   435
    Size.cy += TextMargin * 2;
slouken@7028
   436
slouken@7191
   437
    /* Ensure the size is wide enough for all of the buttons. */
slouken@7028
   438
    if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
slouken@7028
   439
        Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
slouken@7028
   440
slouken@7191
   441
    /* Add vertical space for the buttons and border. */
slouken@7028
   442
    Size.cy += ButtonHeight + TextMargin;
slouken@7028
   443
slouken@7028
   444
    dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
slouken@6620
   445
    if (!dialog) {
slouken@6620
   446
        return -1;
slouken@6620
   447
    }
slouken@6620
   448
slouken@7028
   449
    if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
slouken@6620
   450
        FreeDialogData(dialog);
slouken@6620
   451
        return -1;
slouken@6620
   452
    }
slouken@6620
   453
slouken@7191
   454
    /* Align the buttons to the right/bottom. */
slouken@10478
   455
    x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
slouken@7028
   456
    y = Size.cy - ButtonHeight - ButtonMargin;
slouken@10478
   457
    for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
slouken@6620
   458
        SDL_bool isDefault;
slouken@6620
   459
slouken@6620
   460
        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
slouken@6620
   461
            isDefault = SDL_TRUE;
slouken@6620
   462
        } else {
slouken@6620
   463
            isDefault = SDL_FALSE;
slouken@6620
   464
        }
slouken@7028
   465
        if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, i, isDefault)) {
slouken@6620
   466
            FreeDialogData(dialog);
slouken@6620
   467
            return -1;
slouken@6620
   468
        }
slouken@10478
   469
        x += ButtonWidth + ButtonMargin;
slouken@6620
   470
    }
slouken@6620
   471
slouken@6620
   472
    /* FIXME: If we have a parent window, get the Instance and HWND for them */
slouken@7028
   473
    which = DialogBoxIndirect(NULL, (DLGTEMPLATE*)dialog->lpDialog, NULL, (DLGPROC)MessageBoxDialogProc);
slouken@6620
   474
    *buttonid = buttons[which].buttonid;
slouken@6620
   475
slouken@6620
   476
    FreeDialogData(dialog);
slouken@6620
   477
    return 0;
slouken@6620
   478
}
slouken@6620
   479
slouken@6620
   480
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6620
   481
slouken@6620
   482
/* vi: set ts=4 sw=4 expandtab: */