【发布时间】:2013-09-13 00:38:50
【问题描述】:
我可以在 MsgBox 中显示自定义按钮吗?我想要与 msgbox 的常规按钮不同的按钮:
- 好的
- 取消
- 中止
- 重试
- 忽略
- 是的
- 没有
如何控制这些按钮的文本和值?
【问题讨论】:
我可以在 MsgBox 中显示自定义按钮吗?我想要与 msgbox 的常规按钮不同的按钮:
如何控制这些按钮的文本和值?
【问题讨论】:
不,MsgBox 直接绑定到底层 Windows UI,不能轻易更改或扩展。
您应该创建自己的课程或寻找类似这样的已制作项目
A versatile MessageBox replacement
嗯,对这个主题的一些研究让我找到了这篇旧文章和代码
Using Windows Hooks to Enhance MessageBox in .NET
但工作量很大,也许您可以更好地利用您的时间来构建您自己的消息类。
【讨论】:
您可以修改消息框,但会有一些限制。按钮的最大数量为 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")
现在您需要根据您选择的消息框样式处理来自消息框的结果。
【讨论】:
我找到了一种方法,对我来说效果很好。
我创建了一个新表单,我让它看起来像一个“msgbox”,我添加了我需要的东西,比如按钮、图片......以及其他任何东西,但是当我需要显示表单时(msgbox)。 .. 我用这个代码:
Form1.showDialog()
而不是写:Form1.Show()
你可以让它看起来像一个带有自定义按钮的“msgbox”,并且你不能在其他打开的窗口中做任何事情来关闭这个表单(就像一个“msgbox”)。
我不知道...我只是找到了这种方式...非常好且容易。
【讨论】: