コピー可能なメッセージボックス1

普通のメッセージボックスは表示されたメッセージをコピーできない。
いや、Ctrl+Cでコピーすることはできるが、いらない情報がくっついてくる。


http://msdn.microsoft.com/ja-jp/ff427438.aspx

エラー メッセージに長い番号などが表示されている場合にはこの機能を活用することで間違うことなく内容を取得できます。

うむ。言いたいことはわかるが、一部だけコピーしたい場合だってある。
仕事で使うことになったので、さくっと作ってみた。*1
あとでコピって使おうっと。


これ(→)が完成図。
ただ作ってもつまらないので、JITのやつ(右の方ね)を真似してみる。
デザインの課程は省略するとして、インターフェースを考えてみる。

インターフェース

突飛なものは必要ないはず。
System.Windows.MessageBoxから朴ることにする。クラス名はMessageDialogとしておこう。
さしあたってはShowメソッドだけあれば良いが、ヘルプファイルを指定するやつは不要だろう……。
以下の5つに決定。

Public Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String) As System.Windows.Forms.DialogResult
Public Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String, ByVal caption As String) As System.Windows.Forms.DialogResult
Public Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As System.Windows.Forms.MessageBoxButtons) As System.Windows.Forms.DialogResult
Public Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As System.Windows.Forms.MessageBoxButtons, ByVal icon As System.Windows.Forms.MessageBoxIcon) As System.Windows.Forms.DialogResult
Public Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As System.Windows.Forms.MessageBoxButtons, ByVal icon As System.Windows.Forms.MessageBoxIcon, ByVal defaultButton As System.Windows.Forms.MessageBoxDefaultButton) As System.Windows.Forms.DialogResult

長い。
一番引数の多いヤツだけ書けばいい訳だが、丸投げコードもこれだけあるとめんどくさい。

実装

とりあえずSharedメソッドなので、自身のインスタンスはShared変数にぶち込んでシングルトンな感じにしておく。

    Private Shared _MyInstance As New MessageDialog
    ''' <summary>
    ''' このクラスのシングルトンインスタンスを返します。
    ''' </summary>
    ''' <returns>MessageDialog のインスタンス</returns>
    ''' <remarks></remarks>
    Private Shared ReadOnly Property MyInstance() As MessageDialog
        Get
            Return _MyInstance
        End Get
    End Property
Showメソッド

で、Showメソッドを実装してみる。System.Windows.Forms.Formを継承したので、ShowメソッドにはOverloadキーワードが必要。
ボタンを追加したりアイコンを描いたりする処理はインスタンスメソッドで書くとして、とりあえずこんな感じに。

    ''' <summary>
    ''' 指定したオブジェクトの前に、指定したテキストを表示するメッセージ ボックスを表示します。
    ''' </summary>
    ''' <param name="owner">モーダル ダイアログ ボックスを所有する System.Windows.Forms.IWin32Window の実装。</param>
    ''' <param name="text">メッセージ ボックスに表示するテキスト。</param>
    ''' <param name="caption">メッセージ ボックスのタイトル バーに表示するテキスト。</param>
    ''' <param name="buttons">メッセージ ボックスに表示されるボタンを指定する System.Windows.Forms.MessageBoxButtons 値の 1 つ。</param>
    ''' <param name="icon">メッセージ ボックスに表示されるアイコンを指定する System.Windows.Forms.MessageBoxIcon 値の 1 つ。</param>
    ''' <param name="defaultButton">メッセージ ボックスの既定のボタンを指定する System.Windows.Forms.MessageBoxDefaultButton 値の 1 つ。</param>
    ''' <returns>System.Windows.Forms.DialogResult 値のいずれか。</returns>
    ''' <remarks></remarks>
    Public Overloads Shared Function Show(ByVal owner As System.Windows.Forms.IWin32Window, ByVal text As String, ByVal caption As String, ByVal buttons As System.Windows.Forms.MessageBoxButtons, ByVal icon As System.Windows.Forms.MessageBoxIcon, ByVal defaultButton As System.Windows.Forms.MessageBoxDefaultButton) As System.Windows.Forms.DialogResult
        With MyInstance
            .Clear()
            .txtMessage.Text = text
            .Text = caption
            .SetButtons(buttons)
            .SetIcon(icon)
            .SetDefaultButton(defaultButton)

            If (.AcceptButton IsNot Nothing) Then
                DirectCast(.AcceptButton, System.Windows.Forms.Button).Select()
                DirectCast(.AcceptButton, System.Windows.Forms.Button).Focus()
            End If
        End With

        Return MyInstance.ShowDialog(owner)
    End Function

Clearメソッドはダイアログを初期化する*2。たいしたことないので割愛。
メッセージとキャプションは普通にテキストボックスとフォーム自身のTextプロパティに設定してやればよい。
JITのあれっぽく動かすには、textの代わりにExceptionを受けてMessageとStackTraceをごにょごにょすればいいだろう。
なんか長くなってしまったのでSetButtonsメソッド以降は別途。

*1:といってもメモってたら結構な長文になってしまった。ここに書いてた時間の方が絶対に長い。

*2:メッセージとキャプションとボタンとアイコンを消去でおk。