Search Unity

Windows Message Box

Discussion in 'Scripting' started by mholmes, Oct 19, 2018.

  1. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    I take little credit for this post. I got this from another post and I just built it out in a more complete fashion:

    Code (CSharp):
    1. using System;
    2. using System.Runtime.InteropServices;
    3.  
    4. namespace WBG
    5. {
    6.     /// <see>https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-messagebox</see>
    7.     public class MessageBox
    8.     {
    9.         [System.Runtime.InteropServices.DllImport("user32.dll")]
    10.         private static extern System.IntPtr GetActiveWindow();
    11.         [DllImport("user32.dll", SetLastError = true)]
    12.         static extern int MessageBox(IntPtr hwnd, String lpText, String lpCaption, uint uType);
    13.  
    14.         public static System.IntPtr GetWindowHandle()
    15.         {
    16.             return GetActiveWindow();
    17.         }
    18.  
    19. /// <summary>
    20.         /// Shows Message Box with button type.
    21.         /// </summary>
    22.         /// <param name="text">Main alert text / content.</param>
    23.         /// <param name="caption">Message box title.</param>
    24.         /// <param name="type">Type of message / icon to use - </param>
    25.         /// <remarks>types: AbortRetryIgnore, CancelTryContinue, Help, OK, OkCancel, RetryCancel, YesNo, YesNoCancel</remarks>
    26.         /// <example>Message_Box("My Text Message", "My Title", "OK");</example>
    27.         /// <returns>OK,CANCEL,ABORT,RETRY, IGNORE, YES, NO, TRY AGAIN</returns>
    28.         public string Message_Box(string text, string caption, string type)
    29.         {
    30.             try
    31.             {
    32.                 string DialogResult = string.Empty;
    33.                 uint MB_ABORTRETRYIGNORE = (uint)(0x00000002L | 0x00000010L);
    34.                 uint MB_CANCELTRYCONTINUE = (uint)(0x00000006L | 0x00000030L);
    35.                 uint MB_HELP = (uint)(0x00004000L | 0x00000040L);
    36.                 uint MB_OK = (uint)(0x00000000L | 0x00000040L);
    37.                 uint MB_OKCANCEL = (uint)(0x00000001L | 0x00000040L);
    38.                 uint MB_RETRYCANCEL = (uint)0x00000005L;
    39.                 uint MB_YESNO = (uint)(0x00000004L | 0x00000040L);
    40.                 uint MB_YESNOCANCEL = (uint)(0x00000003L | 0x00000040L);
    41.                 int intresult = -1;
    42.                 string strResult = string.Empty;
    43.  
    44.                 switch (type)
    45.                 {
    46.                     case "AbortRetryIgnore":
    47.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_ABORTRETRYIGNORE);
    48.                         break;
    49.                     case "CancelTryContinue":
    50.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_CANCELTRYCONTINUE);
    51.                         break;
    52.                     case "Help":
    53.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_HELP);
    54.                         break;
    55.                     case "OK":
    56.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_OK);
    57.                         break;
    58.                     case "OkCancel":
    59.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_OKCANCEL);
    60.                         break;
    61.                     case "RetryCancel":
    62.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_RETRYCANCEL);
    63.                         break;
    64.                     case "YesNo":
    65.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_YESNO);
    66.                         break;
    67.                     case "YesNoCancel":
    68.                         intresult = MessageBox(GetWindowHandle(), text, caption, MB_YESNOCANCEL);
    69.                         break;
    70.                     default:
    71.                         intresult = MessageBox(GetWindowHandle(), text, caption, (uint)(0x00000000L | 0x00000010L));
    72.                         break;
    73.                 }
    74.  
    75.                 switch(intresult)
    76.                 {
    77.                     case 1:
    78.                         strResult = "OK";
    79.                         break;
    80.                     case 2:
    81.                         strResult = "CANCEL";
    82.                         break;
    83.                     case 3:
    84.                         strResult = "ABORT";
    85.                         break;
    86.                     case 4:
    87.                         strResult = "RETRY";
    88.                         break;
    89.                     case 5:
    90.                         strResult = "IGNORE";
    91.                         break;
    92.                     case 6:
    93.                         strResult = "YES";
    94.                         break;
    95.                     case 7:
    96.                         strResult = "NO";
    97.                         break;
    98.                     case 10:
    99.                         strResult = "TRY AGAIN";
    100.                         break;
    101.                     default:
    102.                         strResult = "OK";
    103.                         break;
    104.  
    105.                 }
    106.  
    107.                 return strResult;
    108.             }
    109.             catch (Exception ex)
    110.             {
    111.                 return string.Empty;
    112.             }
    113.         }
    114.     }
    115. }
    Requires:
    User32.dll
    User32.lib

    Might try it on Mac it may work if you include the DLL in your solution and compile it.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    No it won't.

    User32.dll is a Windows specific system library.
     
  3. mholmes

    mholmes

    Joined:
    Dec 8, 2012
    Posts:
    414
    I believe DLL is also a windows specific thing as well so likely will not work but maybe someone might find the "fork in the road" or figure out a way to get it to work. Who knows. Just passing the info along. I know I had a hard time finding a message box solution for Unity without paying.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    It's not just that the concept of a dll is a Windows thing. Which it is, Microsoft came up with the dynamic link library back in the 80's.

    But it's not just that. A dll can contain all sorts of kind of code, C# compiles into a managed dll that relies on the .net or mono runtime to run. These can easily be made to work on different platforms.

    Where as User32.dll is a Windows core component. It directly relies on the Windows kernel and windowing system. Something both Mac and Linux do NOT use at all and instead have their own software, MacOS with their BSD like Darwin kernel, and Linux with well... its Linux kernel. And they use the X11 windowing system instead. These are completely different from Windows.

    Now yes... you can write a model dialog window for both Linux and MacOS. But the User32.dll would not be part of it. The code wouldn't be either because the API of their windowing system is completely different.

    And of course it's been accomplished in the past. There is even as asset on the asset store for it:
    https://assetstore.unity.com/packages/tools/os-x-native-alert-21741

    The Xamarin library also contains its own sub library for native mac stuff like the NSAlert (though probably with some compatibility issues in unity... long story there):
    https://docs.microsoft.com/en-us/xamarin/mac/user-interface/alert

    ...

    My point is you can't just include the User32.dll and get it to work with some fiddling. It just won't happen. It's not a possibility (with the exception of running a windows emulator on mac or linux, but then you're not really showing a mac/linux alert message anyways).

    I'm bringing this up in case someone trips over your example and thinks that they might be able to get it to work and goes down a path not worth the effort because it just won't happen.
     
    Larzarus likes this.