src/video/windows/SDL_windowsmessagebox.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 28 Feb 2018 01:54:22 -0500
changeset 11909 b2e68bf41993
parent 11811 5d94cb6b24d3
child 11910 9947d9f539e8
permissions -rw-r--r--
windows: Message boxes use Task Dialogs if possible (thanks, Jack!).

This lets the message box have an icon. Unless the app has opted-in to using
the v6 common controls, though, this will fall back to the usual SDL message
boxes.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_DRIVER_WINDOWS
    24 
    25 #include "../../core/windows/SDL_windows.h"
    26 
    27 #include "SDL_assert.h"
    28 #include "SDL_windowsvideo.h"
    29 #include "SDL_windowstaskdialog.h"
    30 
    31 #ifndef SS_EDITCONTROL
    32 #define SS_EDITCONTROL  0x2000
    33 #endif
    34 
    35 /* Display a Windows message box */
    36 
    37 #pragma pack(push, 1)
    38 
    39 typedef struct
    40 {
    41     WORD dlgVer;
    42     WORD signature;
    43     DWORD helpID;
    44     DWORD exStyle;
    45     DWORD style;
    46     WORD cDlgItems;
    47     short x;
    48     short y;
    49     short cx;
    50     short cy;
    51 } DLGTEMPLATEEX;
    52 
    53 typedef struct
    54 {
    55     DWORD helpID;
    56     DWORD exStyle;
    57     DWORD style;
    58     short x;
    59     short y;
    60     short cx;
    61     short cy;
    62     DWORD id;
    63 } DLGITEMTEMPLATEEX;
    64 
    65 #pragma pack(pop)
    66 
    67 typedef struct
    68 {
    69     DLGTEMPLATEEX* lpDialog;
    70     Uint8 *data;
    71     size_t size;
    72     size_t used;
    73 } WIN_DialogData;
    74 
    75 
    76 static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
    77 {
    78     switch ( iMessage ) {
    79     case WM_COMMAND:
    80         /* Return the ID of the button that was pushed */
    81         EndDialog(hDlg, LOWORD(wParam));
    82         return TRUE;
    83 
    84     default:
    85         break;
    86     }
    87     return FALSE;
    88 }
    89 
    90 static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
    91 {
    92     size_t size = dialog->size;
    93 
    94     if (size == 0) {
    95         size = space;
    96     } else {
    97         while ((dialog->used + space) > size) {
    98             size *= 2;
    99         }
   100     }
   101     if (size > dialog->size) {
   102         void *data = SDL_realloc(dialog->data, size);
   103         if (!data) {
   104             SDL_OutOfMemory();
   105             return SDL_FALSE;
   106         }
   107         dialog->data = data;
   108         dialog->size = size;
   109         dialog->lpDialog = (DLGTEMPLATEEX*)dialog->data;
   110     }
   111     return SDL_TRUE;
   112 }
   113 
   114 static SDL_bool AlignDialogData(WIN_DialogData *dialog, size_t size)
   115 {
   116     size_t padding = (dialog->used % size);
   117 
   118     if (!ExpandDialogSpace(dialog, padding)) {
   119         return SDL_FALSE;
   120     }
   121 
   122     dialog->used += padding;
   123 
   124     return SDL_TRUE;
   125 }
   126 
   127 static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
   128 {
   129     if (!ExpandDialogSpace(dialog, size)) {
   130         return SDL_FALSE;
   131     }
   132 
   133     SDL_memcpy(dialog->data+dialog->used, data, size);
   134     dialog->used += size;
   135 
   136     return SDL_TRUE;
   137 }
   138 
   139 static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
   140 {
   141     WCHAR *wstring;
   142     WCHAR *p;
   143     size_t count;
   144     SDL_bool status;
   145 
   146     if (!string) {
   147         string = "";
   148     }
   149 
   150     wstring = WIN_UTF8ToString(string);
   151     if (!wstring) {
   152         return SDL_FALSE;
   153     }
   154 
   155     /* Find out how many characters we have, including null terminator */
   156     count = 0;
   157     for (p = wstring; *p; ++p) {
   158         ++count;
   159     }
   160     ++count;
   161 
   162     status = AddDialogData(dialog, wstring, count*sizeof(WCHAR));
   163     SDL_free(wstring);
   164     return status;
   165 }
   166 
   167 static int s_BaseUnitsX;
   168 static int s_BaseUnitsY;
   169 static void Vec2ToDLU(short *x, short *y)
   170 {
   171     SDL_assert(s_BaseUnitsX != 0); /* we init in WIN_ShowMessageBox(), which is the only public function... */
   172 
   173     *x = MulDiv(*x, 4, s_BaseUnitsX);
   174     *y = MulDiv(*y, 8, s_BaseUnitsY);
   175 }
   176 
   177 
   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)
   179 {
   180     DLGITEMTEMPLATEEX item;
   181     WORD marker = 0xFFFF;
   182     WORD extraData = 0;
   183 
   184     SDL_zero(item);
   185     item.style = style;
   186     item.exStyle = exStyle;
   187     item.x = x;
   188     item.y = y;
   189     item.cx = w;
   190     item.cy = h;
   191     item.id = id;
   192 
   193     Vec2ToDLU(&item.x, &item.y);
   194     Vec2ToDLU(&item.cx, &item.cy);
   195 
   196     if (!AlignDialogData(dialog, sizeof(DWORD))) {
   197         return SDL_FALSE;
   198     }
   199     if (!AddDialogData(dialog, &item, sizeof(item))) {
   200         return SDL_FALSE;
   201     }
   202     if (!AddDialogData(dialog, &marker, sizeof(marker))) {
   203         return SDL_FALSE;
   204     }
   205     if (!AddDialogData(dialog, &type, sizeof(type))) {
   206         return SDL_FALSE;
   207     }
   208     if (!AddDialogString(dialog, caption)) {
   209         return SDL_FALSE;
   210     }
   211     if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
   212         return SDL_FALSE;
   213     }
   214     ++dialog->lpDialog->cDlgItems;
   215 
   216     return SDL_TRUE;
   217 }
   218 
   219 static SDL_bool AddDialogStatic(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
   220 {
   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);
   223 }
   224 
   225 static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, SDL_bool isDefault)
   226 {
   227     DWORD style = WS_VISIBLE | WS_CHILD;
   228     if (isDefault) {
   229         style |= BS_DEFPUSHBUTTON;
   230     } else {
   231         style |= BS_PUSHBUTTON;
   232     }
   233     return AddDialogControl(dialog, 0x0080, style, 0, x, y, w, h, id, text);
   234 }
   235 
   236 static void FreeDialogData(WIN_DialogData *dialog)
   237 {
   238     SDL_free(dialog->data);
   239     SDL_free(dialog);
   240 }
   241 
   242 static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
   243 {
   244     WIN_DialogData *dialog;
   245     DLGTEMPLATEEX dialogTemplate;
   246     WORD WordToPass;
   247 
   248     SDL_zero(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);
   257 
   258     dialog = (WIN_DialogData *)SDL_calloc(1, sizeof(*dialog));
   259     if (!dialog) {
   260         return NULL;
   261     }
   262 
   263     if (!AddDialogData(dialog, &dialogTemplate, sizeof(dialogTemplate))) {
   264         FreeDialogData(dialog);
   265         return NULL;
   266     }
   267 
   268     /* No menu */
   269     WordToPass = 0;
   270     if (!AddDialogData(dialog, &WordToPass, 2)) {
   271         FreeDialogData(dialog);
   272         return NULL;
   273     }
   274 
   275     /* No custom class */
   276     if (!AddDialogData(dialog, &WordToPass, 2)) {
   277         FreeDialogData(dialog);
   278         return NULL;
   279     }
   280 
   281     /* title */
   282     if (!AddDialogString(dialog, caption)) {
   283         FreeDialogData(dialog);
   284         return NULL;
   285     }
   286 
   287     /* Font stuff */
   288     {
   289         /*
   290          * We want to use the system messagebox font.
   291          */
   292         BYTE ToPass;
   293 
   294         NONCLIENTMETRICSA NCM;
   295         NCM.cbSize = sizeof(NCM);
   296         SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
   297 
   298         /* Font size - convert to logical font size for dialog parameter. */
   299         {
   300             HDC ScreenDC = GetDC(NULL);
   301             int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY);
   302             if (!LogicalPixelsY) /* This can happen if the application runs out of GDI handles */
   303                 LogicalPixelsY = 72;
   304             WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY);
   305             ReleaseDC(NULL, ScreenDC);
   306         }
   307 
   308         if (!AddDialogData(dialog, &WordToPass, 2)) {
   309             FreeDialogData(dialog);
   310             return NULL;
   311         }
   312 
   313         /* Font weight */
   314         WordToPass = (WORD)NCM.lfMessageFont.lfWeight;
   315         if (!AddDialogData(dialog, &WordToPass, 2)) {
   316             FreeDialogData(dialog);
   317             return NULL;
   318         }
   319 
   320         /* italic? */
   321         ToPass = NCM.lfMessageFont.lfItalic;
   322         if (!AddDialogData(dialog, &ToPass, 1)) {
   323             FreeDialogData(dialog);
   324             return NULL;
   325         }
   326 
   327         /* charset? */
   328         ToPass = NCM.lfMessageFont.lfCharSet;
   329         if (!AddDialogData(dialog, &ToPass, 1)) {
   330             FreeDialogData(dialog);
   331             return NULL;
   332         }
   333 
   334         /* font typeface. */
   335         if (!AddDialogString(dialog, NCM.lfMessageFont.lfFaceName)) {
   336             FreeDialogData(dialog);
   337             return NULL;
   338         }
   339     }
   340 
   341     return dialog;
   342 }
   343 
   344 /* This function is called if a Task Dialog is unsupported. */
   345 static int
   346 WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
   347 {
   348     WIN_DialogData *dialog;
   349     int i, x, y;
   350     const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
   351     HFONT DialogFont;
   352     SIZE Size;
   353     RECT TextSize;
   354     wchar_t* wmessage;
   355     TEXTMETRIC TM;
   356 
   357     HWND ParentWindow = NULL;
   358 
   359     const int ButtonWidth = 88;
   360     const int ButtonHeight = 26;
   361     const int TextMargin = 16;
   362     const int ButtonMargin = 12;
   363 
   364 
   365     /* Jan 25th, 2013 - dant@fleetsa.com
   366      *
   367      *
   368      * I've tried to make this more reasonable, but I've run in to a lot
   369      * of nonsense.
   370      *
   371      * The original issue is the code was written in pixels and not
   372      * dialog units (DLUs). All DialogBox functions use DLUs, which
   373      * vary based on the selected font (yay).
   374      *
   375      * According to MSDN, the most reliable way to convert is via
   376      * MapDialogUnits, which requires an HWND, which we don't have
   377      * at time of template creation.
   378      *
   379      * We do however have:
   380      *  The system font (DLU width 8 for me)
   381      *  The font we select for the dialog (DLU width 6 for me)
   382      *
   383      * Based on experimentation, *neither* of these return the value
   384      * actually used. Stepping in to MapDialogUnits(), the conversion
   385      * is fairly clear, and uses 7 for me.
   386      *
   387      * As a result, some of this is hacky to ensure the sizing is
   388      * somewhat correct.
   389      *
   390      * Honestly, a long term solution is to use CreateWindow, not CreateDialog.
   391      *
   392 
   393      *
   394      * In order to get text dimensions we need to have a DC with the desired font.
   395      * I'm assuming a dialog box in SDL is rare enough we can to the create.
   396      */
   397     HDC FontDC = CreateCompatibleDC(0);
   398 
   399     {
   400         /* Create a duplicate of the font used in system message boxes. */
   401         LOGFONT lf;
   402         NONCLIENTMETRICS NCM;
   403         NCM.cbSize = sizeof(NCM);
   404         SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
   405         lf = NCM.lfMessageFont;
   406         DialogFont = CreateFontIndirect(&lf);
   407     }
   408 
   409     /* Select the font in to our DC */
   410     SelectObject(FontDC, DialogFont);
   411 
   412     {
   413         /* Get the metrics to try and figure our DLU conversion. */
   414         GetTextMetrics(FontDC, &TM);
   415 
   416         /* Calculation from the following documentation:
   417          * https://support.microsoft.com/en-gb/help/125681/how-to-calculate-dialog-base-units-with-non-system-based-font
   418          * This fixes bug 2137, dialog box calculation with a fixed-width system font
   419          */
   420         {
   421             SIZE extent;
   422             GetTextExtentPoint32A(FontDC, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &extent);
   423             s_BaseUnitsX = (extent.cx / 26 + 1) / 2;
   424         }
   425         /*s_BaseUnitsX = TM.tmAveCharWidth + 1;*/
   426         s_BaseUnitsY = TM.tmHeight;
   427     }
   428 
   429     /* Measure the *pixel* size of the string. */
   430     wmessage = WIN_UTF8ToString(messageboxdata->message);
   431     SDL_zero(TextSize);
   432     DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);
   433 
   434     /* Add some padding for hangs, etc. */
   435     TextSize.right += 2;
   436     TextSize.bottom += 2;
   437 
   438     /* Done with the DC, and the string */
   439     DeleteDC(FontDC);
   440     SDL_free(wmessage);
   441 
   442     /* Increase the size of the dialog by some border spacing around the text. */
   443     Size.cx = TextSize.right - TextSize.left;
   444     Size.cy = TextSize.bottom - TextSize.top;
   445     Size.cx += TextMargin * 2;
   446     Size.cy += TextMargin * 2;
   447 
   448     /* Ensure the size is wide enough for all of the buttons. */
   449     if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
   450         Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;
   451 
   452     /* Add vertical space for the buttons and border. */
   453     Size.cy += ButtonHeight + TextMargin;
   454 
   455     dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
   456     if (!dialog) {
   457         return -1;
   458     }
   459 
   460     if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
   461         FreeDialogData(dialog);
   462         return -1;
   463     }
   464 
   465     /* Align the buttons to the right/bottom. */
   466     x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
   467     y = Size.cy - ButtonHeight - ButtonMargin;
   468     for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
   469         SDL_bool isDefault;
   470 
   471         if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
   472             isDefault = SDL_TRUE;
   473         } else {
   474             isDefault = SDL_FALSE;
   475         }
   476         if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, buttons[i].buttonid, isDefault)) {
   477             FreeDialogData(dialog);
   478             return -1;
   479         }
   480         x += ButtonWidth + ButtonMargin;
   481     }
   482 
   483     /* If we have a parent window, get the Instance and HWND for them
   484      * so that our little dialog gets exclusive focus at all times. */
   485     if (messageboxdata->window) {
   486         ParentWindow = ((SDL_WindowData*)messageboxdata->window->driverdata)->hwnd;
   487     }
   488 
   489     *buttonid = (int)DialogBoxIndirect(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc);
   490 
   491     FreeDialogData(dialog);
   492     return 0;
   493 }
   494 
   495 /* TaskDialogIndirect procedure
   496  * This is because SDL targets Windows XP (0x501), so this is not defined in the platform SDK.
   497  */
   498 typedef HRESULT(FAR WINAPI *TASKDIALOGINDIRECTPROC)(_In_ const TASKDIALOGCONFIG *pTaskConfig, _Out_opt_ int *pnButton, _Out_opt_ int *pnRadioButton, _Out_opt_ BOOL *pfVerificationFlagChecked);
   499 
   500 int
   501 WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
   502 {
   503     HWND ParentWindow = NULL;
   504     wchar_t *wmessage;
   505     wchar_t *wtitle;
   506     TASKDIALOGCONFIG TaskConfig;
   507     TASKDIALOG_BUTTON *pButtons;
   508     TASKDIALOG_BUTTON *pButton;
   509     HMODULE hComctl32;
   510     TASKDIALOGINDIRECTPROC pfnTaskDialogIndirect;
   511     HRESULT hr;
   512     int nButton;
   513     int nCancelButton;
   514     int i;
   515 
   516     /* If we cannot load comctl32.dll use the old messagebox! */
   517     hComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
   518     if (hComctl32 == NULL) {
   519         return WIN_ShowOldMessageBox(messageboxdata,buttonid);
   520     }
   521     
   522     /* If TaskDialogIndirect doesn't exist use the old messagebox!
   523        This will fail prior to Windows Vista.
   524        The manifest file in the application may require targeting version 6 of comctl32.dll, even
   525        when we use LoadLibrary here!
   526        If you don't want to bother with manifests, put this #pragma in your app's source code somewhere:
   527        pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0'  processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
   528      */
   529     pfnTaskDialogIndirect = (TASKDIALOGINDIRECTPROC) GetProcAddress(hComctl32, "TaskDialogIndirect");
   530     if (pfnTaskDialogIndirect == NULL) {
   531         FreeLibrary(hComctl32);
   532         return WIN_ShowOldMessageBox(messageboxdata, buttonid);
   533     }
   534 
   535     /* If we have a parent window, get the Instance and HWND for them
   536        so that our little dialog gets exclusive focus at all times. */
   537     if (messageboxdata->window) {
   538         ParentWindow = ((SDL_WindowData *) messageboxdata->window->driverdata)->hwnd;
   539     }
   540 
   541     wmessage = WIN_UTF8ToString(messageboxdata->message);
   542     wtitle = WIN_UTF8ToString(messageboxdata->title);
   543 
   544     SDL_zero(TaskConfig);
   545     TaskConfig.cbSize = sizeof (TASKDIALOGCONFIG);
   546     TaskConfig.hwndParent = ParentWindow;
   547     TaskConfig.dwFlags = TDF_SIZE_TO_CONTENT;
   548     TaskConfig.pszWindowTitle = wtitle;
   549     if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
   550         TaskConfig.pszMainIcon = TD_ERROR_ICON;
   551     } else if (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) {
   552         TaskConfig.pszMainIcon = TD_WARNING_ICON;
   553     } else if (messageboxdata->flags & SDL_MESSAGEBOX_INFORMATION) {
   554         TaskConfig.pszMainIcon = TD_INFORMATION_ICON;
   555     } else {
   556         TaskConfig.pszMainIcon = NULL;
   557     }
   558 
   559     TaskConfig.pszContent = wmessage;
   560     TaskConfig.cButtons = messageboxdata->numbuttons;
   561     pButtons = SDL_malloc(sizeof (TASKDIALOG_BUTTON) * messageboxdata->numbuttons);
   562     TaskConfig.nDefaultButton = 0;
   563     for (i = 0; i < messageboxdata->numbuttons; i++)
   564     {
   565         pButton = &pButtons[messageboxdata->numbuttons-1-i];
   566         if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
   567             nCancelButton = messageboxdata->buttons[i].buttonid;
   568             pButton->nButtonID = 2;
   569         } else {
   570             pButton->nButtonID = messageboxdata->buttons[i].buttonid + 1;
   571             if (pButton->nButtonID >= 2) {
   572                 pButton->nButtonID++;
   573             }
   574         }
   575         pButton->pszButtonText = WIN_UTF8ToString(messageboxdata->buttons[i].text);
   576         if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
   577             TaskConfig.nDefaultButton = pButton->nButtonID;
   578         }
   579     }
   580     TaskConfig.pButtons = pButtons;
   581 
   582     /* Show the Task Dialog */
   583     hr = pfnTaskDialogIndirect(&TaskConfig, &nButton, NULL, NULL);
   584 
   585     /* Free everything */
   586     FreeLibrary(hComctl32);
   587     SDL_free(wmessage);
   588     SDL_free(wtitle);
   589     for (i = 0; i < messageboxdata->numbuttons; i++) {
   590         SDL_free((wchar_t *) pButtons[i].pszButtonText);
   591     }
   592     SDL_free(pButtons);
   593 
   594     /* Check the Task Dialog was successful and give the result */
   595     if (SUCCEEDED(hr)) {
   596         if (nButton == 2) {
   597             *buttonid = nCancelButton;
   598         } else if (nButton > 2) {
   599             *buttonid = nButton-1-1;
   600         } else {
   601             *buttonid = nButton-1;
   602         }
   603         return 0;
   604     }
   605 
   606     /* We failed showing the Task Dialog, use the old message box! */
   607     return WIN_ShowOldMessageBox(messageboxdata, buttonid);
   608 }
   609 
   610 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
   611 
   612 /* vi: set ts=4 sw=4 expandtab: */