如何在VB中控制仪器“msgbox”。净

时间:2013-09-09 13:45:04

标签: vb.net-2010 messagebox

我可以在MsgBox中显示自定义按钮吗?我想在msgbox的常规按钮中使用不同的按钮:

  1. 取消
  2. 中止
  3. 重试
  4. 忽略
  5. 没有
  6. 如何控制这些按钮的文字和值?

3 个答案:

答案 0 :(得分:3)

不,MsgBox直接绑定到底层Windows UI,无法轻松更改或扩展 你应该创建自己的类或者寻找像这样的已经制作的项目

A versatile MessageBox replacement

嗯,关于这个问题的一些研究让我看到了这篇旧文章和代码

Using Windows Hooks to Enhance MessageBox in .NET

但这是很多工作,也许你可以更好地利用你的时间来构建自己的消息类。

答案 1 :(得分:1)

您可以修改消息框,但会有限制。最大按钮数为3.按钮文本可以更改。

将以下类添加到项目中,这将帮助您更改按钮的文本。

Imports System.Text
Imports System.Windows.Forms

Public Class MessageClass

Private Shared mLabels() As String    '' Desired new labels
Private Shared mLabelIndex As Integer '' Next caption to update

Public Shared Sub PatchMsgBox(ByVal labels() As String)
    ''--- Updates message box buttons
    mLabels = labels
    Application.OpenForms(0).BeginInvoke(New FindWindowDelegate(AddressOf FindMsgBox), GetCurrentThreadId())
End Sub

Private Shared Sub FindMsgBox(ByVal tid As Integer)
    ''--- Enumerate the windows owned by the UI thread
    EnumThreadWindows(tid, AddressOf EnumWindow, IntPtr.Zero)
End Sub

Private Shared Function EnumWindow(ByVal hWnd As IntPtr, ByVal lp As IntPtr) As Boolean
    ''--- Is this the message box?
    Dim sb As New StringBuilder(256)
    GetClassName(hWnd, sb, sb.Capacity)
    If sb.ToString() <> "#32770" Then Return True
    ''--- Got it, now find the buttons
    mLabelIndex = 0
    EnumChildWindows(hWnd, AddressOf FindButtons, IntPtr.Zero)
    Return False
End Function

Private Shared Function FindButtons(ByVal hWnd As IntPtr, ByVal lp As IntPtr) As Boolean
    Dim sb As New StringBuilder(256)
    GetClassName(hWnd, sb, sb.Capacity)
    If sb.ToString() = "Button" And mLabelIndex <= UBound(mLabels) Then
        ''--- Got one, update text
        SetWindowText(hWnd, mLabels(mLabelIndex))
        mLabelIndex += 1
    End If
    Return True
End Function

''--- P/Invoke declarations
Private Delegate Sub FindWindowDelegate(ByVal tid As Integer)
Private Delegate Function EnumWindowDelegate(ByVal hWnd As IntPtr, ByVal lp As IntPtr) As Boolean
Private Declare Auto Function EnumThreadWindows Lib "user32.dll" (ByVal tid As Integer, ByVal callback As EnumWindowDelegate, ByVal lp As IntPtr) As Boolean
Private Declare Auto Function EnumChildWindows Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal callback As EnumWindowDelegate, ByVal lp As IntPtr) As Boolean
Private Declare Auto Function GetClassName Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal name As StringBuilder, ByVal maxlen As Integer) As Integer
Private Declare Auto Function GetCurrentThreadId Lib "kernel32.dll" () As Integer
Private Declare Auto Function SetWindowText Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal text As String) As Boolean

End Class

现在按以下方式使用该类来显示消息:

MessageClass.PatchMsgBox(New String() {"Button name 1", "Button name 2"})
Dim Result As DialogResult = MsgBox("Message", MsgBoxStyle.OkCancel, "Title")

现在您需要从消息框中处理结果,该消息框将基于您选择的消息框样式。

答案 2 :(得分:0)

我找到了一种方法,这对我来说很好。

我创建了一个新表单,并使其看起来像一个&#34; msgbox&#34;我添加了我需要的东西,如按钮,图片...和其他任何东西,但当我需要显示表格(msgbox)...我使用此代码:

Form1.showDialog()

而不是写:Form1.Show()

你可以让它看起来像一个&#34; msgbox&#34;使用自定义按钮,您无法在其他打开的窗口中执行任何操作来关闭此表单(完全类似于&#34; msgbox&#34;)。

我不知道......我只是发现了这种方式......非常好而且容易。