【VBA研究】定时关闭MsgBox及相关未公开的API

时间:2022-06-30 18:09:29

iamlaosong文

    大家都知道,VBA中自带的MsgBox不能自动关闭,某些特殊情况下需要在指定时间内用户没有点击消息框按钮后能继续运行代码,需要用到定时关闭的消息框,我一般都是自己做一个窗体显示,再用定时函数关闭对话框。方法如下:

1、创建窗体UserForm1,窗体的初始化函数最简单如下:

Private Sub UserForm_Initialize()

    Label1.Caption = “欢迎使用本工作薄!”
    Application.OnTime Now + TimeValue("00:00:05"), "CloseMsgBox"
End Sub

下面是防止用户自己关闭窗口:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
     If CloseMode <> 1 Then Cancel = 1
End Sub

2、创建一个模块,模块中放一个关闭窗体的过程CloseMsgBox:

Sub CloseMsgBox()
      Unload UserForm1
End Sub

反复使用的时候,可以用下列方法,这种方法关闭不能在Initialize事件中放定时器,显示的内容可以通过函数变量传递(进一步可以将显示时间作为函数变量或者增加其它功能),例如:

Sub MyMsgBox(hint As String)
    UserForm1.Label1.Caption = hint
    Application.OnTime Now + TimeValue("00:00:05"), "CloseMsgBox"
    UserForm1.Show
End Sub

Sub CloseMsgBox()
      UserForm1.Hide
End Sub


Sub test()
    MyMsgBox ("这只是一个测试!")
End Sub

     自己做窗体的好处是可以按照自己喜欢的方式和样子做消息框,可以附加一些自己想要的功能,相对也就比较麻烦,其实API提供了这样一个未公开的API可以实现定时关闭消息框,wType参数改成可以提示输入VBA的vbMsgboxStyle常数,用起来非常方便。

Private Declare Function MsgBoxEx Lib "user32" Alias "MessageBoxTimeoutA" ( _
    ByVal hwnd As Long, _
    ByVal lpText As String, _
    ByVal lpCaption As String, _
    ByVal wType As VbMsgBoxStyle, _
    ByVal wlange As Long, _
    ByVal dwTimeout As Long) As Long

这个API函数的参数如下:
    hwnd:窗口句柄,可以设为0
    lpText:消息框显示内容,类似于MsgBox函数的第一个参数Prompt
    lpCaption:消息框标题,类似于MsgBox函数的第三个参数Caption
    wType:消息框类型,类似于MsgBox函数的第二个参数Buttons
    wlange:不是太明白这个参数,0或者1都看不出什么差别
    dwTimeout:延时时间,单位是毫秒
返回的值和vbMsgBoxResult常数一样,多了一个返回值32000表示超过延时时间未选择任何按钮。
下面是测试程序:
Private Sub TestMsgboxEx()
    Dim ret As Long
    ret = MsgBoxEx(0, "请选择", "两秒后自动关闭", vbYesNo + vbInformation, 1, 2000)
    If ret = 32000 Then
        Debug.Print "超时关闭"
    ElseIf ret = vbYes Then
        Debug.Print "选择Yes"
    ElseIf ret = vbNo Then
        Debug.Print "选择No"
    End If
End Sub