src/video/windows/SDL_windowsmessagebox.c
changeset 11911 235c5929651c
parent 11910 9947d9f539e8
child 11917 5ce3f8bf8381
equal deleted inserted replaced
11910:9947d9f539e8 11911:235c5929651c
    24 
    24 
    25 #include "../../core/windows/SDL_windows.h"
    25 #include "../../core/windows/SDL_windows.h"
    26 
    26 
    27 #include "SDL_assert.h"
    27 #include "SDL_assert.h"
    28 #include "SDL_windowsvideo.h"
    28 #include "SDL_windowsvideo.h"
    29 #include "SDL_windowstaskdialog.h"
    29 
    30 
    30 
    31 #ifndef SS_EDITCONTROL
    31 #ifndef SS_EDITCONTROL
    32 #define SS_EDITCONTROL  0x2000
    32 #define SS_EDITCONTROL  0x2000
    33 #endif
    33 #endif
    34 
    34 
   339     }
   339     }
   340 
   340 
   341     return dialog;
   341     return dialog;
   342 }
   342 }
   343 
   343 
   344 /* This function is called if a Task Dialog is unsupported. */
   344 int
   345 static int
   345 WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
   346 WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
       
   347 {
   346 {
   348     WIN_DialogData *dialog;
   347     WIN_DialogData *dialog;
   349     int i, x, y;
   348     int i, x, y;
   350     const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
   349     const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
   351     HFONT DialogFont;
   350     HFONT DialogFont;
   490 
   489 
   491     FreeDialogData(dialog);
   490     FreeDialogData(dialog);
   492     return 0;
   491     return 0;
   493 }
   492 }
   494 
   493 
   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)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, 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 */
   494 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
   611 
   495 
   612 /* vi: set ts=4 sw=4 expandtab: */
   496 /* vi: set ts=4 sw=4 expandtab: */