Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function MessageBoxIndirect Lib "user32" Alias "MessageBoxIndirectW" (lpMsgBoxParams As MSGBOXPARAMS) As Long
Private Declare PtrSafe Function MessageBeep Lib "user32" (ByVal wType As Long) As Long
#Else
Private Enum LongPtr
[_]
End Enum
Private Declare Function MessageBoxIndirect Lib "user32" Alias "MessageBoxIndirectW" (lpMsgBoxParams As MSGBOXPARAMS) As Long
Private Declare Function MessageBeep Lib "user32" (ByVal wType As Long) As Long
#End If
Private Type MSGBOXPARAMS
cbSize As Long
hwndOwner As LongPtr
hInstance As LongPtr
lpszText As LongPtr
lpszCaption As LongPtr
dwStyle As Long
lpszIcon As LongPtr
dwContextHelpId As LongPtr
lpfnMsgBoxCallback As LongPtr
dwLanguageId As Long
End Type
Public Function MuteMsgBox( _
ByVal Prompt As String, _
Optional Buttons As VbMsgBoxStyle, _
Optional Title As String = "Microsoft Excel", _
Optional Mute As Boolean = True _
) As VbMsgBoxResult
Const MB_USERICON = &H80&
Dim tMP As MSGBOXPARAMS
Dim lIcon As Long
lIcon = ExtractIcon(Buttons)
If Mute = False And lIcon Then
Call MessageBeep(lIcon)
End If
With tMP
.cbSize = LenB(tMP)
.hwndOwner = Application.hwnd
.lpszText = StrPtr(Prompt)
.lpszCaption = StrPtr(Title)
.lpszIcon = IconID(lIcon)
.dwStyle = IIf(.lpszIcon, ((Buttons + MB_USERICON) And Not (&H70&)), Buttons)
End With
MuteMsgBox = MessageBoxIndirect(tMP)
End Function
Private Function IconID(ByVal ID As VbMsgBoxStyle) As LongPtr
Const IDI_WARNING = 101&, IDI_QUESTION = 102&
Const IDI_ERROR = 103&, IDI_INFORMATION = 104&
Select Case ID
Case vbCritical
IconID = IDI_ERROR
Case vbQuestion
IconID = IDI_QUESTION
Case vbExclamation
IconID = IDI_WARNING
Case vbInformation
IconID = IDI_INFORMATION
End Select
End Function
Private Function ExtractIcon(Buttons As Long) As Long
Dim i As Long
For i = 16& To 64& Step 16&
If (Buttons And i) = i Then
ExtractIcon = i
End If
Next i
End Function