有没有简单的方法来显示自定义按钮标题的VB.NET中的消息框?我在堆栈溢出存档中遇到了What is an easy way to create a MessageBox with custom button text in Managed C++?,但它是Managed C++。.NET消息框中的自定义按钮标题?
回答
编号
您必须使用FormBorderType = FixedDialog
进行自定义表格。
这里是一个小教程:
在.NET创建对话框
由James D.穆雷在Jun.12,2007年,在70-526
微软认证考试:70 -526(MCTS)
目标:在Windows窗体应用程序中创建和使用自定义对话框。
语言:Visual Basic 2005中(点击这里找到相关的C#版本)
我记得我第一次需要建立在我在C#编写.NET应用程序的对话框。作为一个长期的Visual Basic程序员,我认为这很容易通过使用Visual Studio.NET附带的对话框模板来完成。令我惊讶的是,虽然C#没有这样的表单模板,但是对于Visual Basic 2005来说却是这样。在涉及Windows Forms 2.0编程信息的几本书和网页中浏览完毕后,一系列基本的步骤对于手动转换.NET窗体转换为Windows对话框:
第1步:向.NET项目中添加一个窗体并将其命名为“DialogBoxForm”。
第2步:将两个按钮放在窗体的右下角区域并将它们命名为“OK按钮”和“取消按钮”。
步骤3:更改形式的下列属性来调整其外观和行为要像标准对话框:
Property Value Description ----------------------------------------------------------------------------------------------------------------------------- AcceptButton OK button instance Causes form to return value DialogResult.OK. Only used on modal dialog boxes. CancelButton Cancel button instance Causes form to return value DialogResult.Cancel. Only used on modal dialog boxes. FormBorderStyle FixedDialog Create a non-sizable form with no control box on the title bar. HelpButton True The Help button appears in the caption bar next to the Close button. The ControlBox property must be True for these buttons to be visible. MaximizeBox False Hide the Maximize button in the title bar. MinimizeBox False Hide the Minimize button in the title bar. ShowIcon False The title bar icon is not visible in a dialog box. ShowInTaskBar False Do not indicate the presence of the form on the Windows Task Bar. Start Position CenterParent The initial position of a dialog box is over its parent form. Size As Needed The fixed size needed for the dialog box.
这些属性可以使用属性窗口的形式,或使用设置代码放置在窗体的Load事件:
Me.AcceptButton = OKButton
Me.CancelButton = CancelButton
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedDialog
Me.HelpButton = True
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.ShowInTaskbar = False
Me.ShowIcon = False
Me.StartPosition = FormStartPosition.CenterParent
第4步:下面的按钮单击事件处理程序添加到窗体:
Private Sub OKButton_Click(ByVal sender As Object, _ByVal e As EventArgs) ' User clicked the OK button Me.DialogResult = Windows.Forms.DialogResult.OK End Sub Private Sub CancelButton_Click(ByVal sender As Object, _ByVal e As EventArgs) ' User clicked the Cancel button Me.DialogResult = Windows.Forms.DialogResult.Cancel End Sub
第5步:添加你需要将数据移入和移出的对话框,你会任何形式的性质:
Private _LoginName As String Private _LoginPassword As String Public Property LoginName() As String Get Return _LoginName End Get Set(ByVal value As String) _LoginName = value End Set End Property Public Property LoginPassword() As String Get Return _LoginPassword End Get Set(ByVal value As String) _LoginPassword = value End Set End Property
第6步:通过调用ShowDialog的模态显示的对话框()的形式:
Public Sub ShowDialogBox() Dim dialog As New DialogBoxForm dialog.LoginName = "JDMurray" dialog.LoginPassword = String.Empty If dialog.ShowDialog() = Windows.Forms.DialogResult.OK Then Debug.WriteLine("Login Name: " & dialog.LoginName) Debug.WriteLine("Password: " & dialog.LoginPassword) Else ' User clicked the Cancel button End If End Sub
步骤7:要无模式地显示对话框,请调用DialogBoxForm的Show()方法。您将需要一个事件处理程序添加到DialogBoxForm的关闭事件,当用户关闭对话框知道:
Public Sub ShowDialogBox() Dim dialog As DialogBoxForm = New DialogBoxForm dialog.LoginName = "JDMurray" dialog.Password = String.Empty AddHandler dialog.FormClosed, AddressOf dialog_FormClosed dialog.Show() ' The Show() method returns immediately End Sub Private Sub dialog_FormClosed(ByVal sender As Object, _ ByVal e As FormClosedEventArgs) ' This method is called when the user closes the dialog box End Sub
C#代码来完成同样的事情可以在文章中找到MSDN论坛,https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3087899&SiteID=1。
MessageBox使用一个简单的窗口,可以像任何其他窗口一样搞乱。 Windows已经有很长的一段时间了,已经有20多年了。虽然这些技术变得晦涩难懂,但太多友善的类包装会隐藏本地的winapi,并且不会暴露你可以用它做的一切。如此多的程序员现在会自动假设这是不可能的,正如您从upvoted的答案中可以看出的那样。这是Petzold在其开创性的“Programming Windows”一书中教给我们的一种编程。使用自定义窗体或窗口替换MessageBox实际上很难做到,它可以进行非平凡的自动布局以适应文本并且无需任何帮助即可支持本地化。虽然这正是你似乎不喜欢:)
Anyhoo,消息框窗口很容易找回。它由UI线程拥有,并有一个特殊的类名称,使其具有独特性。 EnumThreadWindows()枚举线程拥有的窗口,GetClassName()让你检查窗口的种类。然后用SetWindowText()将文本戳到按钮上。
向您的项目中添加一个新类并粘贴下面显示的代码。用这样的代码来调用它:
Nobugz.PatchMsgBox(New String() {"Da", "Njet"})
MsgBox("gack", MsgBoxStyle.YesNo)
下面的代码:
Imports System.Text
Imports System.Runtime.InteropServices
Public Class Nobugz
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
有一个解决方案。通过安装CBT挂钩,可以实时调整各种MessageBox可视设置:消息和按钮字体,对话框背景,对话框定位,图标,按钮标题,超时,甚至插入附加控件。
完整的解决方案:扩展的MessageBox .NET程序集 http://www.news2news.com/vfp/?solution=5
这是一个全功能的试用版,普通版包括完整的C#源代码。
将此添加到您希望显示对话框的按钮。 这是一个自定义窗体messageBox;
private void DGroup_Click(object sender, EventArgs e)
{
messageBox m = new messageBox();
m.ShowDialog();
if (m.DialogResult == DialogResult.Yes)
{
//del(groups.php?opt=del&id=613','asdasd');
String[] asd = new String[2];
asd[0] = "groups.php?opt=del&id=613";
asd[1] = "asdasd";
addgroup.Document.InvokeScript("del",asd);
}
else
if (m.DialogResult == DialogResult.No)
{
MessageBox.Show("App won´t close");
}
}
将此代码添加到messageBox。
private void deleteGroupOnly_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Yes;
this.Close();
}
private void deleteAll_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.No;
this.Close();
}
private void cancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
下面是一个使用一个Win32钩以改变按钮标题一个C#代码段(从http://icodesnip.com/snippet/csharp/custom-messagebox-buttons来源):
[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll")]
private static extern bool SetDlgItemText(IntPtr hWnd, int nIDDlgItem, string lpString);
delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
static HookProc dlgHookProc;
private const long WH_CBT = 5;
private const long HCBT_ACTIVATE = 5;
private const int ID_BUT_OK = 1;
private const int ID_BUT_CANCEL = 2;
private const int ID_BUT_ABORT = 3;
private const int ID_BUT_RETRY = 4;
private const int ID_BUT_IGNORE = 5;
private const int ID_BUT_YES = 6;
private const int ID_BUT_NO = 7;
private const string BUT_OK = "Save";
private const string BUT_CANCEL = "Cancel";
private const string BUT_ABORT = "Stop";
private const string BUT_RETRY = "Continue";
private const string BUT_IGNORE = "Ignore";
private const string BUT_YES = "Yeeh";
private const string BUT_NO = "Never";
private static int _hook = 0;
private static int DialogHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
if (nCode == HCBT_ACTIVATE)
{
SetDlgItemText(wParam, ID_BUT_OK, BUT_OK);
SetDlgItemText(wParam, ID_BUT_CANCEL, BUT_CANCEL);
SetDlgItemText(wParam, ID_BUT_ABORT, BUT_ABORT);
SetDlgItemText(wParam, ID_BUT_RETRY, BUT_RETRY);
SetDlgItemText(wParam, ID_BUT_IGNORE, BUT_IGNORE);
SetDlgItemText(wParam, ID_BUT_YES, BUT_YES);
SetDlgItemText(wParam, ID_BUT_NO, BUT_NO);
}
return CallNextHookEx(_hook, nCode, wParam, lParam);
}
private void Button_Click(object sender, EventArgs e)
{
dlgHookProc = new HookProc(DialogHookProc);
_hook = SetWindowsHookEx((int)WH_CBT, dlgHookProc, (IntPtr)0, (int)GetCurrentThreadId());
DialogResult dlgEmptyCheck = MessageBox.Show("Text", "Caption", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3);
if (dlgEmptyCheck == DialogResult.Abort)
{
}
UnhookWindowsHookEx(_hook);
}
由Daniel诺兰的溶液,代码在VB.Net
<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentThreadId() As UInteger
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As HookProc, ByVal hInstance As IntPtr, ByVal threadId As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetDlgItemText(ByVal hWnd As IntPtr, ByVal nIDDlgItem As Integer, ByVal lpString As String) As Boolean
End Function
Private Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Shared dlgHookProc As HookProc
Private Const WH_CBT As Long = 5
Private Const HCBT_ACTIVATE As Long = 5
Private Const ID_BUT_OK As Integer = 1
Private Const ID_BUT_CANCEL As Integer = 2
Private Const ID_BUT_ABORT As Integer = 3
Private Const ID_BUT_RETRY As Integer = 4
Private Const ID_BUT_IGNORE As Integer = 5
Private Const ID_BUT_YES As Integer = 6
Private Const ID_BUT_NO As Integer = 7
Private Const BUT_OK As String = "Save"
Private Const BUT_CANCEL As String = "Cancelar"
Private Const BUT_ABORT As String = "Stop"
Private Const BUT_RETRY As String = "Continue"
Private Const BUT_IGNORE As String = "Ignore"
Private Const BUT_YES As String = "Si"
Private Const BUT_NO As String = "No"
Private Shared _hook As Integer = 0
Private Shared Function DialogHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If nCode < 0 Then
Return CallNextHookEx(_hook, nCode, wParam, lParam)
End If
If nCode = HCBT_ACTIVATE Then
SetDlgItemText(wParam, ID_BUT_OK, BUT_OK)
SetDlgItemText(wParam, ID_BUT_CANCEL, BUT_CANCEL)
SetDlgItemText(wParam, ID_BUT_ABORT, BUT_ABORT)
SetDlgItemText(wParam, ID_BUT_RETRY, BUT_RETRY)
SetDlgItemText(wParam, ID_BUT_IGNORE, BUT_IGNORE)
SetDlgItemText(wParam, ID_BUT_YES, BUT_YES)
SetDlgItemText(wParam, ID_BUT_NO, BUT_NO)
End If
Return CallNextHookEx(_hook, nCode, wParam, lParam)
End Function
Private Sub btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn.Click
dlgHookProc = New HookProc(AddressOf DialogHookProc)
_hook = SetWindowsHookEx(CInt(WH_CBT), dlgHookProc, IntPtr.op_Explicit(0), CInt(GetCurrentThreadId()))
Dim dlgEmptyCheck As DialogResult = MessageBox.Show("Text", "Caption", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button3)
If dlgEmptyCheck = DialogResult.Abort Then
End If
UnhookWindowsHookEx(_hook)
End Sub
- 1. NSIS消息框自定义按钮
- 2. onBeforeUnload自定义按钮的消息
- 3. WPF中的自定义消息框按钮
- 4. VC++中的自定义消息框按钮
- 5. WPF中的自定义标题按钮
- 6. 使用自定义按钮在C#中创建消息框
- 7. 带自定义按钮的ExtJs消息框
- 8. WPF:自定义消息框
- 9. 自定义消息框WPF
- 10. Win32自定义消息框
- 11. JOptionPane消息对话框上的自定义标题
- 12. 只有在Windows Phone 8中确定按钮的自定义消息框
- 13. 自定义全息按钮
- 14. 自定义消息框:Windows'“将光标移动到默认按钮”功能
- 15. 按钮的自定义标题的通用对话框
- 16. iOS自定义按钮标题模糊
- 17. 自定义按钮图标问题
- 18. SharePoint自定义按钮ListViewWebPart标题
- 19. uitabelview自定义按钮标签问题
- 20. 单击r中的操作按钮时的自定义消息
- 21. 便携式消息框按钮/图标?
- 22. 自定义.NET框架生成的异常消息?
- 23. jQuery按钮单击自定义对话框标题
- 24. tabbar问题中的自定义按钮
- 25. 预定义消息Facebook发送按钮
- 26. 如何在.net窗体应用程序的消息框中创建自定义按钮?
- 27. 访问消息框按钮
- 28. 从按钮获取自定义UITableViewCell的自定义标识按
- 29. .net自定义消息框文本突出显示
- 30. c中没有按钮的消息框#
这是我找到的最好的解决方案。非常简单的教程,正是我需要的。 (VB.NET,具体而言,不是C#) – 2011-11-12 00:24:38
现在不可用,但在这里存档http://web.archive.org/web/20101103044008/http://www.techexams。net/blogs/70-526/Creating-dialog-boxes-in-net/ – Urbycoz 2012-07-18 10:18:42