ビルドンブング

自由でシンプルな生活を求めて試行錯誤する記録を毎日更新中

【VBA×WindowsAPI】APIのMessageBoxをVBAのMsgBoxと同じような感覚で使う

当ブログではアフィリエイト広告を利用しています

WindowsAPIのMessageBoxがVBAのMsgBoxと大きく違うのは、ウインドウハンドルを指定できることである。

VBAのMsgBoxだとメッセージボックスは必ずエクセル側で表示されてしまう。
例えば、WindowsAPIで他のアプリを操作していてエクセル以外のウインドウがアクティブになっていたら、そのメッセージは表示されない。
タスクバーのエクセルアイコンが点滅して、自分でエクセルをアクティブにして初めて、メッセージボックスが表示されるのだ。
その辺りはMsgBoxの実行前に「SetForegroundWindow Application.Hwnd」を挟んでおけばとりあえず対応はできる。
けれど、結局はVBAによるエクセルからのメッセージボックスなので、表示位置はエクセルのウインドウ中央となる。

一方のWindowsAPIによるMessageBoxなら、引数でウインドウハンドルを指定できる。
もしも他のウインドウを操作している最中に表示させたいメッセージであれば、そのウインドウハンドルを指定してやれば、よりユーザビリティの高いプログラムになるとは思わないだろうか?

しかし、動作によってWindowsAPIの「MessageBox」とVBAの「MsgBox」を使い分けるのは面倒である。
なにしろ定数が異なる。
その定数に関する部分をできるだけVBAに寄せようというのが今回の試みだ。
というわけで早速コードを提示する。
なお、各種APIと定数の宣言は省略している。

Function ShowMessageBox(btn As Long, ico As Long, sText As String, sCap As String, Optional hWnd As LongPtr = 0, Optional isSysModal As Boolean = True) As Long
	SetForegroundWindow hWnd
		Dim uType As Long
		Select Case btn
			Case vbOKOnly
            uType = MB_OK
        Case vbOKCancel
            uType = MB_OKCANCEL
        Case vbYesNo
            uType = MB_YESNO
        Case vbYesNoCancel
            uType = MB_YESNOCANCEL
    End Select
    Select Case ico
        Case vbInformation
            uType = uType Or MB_ICONINFORMATION
        Case vbExclamation
            uType = uType Or MB_ICONEXCLAMATION
        Case vbQuestion
            uType = uType Or MB_ICONQUESTION
        Case vbCritical
            uType = uType Or MB_ICONSTOP
    End Select
    If isSysModal Then uType = uType Or MB_SYSTEMMODAL
    Dim ret As Long
    ret = MessageBox(hWnd, sText, sCap, uType)
    Select Case ret
        Case IDOK
            ShowMessageBox = vbOK
        Case IDCANCEL
            ShowMessageBox = vbCancel
        Case IDYES
            ShowMessageBox = vbYes
        Case IDNO
            ShowMessageBox = vbNo
    End Select
End Function

要するにAPIの定数とVBAの定数を相互変換して、引数と戻り値をともにVBAのMsgBoxと同じにしているだけである。
機能としては最低限だろうか。

learn.microsoft.com


上記のサイトを参考に引数を増やすなどしてより柔軟に対応できるメッセージボックス関数を作るのも楽しいかもしれない。