2

我可以在 MsgBox 中显示自定义按钮吗?我想要与 msgbox 的常规按钮不同的按钮,它们是:

  1. 好的
  2. 取消
  3. 中止
  4. 重试
  5. 忽视
  6. 是的

如何控制这些按钮的文本和值?

4

3 回答 3

3

不,MsgBox 直接绑定到底层 Windows UI,不能轻易更改或扩展。
您应该创建自己的课程或寻找像这样的已经制作的项目

一个多功能的 MessageBox 替代品

好吧,关于这个主题的一些研究让我找到了这篇旧文章和代码

使用 Windows Hooks 增强 .NET 中的 MessageBox

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

于 2013-09-09T13:50:45.163 回答
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")

现在您需要根据您选择的消息框样式处理来自消息框的结果。

于 2013-09-10T06:29:23.750 回答
0

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

我创建了一个新表单,我让它看起来像一个“msgbox”,我添加了我需要的东西,比如按钮、图片......以及其他任何东西,但是当我需要显示表单(msgbox)时......我使用此代码:

Form1.showDialog()

而不是写:Form1.Show()

你可以让它看起来像一个带有自定义按钮的“msgbox”,并且你不能在其他打开的窗口中做任何事情来关闭这个表单(就像一个“msgbox”)。

我不知道...我只是找到了这种方式...非常好且容易。

于 2015-09-19T19:14:54.687 回答