none
OKボタンのないメッセージボックスを作成したい RRS feed

  • 質問

  • OKボタンのないメッセージボックスを作成したいのですが、どうしてもOKボタンのメッセージボックスしか作成できません。

    それ以外の場合は、[はい]、[いいえ]、および[キャンセル]、または[中止]、[再試行]、および[無視]、 [再試行]ボタンと[キャンセル]ボタンのついたメッセージボックスしか作成できません。

    メッセージボックスにOKボタンはもちろん、何もボタンのないメッセージのみのメッセージボックスにしたいのですが、可能でしょうか?








    • 編集済み kuro1962 2016年4月28日 5:16
    2016年4月28日 5:08

回答

  • Hook を使えばメッセージボックスの OK ボタンを非表示にできます。

    Option Explicit
    
    Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
            (ByVal idHook As Long, _
            ByVal lpfn As LongPtr, _
            ByVal hmod As LongPtr, _
            ByVal dwThreadId As Long) As LongPtr
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As LongPtr
    Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, _
        ByVal nCmdShow As Long) As Long
    Private Declare PtrSafe Function GetDlgItem Lib "user32" ( _
    ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long) As LongPtr
    Private Declare PtrSafe Function MessageBox Lib "user32" _
       Alias "MessageBoxA" _
      (ByVal hwnd As LongPtr, _
       ByVal lpText As String, _
       ByVal lpCaption As String, _
       ByVal wType As Long) As Long
    
    Private Const WH_CBT = 5
    Private Const HCBT_ACTIVATE = 5
    Private Const SW_HIDE = 0
    Private Const IDOK = 1
    Private Const MB_OK = 0
    
    Private HookHandle As LongPtr
    
    Private Function CBTProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
        If nCode = HCBT_ACTIVATE Then
            Call UnhookWindowsHookEx(HookHandle)
            Call ShowWindow(GetDlgItem(wParam, IDOK), SW_HIDE)
        End If
        CBTProc = 0
    End Function
    
    Public Sub test()
        HookHandle = SetWindowsHookEx(WH_CBT, AddressOf CBTProc, Application.HinstancePtr, GetCurrentThreadId())
        Dim hwnd As LongPtr
            If (Application.Version > 14) Then
                hwnd = Application.ActiveWindow.hwnd
            Else
                hwnd = Application.hwnd
            End If
        Call MessageBox(hwnd, "OKボタン非表示", "タイトル", MB_OK)
    End Sub
    

    • 回答としてマーク kuro1962 2016年4月29日 7:56
    2016年4月28日 6:24
  • メッセージボックスでは無理だと思いますので、ユーザーフォームのようなものを代わりに使うようになると思います。

    (参考)
    ユーザーフォームについて
    http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_080.html

    ところで、開発されているのは何のVBAなのでしょうか? Excel? Access? その他・・・


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク kuro1962 2016年4月29日 8:03
    2016年4月28日 5:56
    モデレータ
  • 確かにフックという方法がありますね。失礼いたしました。
    ただ、杞憂かもしれませんが、ひょっとするとお使いの環境に依存するかもしれませんね・・・


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2016年4月28日 7:01
    モデレータ

すべての返信

  • メッセージボックスでは無理だと思いますので、ユーザーフォームのようなものを代わりに使うようになると思います。

    (参考)
    ユーザーフォームについて
    http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_080.html

    ところで、開発されているのは何のVBAなのでしょうか? Excel? Access? その他・・・


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク kuro1962 2016年4月29日 8:03
    2016年4月28日 5:56
    モデレータ
  • Hook を使えばメッセージボックスの OK ボタンを非表示にできます。

    Option Explicit
    
    Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
            (ByVal idHook As Long, _
            ByVal lpfn As LongPtr, _
            ByVal hmod As LongPtr, _
            ByVal dwThreadId As Long) As LongPtr
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As LongPtr
    Private Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, _
        ByVal nCmdShow As Long) As Long
    Private Declare PtrSafe Function GetDlgItem Lib "user32" ( _
    ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long) As LongPtr
    Private Declare PtrSafe Function MessageBox Lib "user32" _
       Alias "MessageBoxA" _
      (ByVal hwnd As LongPtr, _
       ByVal lpText As String, _
       ByVal lpCaption As String, _
       ByVal wType As Long) As Long
    
    Private Const WH_CBT = 5
    Private Const HCBT_ACTIVATE = 5
    Private Const SW_HIDE = 0
    Private Const IDOK = 1
    Private Const MB_OK = 0
    
    Private HookHandle As LongPtr
    
    Private Function CBTProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
        If nCode = HCBT_ACTIVATE Then
            Call UnhookWindowsHookEx(HookHandle)
            Call ShowWindow(GetDlgItem(wParam, IDOK), SW_HIDE)
        End If
        CBTProc = 0
    End Function
    
    Public Sub test()
        HookHandle = SetWindowsHookEx(WH_CBT, AddressOf CBTProc, Application.HinstancePtr, GetCurrentThreadId())
        Dim hwnd As LongPtr
            If (Application.Version > 14) Then
                hwnd = Application.ActiveWindow.hwnd
            Else
                hwnd = Application.hwnd
            End If
        Call MessageBox(hwnd, "OKボタン非表示", "タイトル", MB_OK)
    End Sub
    

    • 回答としてマーク kuro1962 2016年4月29日 7:56
    2016年4月28日 6:24
  • 確かにフックという方法がありますね。失礼いたしました。
    ただ、杞憂かもしれませんが、ひょっとするとお使いの環境に依存するかもしれませんね・・・


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2016年4月28日 7:01
    モデレータ
  • Excel です。メッセージボックスがダメなら、ユーザーフォームも参考にしたいと思います。

    • 編集済み kuro1962 2016年4月29日 8:07
    2016年4月29日 8:03
  • 回答ありがとうございました。

    参考にしながらやってみます。

    2016年4月29日 8:10
  • 今更ですが、OK ボタンを消したいという要求があるのに、メッセージボックスをこだわる理由は何だろうと疑問に感じます。

    フォームを自分で作る方が、圧倒的に自由度が高いのはご理解いただいているものと思います。
    それでもなお、メッセージボックスを選び、そして OK ボタンを消し去りたいというのはどういった理由からなのかが読み取れませんでした。
    なお、メッセージボックスを改造して使う方法は、将来的な安定性に欠けますのでおすすめしません。
    (Windows 10 のどこかのビルドでうまく動かなくなるとか、そういった未来も十分あり得るという話です)

    2016年4月30日 15:18