Custom button captions in .NET messagebox?

后端 未结 8 1641
没有蜡笔的小新
没有蜡笔的小新 2020-12-03 05:24

Is there an easy way to display a messagebox in VB.NET with custom button captions? I came across What is an easy way to create a MessageBox with custom button text in

相关标签:
8条回答
  • 2020-12-03 05:29

    No there is no method to access or redirect the Messagebox's default button text.

    The only way to do this is to code your own or just use one of many free ones from the internet:

    Free MsgBoxGo!

    0 讨论(0)
  • 2020-12-03 05:41

    No.
    You'll have to make a custom form with FormBorderType = FixedDialog.
    Here is a little tutorial:

    Creating Dialog Boxes in .NET

    by James D. Murray on Jun.12, 2007, under 70-526

    Microsoft Certification Exam: 70-526 (MCTS)
    Objective: Create and use custom dialog boxes in Windows Forms applications.
    Language: Visual Basic 2005 (click here for the C# version of this entry)

    I remember the first time I needed to create a dialog box in a .NET application that I was writing in C#. Being a long-time Visual Basic programmer, I assumed that this could easily be accomplished by using a dialog box template included with Visual Studio.NET. To my surprise, no such form template existed for C#, although one does for Visual Basic 2005. After wading through several books and Web pages filled with information on Windows Forms 2.0 programming, a basic set of steps became apparent to me for manually converting a .NET form into a Windows dialog box:

    Step 1 : Add a Form to your .NET project and name it “DialogBoxForm”.

    Step 2 : Drop two buttons in the lower right-hand area of the Form and name them “OKButton” and “CancelButton”.

    Step 3 : Change the following properties of the Form to adjust its appearance and behavior to be like a standard dialog box:

        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.
    

    These properties can be set using the Properties window for the form, or using code placed in the Form’s Load event:

        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
    

    Step 4 : Add the following button click event handlers to the Form:

        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
    

    Step 5 : Add properties that you need to move data into and out of the dialog box as you would for any Form:

        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
    

    Step 6 : Show the dialog box modally by calling the ShowDialog() of the form:

        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
    

    Step 7 : To show the dialog box modelessly, call the Show() method of DialogBoxForm instead. You will need to add an event handler to the Close event of DialogBoxForm to know when the user closes the dialog box:

        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
    
    0 讨论(0)
  • 2020-12-03 05:45

    There is a solution. Via installing a CBT hook it is possible to adjust a wide variety of MessageBox visual settings on the fly: message and button fonts, dialog background, dialog positioning, icons, button captions, timeout, even inserting additional controls.

    Complete solution: Extended MessageBox .NET Assembly http://www.news2news.com/vfp/?solution=5

    It is a fully-functional trial version, the regular version includes complete C# source code.

    0 讨论(0)
  • 2020-12-03 05:46

    Here is a C# snippet that uses a Win32 hook to alter the button captions (sourced from 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);
            }
    
    0 讨论(0)
  • 2020-12-03 05:47

    MessageBox uses a plain window that can be messed with like any other window. This has been possible in Windows for a very long time, well over 20 years already. The techniques are getting obscure though, too many friendly class wrappers that hide the native winapi and don't expose everything you can do with it. So much so that programmers now automatically assume that this isn't possible, as you can tell from the upvoted answers. It is the kind of programming that Petzold taught us in his seminal "Programming Windows" book. Replacing MessageBox with a custom Form or Window is actually fairly hard to do, it does non-trivial automatic layout to fit the text and supports localization without help. Although that's exactly what you don't seem to like :)

    Anyhoo, the message box window is easy to find back. It is owned by the UI thread and has a special class name that makes it unique. EnumThreadWindows() enumerates the windows owned by a thread, GetClassName() lets you check the kind of window. Then just poke the text into the button with SetWindowText().

    Add a new class to your project and paste the code shown below. Invoke it with code like this:

    Nobugz.PatchMsgBox(New String() {"Da", "Njet"})
    MsgBox("gack", MsgBoxStyle.YesNo)
    

    Here's the code:

    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
    
    0 讨论(0)
  • 2020-12-03 05:47

    Add this to the button that you want the dialog to be shown from. This is a custom form 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&amp;id=613','asdasd');
                String[] asd = new String[2];
                asd[0] = "groups.php?opt=del&amp;id=613";
                asd[1] = "asdasd";
                addgroup.Document.InvokeScript("del",asd);
            }
            else
                if (m.DialogResult == DialogResult.No)
                {
                    MessageBox.Show("App won´t close");
                }
        }
    

    Add this code to 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();
        }
    
    0 讨论(0)
提交回复
热议问题