VBA – Message Box That Supports Unicode Characters

Working on a recent project I needed to be able to use unicode characters in a Message Box. Sadly, the built-in MsgBox does not support such characters. Who knew?!

So I set off and quickly came across a Stack Overflow thread in which it was mentioned to use the MessageBoxW API. I then search it up and found:

 

Armed with this information, we could build a wrapper around the function call so we could create a reusable user defined function.

This was what I eventually ended up with, after a few permutations:

#If VBA7 Then
    Private Declare PtrSafe Function MessageBoxW Lib "user32" (ByVal hWnd As LongPtr, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, ByVal uType As Long) As Long
#Else
    Private Declare Function MessageBoxW Lib "user32" (ByVal hWnd As Long, ByVal lpText As Long, ByVal lpCaption As Long, ByVal uType As Long) As Long
#End If

'---------------------------------------------------------------------------------------
' Procedure : Unicode_MsgBox
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Unicode Message Box
'               Same format as standard MsgBox()
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
'             (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: None required
' Dependencies: MessageBoxW API Declaration
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPrompt   : Message to display
' lButtons  : Button(s) to display
' sTitle    : Dialog title
' bLTR      : Left-To-Right display of content?
'               True  => Left-to-Right
'               False => Right-to-Left
'
' Usage:
' ~~~~~~
' ? Unicode_MsgBox(sMsg, vbCritical Or vbYesNo, "Left-To-Right Example")
'
' ? Unicode_MsgBox(sMsg, vbCritical Or vbOKOnly, "Right-To-Left Example", False)
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2023-01-11
' 1         2023-03-02              Added Left-To-Right/Right-To-Left Option
'---------------------------------------------------------------------------------------
Public Function Unicode_MsgBox(sPrompt As String, lButtons As VbMsgBoxStyle, sTitle As String, _
                               Optional bLTR As Boolean = True) As VbMsgBoxResult
On Error GoTo Error_Handler
    #If VBA7 Then
        Dim lhWnd             As LongPtr
    #Else
        Dim lhWnd             As Long
    #End If
    Dim oApp                  As Object

    Set oApp = Application    'Need to do this to get around Compilation issue
    'of using it directly in code!

    Select Case Application.Name
        Case "Microsoft Access"
            lhWnd = oApp.hWndAccessApp        'Access
        Case "Microsoft Excel"
            lhWnd = oApp.ActiveWindow.hWnd    'Excel
        Case "Microsoft Word"
            lhWnd = oApp.ActiveWindow.hWnd    'Word
    End Select

    If bLTR = False Then
        sPrompt = ChrW(8207) & ChrW(8207) & sPrompt
        sTitle = ChrW(8207) & ChrW(8207) & sTitle
    End If

    Unicode_MsgBox = MessageBoxW(lhWnd, StrPtr(sPrompt), StrPtr(sTitle), lButtons)

Error_Handler_Exit:
    On Error Resume Next
    Set oApp = Nothing
    Exit Function
 
Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: Unicode_MsgBox" & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occurred!"
    Resume Error_Handler_Exit
End Function

If you read the documentation, it states:

Adding two right-to-left marks (RLMs), represented by Unicode formatting character U+200F, in the beginning of a MessageBox display string is interpreted by the MessageBox rendering engine so as to cause the reading order of the MessageBox to be rendered as right-to-left (RTL).Microsoft

and that is why the function includes an optional 4th argument which switches between right-to-left and left-to-right display. So by prefixing the prompt with 2 RLM marks (ChrW(8207)), we can switch to the direction. (not hard once you know!)

Also, we could also have code the call from a form and thus used the form’s Hwnd value, but by coding things in this manner it is more flexible and we can now use it in Access, Excel & Word. It can be further expanded to PowerPoint and Outlook, and even beyond, but would require more coding to be able to retrieve their Hwnd values at runtime.
 

Usage Examples

Simple Message Box

Unicode_MsgBox "I moved my " & ChrW(9822), vbOKOnly, "My Chess Move Was"

Checking The Clicked Button

If vbYes = Unicode_MsgBox("Would you like to move your " & ChrW(9822), vbQuestion Or vbYesNo, "My Chess Move Was") Then

End If

Right-to-Left Message

Unicode_MsgBox "I moved my " & ChrW(9822), vbOKOnly, "My Chess Move Was", False

 

Useful Resources

2 responses on “VBA – Message Box That Supports Unicode Characters

  1. Taha

    Simple and powerfull MsgBox :
    CreateObject(“Wscript.Shell”).Popup ChrW(9829) & ChrW(32) & ChrW(9834)

    1. Daniel Pineault Post author

      Thank you for sharing. I’d never seen/heard of Popup before, nor can I find official documentation on it, but it does indeed work and offers the same options (in a different order though) as MsgBox making it easy to use.

      The nice thing here is we don’t need any API declarations and the “ChrW(8207) & ChrW(8207)” code does work to switch the dialog to right handed.

      The one oddity I’ve found is the 2nd argument, nSecondsToWait, does not seem to be respected in VBA.