> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# WizMsg(): A Simple Way to Create a MsgBox with Bold Text
- URL: https://nolongerset.com/wizmsg/
- Published: 2022-10-28T03:59:00.000Z
- Updated: 2026-05-08T12:53:55.000Z
- Description: Bold text in a Microsoft Access message box? It's true. And it requires no API calls, no third-party libraries, and no arcane string syntax. Check out WizMsgBox!
- Author: Mike Wolfe
- Tags: WizHook, Code Library, #WizHook, #Import 2026-05-20 02:59

It's not possible to add formatting to a standard message box in VBA.

However, using the [hidden WizHook object](https://nolongerset.com/wizhook/) in Access, we gain the ability to easily create message boxes with a leading line of bold text. We can do this without relying on API calls or other advanced trickery.

The message box is very similar to the built-in version, with a few key differences:

- WizMsgBox treats the `@` symbol as a paragraph separator
- First paragraph of the message box appears in **bold**
- Up to three distinct paragraphs may be included

As this is an undocumented internal function that was never meant to see the light of day, it takes an...umm...*eccentric* approach to parsing the message text. The at sign (`@`) is used as a paragraph separator for...reasons. ¯\\\_ (ツ)\_/¯

## The Starting Point

I used the following code to test exactly how the @ symbols get treated by WizMsgBox:

```vba
Public Sub TestWizMsgBox()
    With WizHook
        .Key = 51488399
                
        Dim s As String
        s = "BoldLine1 @ @": .WizMsgBox s, "_" & s & "_", 0, 0, ""
        s = "BoldLine1 @ @ ": .WizMsgBox s, "_" & s & "_", 0, 0, ""
        s = "BoldLine1 @@": .WizMsgBox s, "_" & s & "_", 0, 0, ""
        s = "BoldLine1@@": .WizMsgBox s, "_" & s & "_", 0, 0, ""
    End With
End Sub
```

If you run this code, you'll see it produces a surprising variety of results. 

## The Approach

Trying to understand and remember the arbitrary rules for the special @ symbol handling seemed destined to cause frustration and lead to easily-missed bugs.

So, instead of calling WizMsgBox directly in my code, I created a wrapper function that encapsulates the @-handling complexity.

### A Note About Parameter Order

One thing you may notice is that–unlike the standard MsgBox–the dialog's Title (A) is the first parameter and (B) is required.

I agonized over this difference, but ultimately decided it made sense since I have separate optional arguments for lines 2 and 3\. It didn't feel right to put the title after both of the optional lines, especially since I don't anticipate Line3 will be called very often. And putting the Title between lines 2 and 3 seemed like the worst sort of compromise. 

In the end, I'm happy with how it turned out. The arguments appear on the dialog box from top to bottom: 

- Title
- Line 1
- Line 2
- Line 3
- Button Styles

Obviously, you can change the order of the arguments as you see fit.

### The Optional Values of Line2 and Line3

As the comments explain, these values are not typos.

- Line2's default value is a single space
- Line3's default value is a zero-length string

I arrived at these values through trial and error. See the bottom of the article for a screenshot of how various message boxes appear based on which lines are provided and which are not.

## The `WizMsg` Function

As with many WizHook methods, we first need to unlock the WizHook object by setting its key to the magic value of `**51488399**`. Rather than do this directly, I call my [**Wiz()** convenience function](https://nolongerset.com/wiz-wizhook-helper/), which handles applying the magic value when needed.

```vba
' ----------------------------------------------------------------
' Procedure : WizMsg
' Date      : 10/28/2022
' Author    : Mike Wolfe
' Source    : https://nolongerset.com/wizmsg/
' Purpose   : Wrapper around the WizHook.WizMsgBox function
'               for improved code readability and reliability.
' Notes     - The optional values of Line2 and Line3 are not typos:
'               - Line2 is a single space
'               - Line3 is a zero-length string
'           - This provides us with the most intuitive results when
'				the calling code chooses not to provide either or both.
' ----------------------------------------------------------------
Public Function WizMsg(Title As String, _
        BoldLine1 As String, _
        Optional Line2 As String = " ", _
        Optional Line3 As String = "", _
        Optional MsgBoxStyle As VbMsgBoxStyle = vbOKOnly) As VbMsgBoxResult
    With Wiz
        WizMsg = .WizMsgBox(BoldLine1 & "@" & _
                            Line2 & "@" & _
                            Line3, Title, MsgBoxStyle, 0, "")
    End With
End Function

' Wiz() function included to allow easy copy-pasting of code sample
' Source    : https://nolongerset.com/wiz-wizhook-helper/
Private Function Wiz() As Access.WizHook
    Static WizHookInitialized As Boolean
    
    If Not WizHookInitialized Then
        'Most WizHook methods only work after this key has been applied:
        Const MagicWizHookKey As Long = 51488399
        WizHook.Key = MagicWizHookKey
        
        'The key only needs to be applied once per session
        WizHookInitialized = True
    End If
    
    Set Wiz = WizHook
End Function
```

## Sample Usage

I used the following test routine to see the impact of setting or not setting the three line arguments: `BoldLine1`, `Line2`, and `Line3`.

```vba
Public Sub TestWiz()
    Dim x As String, y As String, z As String
    x = "Line1": y = " ": z = "": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "Line1": y = "Line2": z = "": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "Line1": y = " ": z = "Line3": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "Line1": y = "Line2": z = "Line3": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    
    x = "": y = " ": z = "": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "": y = "Line2": z = "": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "": y = " ": z = "Line3": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
    x = "": y = "Line2": z = "Line3": WizMsg "x" & x & "x y" & y & "y z" & z & "z", x, y, z
End Sub
```

There are eight samples that represent all possible combinations of these three strings being either populated or not (2^3 = 8). I've included the sample output below as a handy reference.

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2022/10/image-55.png)