it-swarm.com.de

Benutzerdefinierte Schaltflächenbeschriftungen in der .NET-Nachrichtenbox?

Gibt es eine einfache Möglichkeit, eine Nachrichtenbox in VB.NET mit benutzerdefinierten Schaltflächenbeschriftungen anzuzeigen? Ich bin aufgestoßen. Was ist eine einfache Möglichkeit, eine MessageBox mit benutzerdefiniertem Schaltflächentext in Managed C++ zu erstellen?, in den Stack Overflow-Archiven, aber es ist für Managed C++ .

19
subrama6

Nein, es gibt keine Methode, um auf den Standardschaltflächentext der Messagebox zuzugreifen oder ihn umzuleiten.

Die einzige Möglichkeit, dies zu tun, besteht darin, Ihren eigenen Code zu programmieren oder einfach einen von vielen kostenlosen aus dem Internet zu verwenden:

Kostenlose MsgBoxGo!

8

Nein.
Sie müssen mit FormBorderType = FixedDialog ein benutzerdefiniertes Formular erstellen.
Hier ist ein kleines Tutorial:

Erstellen von Dialogfeldern in .NET

von James D. Murray am 12. Juni 2007, unter 70-526

Microsoft-Zertifizierungsprüfung: 70-526 (MCTS)
Ziel: Erstellen und Verwenden von benutzerdefinierten Dialogfeldern in Windows Forms-Anwendungen.
Sprache: Visual Basic 2005 (klicken Sie hier für die C # -Version dieses Eintrags)

Ich erinnere mich an das erste Mal, dass ich ein Dialogfeld in einer .NET-Anwendung erstellen musste, das ich in C # schrieb. Als langjähriger Visual Basic-Programmierer ging ich davon aus, dass dies leicht mithilfe einer Dialogfeldvorlage in Visual Studio.NET erreicht werden kann. Zu meiner Überraschung gab es keine solche Formularvorlage für C #, obwohl dies für Visual Basic 2005 der Fall ist. Nachdem ich einige Bücher und Webseiten mit Informationen zur Windows Forms 2.0-Programmierung durchgeblättert hatte, wurde mir ein grundlegender Satz von Schritten für die manuelle Konvertierung eines Programms klar .NET-Formular in ein Windows-Dialogfeld:

Schritt 1: Fügen Sie Ihrem .NET-Projekt ein Formular hinzu und nennen Sie es "DialogBoxForm".

Schritt 2: Legen Sie zwei Schaltflächen im rechten unteren Bereich des Formulars ab und nennen Sie sie "OKButton" und "CancelButton".

Schritt 3: Ändern Sie die folgenden Eigenschaften des Formulars, um Aussehen und Verhalten wie ein Standarddialogfeld anzupassen:

 Eigenschaftswert Beschreibung 
 ----------------------------------- -------------------------------------------------- -------------------------------------- 
 AcceptButton-Instanz der OK-Schaltfläche Führt ein Formular aus Rückgabewert DialogResult.OK. Wird nur in modalen Dialogfeldern verwendet. 
 CancelButton-Instanz der Schaltfläche "Cancel" bewirkt, dass das Formular den Wert DialogResult.Cancel zurückgibt. Wird nur in modalen Dialogfeldern verwendet. 
 FormBorderStyle FixedDialog Erstellen Sie ein nicht anpassbares Formular ohne Kontrollkästchen in der Titelleiste. 
 HelpButton True Die Schaltfläche Hilfe wird in der Beschriftungsleiste neben der Schaltfläche Schließen angezeigt. Die ControlBox-Eigenschaft muss "True" sein, damit diese Schaltflächen sichtbar sind. 
 MaximizeBox False Die Maximize-Schaltfläche in der Titelleiste ausblenden. 
 MinimizeBox False Die Minimieren-Schaltfläche in der Titelleiste ausblenden. 
 ShowIcon False Das Titelleistensymbol ist in einem Dialogfeld nicht sichtbar. 
 ShowInTaskBar False Geben Sie nicht das Vorhandensein des Formulars in der Windows-Taskleiste an. 
 Start Position CenterParent Die Anfangsposition eines Dialogfelds ist über dem übergeordneten Formular. 
 Erforderliche Größe Die für das Dialogfeld erforderliche feste Größe. 

Diese Eigenschaften können im Eigenschaftenfenster des Formulars oder mithilfe von Code festgelegt werden, der im Load-Ereignis des Formulars platziert wird:

    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

Schritt 4: Fügen Sie dem Formular die folgende Schaltfläche hinzu, und klicken Sie auf Ereignishandler.

 Private Sub OKButton_Click (ByVal Sender als Objekt, _ByVal eEre EventArgs) 
 'Der Benutzer klickte auf die Schaltfläche OK 
. Me.DialogResult = Windows.Forms.DialogResult.OK [.____. End Sub 
 
 Private Sub CancelButton_Click (Absender als Objekt, _ByVal e als EventArgs) 
 'Benutzer klickte auf die Schaltfläche Abbrechen 
 Me.DialogResult = Windows.Forms .DialogResult.Cancel 
 End Sub 

Schritt 5: Fügen Sie Eigenschaften hinzu, die Sie zum Verschieben von Daten in das Dialogfeld und aus dem Dialogfeld wie für jedes Formular benötigen:

 Private _LoginName As String 
 Private _LoginPassword As String 
 
 Öffentliche Eigenschaft LoginName () As String 
 Rufen Sie 
 Ab. Geben Sie _LoginName 
 End Get 
 Set (ByVal-Wert als String) 
 _LoginName = Wert 
 Ende Set 
 End-Eigenschaft 
 
 Public Eigenschaft LoginPassword () As String 
 Get 
 Rückgabe _LoginPassword 
 Ende Get 
 Set (ByVal-Wert als String) 
 _LoginPassword = Wert 
 End Set 
 End-Eigenschaft 

Schritt 6: Zeigen Sie das Dialogfeld modal an, indem Sie den ShowDialog () des Formulars aufrufen:

 Public Sub ShowDialogBox () 
 Dim-Dialog als neue DialogBoxForm 
 
 Dialog.LoginName = "JDMurray" 
 Dialog.LoginPassword = String.Empty 
 
 Wenn dialog.ShowDialog () = Windows.Forms.DialogResult.OK Dann 
 Debug.WriteLine ("Anmeldename:" & dialog.LoginName) 
 Debug. WriteLine ("Password:" & dialog.LoginPassword) 
 Else 
 'Der Benutzer klickte auf die Schaltfläche Abbrechen 
 End If 
 End Sub 

Schritt 7: Um das Dialogfeld modelllos anzuzeigen, rufen Sie stattdessen die Show () - Methode von DialogBoxForm auf. Sie müssen dem Close-Ereignis von DialogBoxForm einen Ereignishandler hinzufügen, um zu wissen, wann der Benutzer das Dialogfeld schließt:

 Public Sub ShowDialogBox () 
 Dim Dialog As DialogBoxForm = Neue DialogBoxForm 
 Dialog.LoginName = "JDMurray" 
 Dialog.Password = String.Empty 
 AddHandler dialog.FormClosed, AddressOf dialog_FormClosed 
 Dialog.Show () 
 
 'Die Show () - Methode gibt sofort 
 End Sub 
 [Zurück. ____.] Private Sub dialog_FormClosed (ByVal Sender als Objekt, _ 
 
 ByVal e FormClosedEventArgs) 
 'Diese Methode wird aufgerufen, wenn der Benutzer das Dialogfeld schließt 
. End Sub
18
BradC

MessageBox verwendet ein einfaches Fenster, mit dem Sie wie jedes andere Fenster etwas anfangen können. Dies ist in Windows schon seit über 20 Jahren möglich. Die Techniken werden jedoch unübersichtlich, zu viele freundliche Klassenumhüllungen, die das native Winapi verstecken und nicht alles preisgeben, was Sie damit machen können. So sehr, dass Programmierer jetzt automatisch davon ausgehen, dass dies nicht möglich ist, wie Sie an den Antworten erkennen können. Es ist die Art von Programmierung, die Petzold uns in seinem wegweisenden Buch "Programmierfenster" gelehrt hat. Das Ersetzen von MessageBox durch ein benutzerdefiniertes Formular oder ein benutzerdefiniertes Fenster ist ziemlich schwierig. Es wird ein nicht triviales automatisches Layout für den Text erstellt und die Lokalisierung ohne Hilfe unterstützt. Obwohl das genau das ist, was du nicht magst :)

Trotzdem ist das Meldungsfenster leicht wiederzufinden. Es gehört dem UI-Thread und hat einen speziellen Klassennamen, der es einzigartig macht. EnumThreadWindows () listet die Fenster auf, die einem Thread gehören. Mit GetClassName () können Sie die Art des Fensters überprüfen. Dann stecken Sie einfach den Text mit SetWindowText () in die Schaltfläche.

Fügen Sie Ihrem Projekt eine neue Klasse hinzu und fügen Sie den unten gezeigten Code ein. Rufen Sie es mit folgendem Code auf:

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

Hier ist der 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
16
Hans Passant

Es gibt eine Lösung. Über die Installation eines CBT-Hooks können Sie die verschiedensten visuellen MessageBox-Einstellungen im Handumdrehen anpassen: Nachrichten- und Schaltflächenschriftarten, Hintergrund des Dialogs, Position des Dialogfelds, Symbole, Schaltflächenbeschriftungen, Zeitüberschreitung und sogar zusätzliche Steuerelemente.

Komplettlösung: Erweiterte MessageBox .NET Assembly http://www.news2news.com/vfp/?solution=5

Es handelt sich um eine voll funktionsfähige Testversion. Die reguläre Version enthält den vollständigen C # -Quellcode.

2

Die Lösung von Daniel Nolan, Code in 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
Miguel Yskatll

Den gleichen Code finden Sie in einem Artikel im MSDN-Forum unter https://forums.Microsoft.com/MSDN/ShowPost.aspx?PostID=3087899&SiteID=1 .

1
balexandre

Fügen Sie dies der Schaltfläche hinzu, von der aus das Dialogfeld angezeigt werden soll. Dies ist eine benutzerdefinierte Formularbox.

    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");
            }
    }

Fügen Sie diesen Code zu MessageBox hinzu.

    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();
    }
1
Tassaduq

Hier ist ein C # -Schnipsel, der einen Win32-Hook verwendet, um die Beschriftungen der Schaltflächen zu ändern (von 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
Dan Nolan