Added Windows message box implementation, but it needs a little work on layout.
authorSam Lantinga <slouken@libsdl.org>
Tue, 30 Oct 2012 18:59:56 -0700
changeset 662062fe18dc6841
parent 6619 42214b6959c5
child 6621 25504f9ab078
Added Windows message box implementation, but it needs a little work on layout.
VisualC/SDL/SDL_VS2008.vcproj
src/video/SDL_video.c
src/video/windows/SDL_windowsmessagebox.c
src/video/windows/SDL_windowsmessagebox.h
     1.1 --- a/VisualC/SDL/SDL_VS2008.vcproj	Tue Oct 30 13:44:59 2012 -0700
     1.2 +++ b/VisualC/SDL/SDL_VS2008.vcproj	Tue Oct 30 18:59:56 2012 -0700
     1.3 @@ -1217,6 +1217,14 @@
     1.4  			>
     1.5  		</File>
     1.6  		<File
     1.7 +			RelativePath="..\..\src\video\windows\SDL_windowsmessagebox.c"
     1.8 +			>
     1.9 +		</File>
    1.10 +		<File
    1.11 +			RelativePath="..\..\src\video\windows\SDL_windowsmessagebox.h"
    1.12 +			>
    1.13 +		</File>
    1.14 +		<File
    1.15  			RelativePath="..\..\src\video\windows\SDL_windowsmodes.c"
    1.16  			>
    1.17  		</File>
     2.1 --- a/src/video/SDL_video.c	Tue Oct 30 13:44:59 2012 -0700
     2.2 +++ b/src/video/SDL_video.c	Tue Oct 30 18:59:56 2012 -0700
     2.3 @@ -2841,6 +2841,9 @@
     2.4      return SDL_FALSE;
     2.5  }
     2.6  
     2.7 +#if SDL_VIDEO_DRIVER_WINDOWS
     2.8 +#include "windows/SDL_windowsmessagebox.h"
     2.9 +#endif
    2.10  #if SDL_VIDEO_DRIVER_COCOA
    2.11  #include "cocoa/SDL_cocoamessagebox.h"
    2.12  #endif
    2.13 @@ -2866,6 +2869,11 @@
    2.14      }
    2.15  
    2.16      /* It's completely fine to call this function before video is initialized */
    2.17 +#if SDL_VIDEO_DRIVER_WINDOWS
    2.18 +    if (WIN_ShowMessageBox(messageboxdata, buttonid) == 0) {
    2.19 +        return 0;
    2.20 +    }
    2.21 +#endif
    2.22  #if SDL_VIDEO_DRIVER_COCOA
    2.23      if (Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) {
    2.24          return 0;
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/video/windows/SDL_windowsmessagebox.c	Tue Oct 30 18:59:56 2012 -0700
     3.3 @@ -0,0 +1,282 @@
     3.4 +/*
     3.5 +  Simple DirectMedia Layer
     3.6 +  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     3.7 +
     3.8 +  This software is provided 'as-is', without any express or implied
     3.9 +  warranty.  In no event will the authors be held liable for any damages
    3.10 +  arising from the use of this software.
    3.11 +
    3.12 +  Permission is granted to anyone to use this software for any purpose,
    3.13 +  including commercial applications, and to alter it and redistribute it
    3.14 +  freely, subject to the following restrictions:
    3.15 +
    3.16 +  1. The origin of this software must not be misrepresented; you must not
    3.17 +     claim that you wrote the original software. If you use this software
    3.18 +     in a product, an acknowledgment in the product documentation would be
    3.19 +     appreciated but is not required.
    3.20 +  2. Altered source versions must be plainly marked as such, and must not be
    3.21 +     misrepresented as being the original software.
    3.22 +  3. This notice may not be removed or altered from any source distribution.
    3.23 +*/
    3.24 +#include "SDL_config.h"
    3.25 +
    3.26 +#if SDL_VIDEO_DRIVER_WINDOWS
    3.27 +
    3.28 +#include "SDL.h"
    3.29 +#include "SDL_windowsvideo.h"
    3.30 +
    3.31 +
    3.32 +/* Display a Windows message box */
    3.33 +
    3.34 +typedef struct
    3.35 +{
    3.36 +    LPDLGTEMPLATE lpDialog;
    3.37 +    Uint8 *data;
    3.38 +    size_t size;
    3.39 +    size_t used;
    3.40 +} WIN_DialogData;
    3.41 +
    3.42 +
    3.43 +static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
    3.44 +{
    3.45 +    switch ( iMessage ) {
    3.46 +    case WM_COMMAND:
    3.47 +        /* Return the ID of the button that was pushed */
    3.48 +		EndDialog(hDlg, LOWORD(wParam));
    3.49 +        return TRUE;
    3.50 +
    3.51 +    default:
    3.52 +        break;
    3.53 +    }
    3.54 +    return FALSE;
    3.55 +}
    3.56 +
    3.57 +static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space)
    3.58 +{
    3.59 +    size_t size = dialog->size;
    3.60 +
    3.61 +    if (size == 0) {
    3.62 +        size = space;
    3.63 +    } else {
    3.64 +        while ((dialog->used + space) > size) {
    3.65 +            size *= 2;
    3.66 +        }
    3.67 +    }
    3.68 +    if (size > dialog->size) {
    3.69 +        void *data = SDL_realloc(dialog->data, size);
    3.70 +        if (!data) {
    3.71 +            SDL_OutOfMemory();
    3.72 +            return SDL_FALSE;
    3.73 +        }
    3.74 +        dialog->data = data;
    3.75 +        dialog->size = size;
    3.76 +        dialog->lpDialog = (LPDLGTEMPLATE)dialog->data;
    3.77 +    }
    3.78 +    return SDL_TRUE;
    3.79 +}
    3.80 + 
    3.81 +static SDL_bool AlignDialogData(WIN_DialogData *dialog, size_t size)
    3.82 +{
    3.83 +    size_t padding = (dialog->used % size);
    3.84 +
    3.85 +    if (!ExpandDialogSpace(dialog, padding)) {
    3.86 +        return SDL_FALSE;
    3.87 +    }
    3.88 +
    3.89 +    dialog->used += padding;
    3.90 +
    3.91 +    return SDL_TRUE;
    3.92 +}
    3.93 +
    3.94 +static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t size)
    3.95 +{
    3.96 +    if (!ExpandDialogSpace(dialog, size)) {
    3.97 +        return SDL_FALSE;
    3.98 +    }
    3.99 +
   3.100 +    SDL_memcpy(dialog->data+dialog->used, data, size);
   3.101 +    dialog->used += size;
   3.102 +
   3.103 +    return SDL_TRUE;
   3.104 +}
   3.105 +
   3.106 +static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string)
   3.107 +{
   3.108 +    WCHAR *wstring;
   3.109 +    WCHAR *p;
   3.110 +    size_t count;
   3.111 +    SDL_bool status;
   3.112 +
   3.113 +    if (!string) {
   3.114 +        string = "";
   3.115 +    }
   3.116 +
   3.117 +    wstring = WIN_UTF8ToString(string);
   3.118 +    if (!wstring) {
   3.119 +        return SDL_FALSE;
   3.120 +    }
   3.121 +
   3.122 +    /* Find out how many characters we have, including null terminator */
   3.123 +    count = 0;
   3.124 +    for (p = wstring; *p; ++p) {
   3.125 +        ++count;
   3.126 +    }
   3.127 +    ++count;
   3.128 +
   3.129 +    status = AddDialogData(dialog, wstring, count*sizeof(WCHAR));
   3.130 +    SDL_free(wstring);
   3.131 +    return status;
   3.132 +}
   3.133 +
   3.134 +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)
   3.135 +{
   3.136 +    DLGITEMTEMPLATE item;
   3.137 +    WORD marker = 0xFFFF;
   3.138 +    WORD extraData = 0;
   3.139 +
   3.140 +    SDL_zero(item);
   3.141 +    item.style = style;
   3.142 +    item.dwExtendedStyle = exStyle;
   3.143 +    item.x = x;
   3.144 +    item.y = y;
   3.145 +    item.cx = w;
   3.146 +    item.cy = h;
   3.147 +    item.id = id;
   3.148 +
   3.149 +    if (!AlignDialogData(dialog, sizeof(DWORD))) {
   3.150 +        return SDL_FALSE;
   3.151 +    }
   3.152 +    if (!AddDialogData(dialog, &item, sizeof(item))) {
   3.153 +        return SDL_FALSE;
   3.154 +    }
   3.155 +    if (!AddDialogData(dialog, &marker, sizeof(marker))) {
   3.156 +        return SDL_FALSE;
   3.157 +    }
   3.158 +    if (!AddDialogData(dialog, &type, sizeof(type))) {
   3.159 +        return SDL_FALSE;
   3.160 +    }
   3.161 +    if (!AddDialogString(dialog, caption)) {
   3.162 +        return SDL_FALSE;
   3.163 +    }
   3.164 +    if (!AddDialogData(dialog, &extraData, sizeof(extraData))) {
   3.165 +        return SDL_FALSE;
   3.166 +    }
   3.167 +    ++dialog->lpDialog->cdit;
   3.168 +
   3.169 +    return SDL_TRUE;
   3.170 +}
   3.171 +
   3.172 +static SDL_bool AddDialogStatic(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text)
   3.173 +{
   3.174 +    DWORD style = WS_VISIBLE | WS_CHILD | SS_LEFT | SS_NOPREFIX;
   3.175 +    return AddDialogControl(dialog, 0x0082, style, 0, x, y, w, h, -1, text);
   3.176 +}
   3.177 +
   3.178 +static SDL_bool AddDialogButton(WIN_DialogData *dialog, int x, int y, int w, int h, const char *text, int id, SDL_bool isDefault)
   3.179 +{
   3.180 +    DWORD style = WS_VISIBLE | WS_CHILD;
   3.181 +    if (isDefault) {
   3.182 +        style |= BS_DEFPUSHBUTTON;
   3.183 +    } else {
   3.184 +        style |= BS_PUSHBUTTON;
   3.185 +    }
   3.186 +    return AddDialogControl(dialog, 0x0080, style, 0, x, y, w, h, id, text);
   3.187 +}
   3.188 +
   3.189 +static void FreeDialogData(WIN_DialogData *dialog)
   3.190 +{
   3.191 +    if (dialog->data) {
   3.192 +        SDL_free(dialog->data);
   3.193 +    }
   3.194 +    SDL_free(dialog);
   3.195 +}
   3.196 +
   3.197 +static WIN_DialogData *CreateDialogData(int w, int h, const char *caption)
   3.198 +{
   3.199 +    WIN_DialogData *dialog;
   3.200 +    DLGTEMPLATE dialogTemplate;
   3.201 +
   3.202 +    SDL_zero(dialogTemplate);
   3.203 +    dialogTemplate.style = (WS_CAPTION | DS_CENTER);
   3.204 +    dialogTemplate.x = 0;
   3.205 +    dialogTemplate.y = 0;
   3.206 +    dialogTemplate.cx = w;
   3.207 +    dialogTemplate.cy = h;
   3.208 +
   3.209 +    dialog = (WIN_DialogData *)SDL_calloc(1, sizeof(*dialog));
   3.210 +    if (!dialog) {
   3.211 +        return NULL;
   3.212 +    }
   3.213 +
   3.214 +    if (!AddDialogData(dialog, &dialogTemplate, sizeof(dialogTemplate))) {
   3.215 +        FreeDialogData(dialog);
   3.216 +        return NULL;
   3.217 +    }
   3.218 +
   3.219 +    /* There is no menu or special class */
   3.220 +    if (!AddDialogString(dialog, "") || !AddDialogString(dialog, "")) {
   3.221 +        FreeDialogData(dialog);
   3.222 +        return NULL;
   3.223 +    }
   3.224 +
   3.225 +    if (!AddDialogString(dialog, caption)) {
   3.226 +        FreeDialogData(dialog);
   3.227 +        return NULL;
   3.228 +    }
   3.229 +
   3.230 +    return dialog;
   3.231 +}
   3.232 +
   3.233 +int
   3.234 +WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
   3.235 +{
   3.236 +    WIN_DialogData *dialog;
   3.237 +    int i, x, y, w, h, gap, which;
   3.238 +    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
   3.239 + 
   3.240 +    /* FIXME: Need a better algorithm for laying out the message box */
   3.241 +
   3.242 +    dialog = CreateDialogData(570, 260, messageboxdata->title);
   3.243 +    if (!dialog) {
   3.244 +        return -1;
   3.245 +    }
   3.246 +
   3.247 +    w = 100;
   3.248 +    h = 25;
   3.249 +    gap = 10;
   3.250 +    x = gap;
   3.251 +    y = 50;
   3.252 +
   3.253 +    if (!AddDialogStatic(dialog, x, y, 550, 100, messageboxdata->message)) {
   3.254 +        FreeDialogData(dialog);
   3.255 +        return -1;
   3.256 +    }
   3.257 +
   3.258 +    y += 110;
   3.259 +
   3.260 +    for (i = 0; i < messageboxdata->numbuttons; ++i) {
   3.261 +        SDL_bool isDefault;
   3.262 +
   3.263 +        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
   3.264 +            isDefault = SDL_TRUE;
   3.265 +        } else {
   3.266 +            isDefault = SDL_FALSE;
   3.267 +        }
   3.268 +        if (!AddDialogButton(dialog, x, y, w, h, buttons[i].text, i, isDefault)) {
   3.269 +            FreeDialogData(dialog);
   3.270 +            return -1;
   3.271 +        }
   3.272 +        x += w + gap;
   3.273 +    }
   3.274 +
   3.275 +    /* FIXME: If we have a parent window, get the Instance and HWND for them */
   3.276 +    which = DialogBoxIndirect(NULL, dialog->lpDialog, NULL, (DLGPROC)MessageBoxDialogProc);
   3.277 +    *buttonid = buttons[which].buttonid;
   3.278 +
   3.279 +    FreeDialogData(dialog);
   3.280 +    return 0;
   3.281 +}
   3.282 +
   3.283 +#endif /* SDL_VIDEO_DRIVER_WINDOWS */
   3.284 +
   3.285 +/* vi: set ts=4 sw=4 expandtab: */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/video/windows/SDL_windowsmessagebox.h	Tue Oct 30 18:59:56 2012 -0700
     4.3 @@ -0,0 +1,29 @@
     4.4 +/*
     4.5 +  Simple DirectMedia Layer
     4.6 +  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4.7 +
     4.8 +  This software is provided 'as-is', without any express or implied
     4.9 +  warranty.  In no event will the authors be held liable for any damages
    4.10 +  arising from the use of this software.
    4.11 +
    4.12 +  Permission is granted to anyone to use this software for any purpose,
    4.13 +  including commercial applications, and to alter it and redistribute it
    4.14 +  freely, subject to the following restrictions:
    4.15 +
    4.16 +  1. The origin of this software must not be misrepresented; you must not
    4.17 +     claim that you wrote the original software. If you use this software
    4.18 +     in a product, an acknowledgment in the product documentation would be
    4.19 +     appreciated but is not required.
    4.20 +  2. Altered source versions must be plainly marked as such, and must not be
    4.21 +     misrepresented as being the original software.
    4.22 +  3. This notice may not be removed or altered from any source distribution.
    4.23 +*/
    4.24 +#include "SDL_config.h"
    4.25 +
    4.26 +#if SDL_VIDEO_DRIVER_WINDOWS
    4.27 +
    4.28 +extern int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
    4.29 +
    4.30 +#endif /* SDL_VIDEO_DRIVER_WINDOWS */
    4.31 +
    4.32 +/* vi: set ts=4 sw=4 expandtab: */