سؤال

هل هناك طريقة سهلة لعرض مراسلة الرسائل في vb.net مع توضيحيات زر مخصصة؟ جئت عبر ما هي الطريقة السهلة لإنشاء مراسلة الرسائل مع نص زر مخصص في C ++ المدارة؟, ، في أرشيفات الفائض في المكدس ، لكنها من أجل تدار C ++.

هل كانت مفيدة؟

المحلول

لا ، لا توجد طريقة للوصول إلى نص الزر الافتراضي الخاص بـ MessageBox أو إعادة توجيهه.

الطريقة الوحيدة للقيام بذلك هي ترميز خاص بك أو مجرد استخدام واحدة من العديد من المجاني من الإنترنت:

msgboxgo المجاني!

نصائح أخرى

رقم.
سيكون عليك صنع شكل مخصص مع FormBorderType = FixedDialog.
هنا تعليمي صغير:

إنشاء مربعات الحوار في .NET

بقلم جيمس د. موراي في 12 يونيو 2007 ، تحت 70-526

امتحان شهادة Microsoft: 70-526 (MCTS)
الهدف: إنشاء واستخدام مربعات الحوار المخصصة في تطبيقات Windows Forms.
اللغة: Visual Basic 2005 (انقر هنا للحصول على إصدار C# من هذا الإدخال)

أتذكر المرة الأولى التي احتاجها لإنشاء مربع حوار في تطبيق .NET الذي كنت أكتبه في C#. نظرًا لكوني مبرمجًا Visual Basic منذ فترة طويلة ، فقد افترضت أنه يمكن تحقيق ذلك بسهولة باستخدام قالب مربع الحوار المدرج في Visual Studio.net. لدهشتي ، لم يكن هناك مثل هذا قالب النموذج من أجل C#، على الرغم من أن المرء يفعل في Visual Basic 2005. بعد الخوض في العديد من الكتب وصفحات الويب المملوءة بالمعلومات عن برمجة Windows Forms 2.0 ، أصبحت مجموعة أساسية من الخطوات واضحة بالنسبة لي لتحويل أدو. .NET Form في مربع حوار Windows:

الخطوة 1: أضف نموذجًا إلى مشروع .NET الخاص بك وتسميته "DialogBoxForm".

الخطوة 2: إسقاط زرين في المنطقة اليمنى السفلية للنموذج وتسميتهما "Okbutton" و "CancelButton".

الخطوة 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.

يمكن تعيين هذه الخصائص باستخدام نافذة الخصائص للنموذج ، أو باستخدام التعليمات البرمجية الموضوعة في حدث تحميل النموذج:

    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: لإظهار مربع الحوار بلا تعديل ، اتصل بالطريقة show () لـ DialogBoxForm بدلاً من ذلك. ستحتاج إلى إضافة معالج الأحداث إلى الحدث الإغلاق لـ 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

يستخدم MessageBox نافذة عادية يمكن إفسادها مع أي نافذة أخرى. لقد كان هذا ممكنًا في Windows لفترة طويلة جدًا ، أكثر من 20 عامًا بالفعل. أصبحت التقنيات غامضة على الرغم من أن الكثير من الأغلفة الصفية الودية التي تخفي Winapi الأصلي ولا تكشف كل ما يمكنك فعله به. لدرجة أن المبرمجين الآن يفترضون تلقائيًا أن هذا غير ممكن ، حيث يمكنك معرفة الإجابات المصحوبة. إنه نوع البرمجة التي علمناها Petzold في كتابه "Windows" Seminal "Windows". من الصعب في الواقع استبدال MessageBox بنموذج أو نافذة مخصصة ، إنه يقوم بتخطيط أوتوماتيكي غير تافهة لتناسب النص ويدعم التوطين دون مساعدة. على الرغم من أن هذا بالضبط ما لا يبدو أنك تحب :)

Anyhoo ، من السهل العثور على نافذة مربع الرسالة. وهي مملوكة لخيط واجهة المستخدم وله اسم فئة خاص يجعله فريدًا. يعدد 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 الموسعة .NEThttp://www.news2news.com/vfp/؟solution=5

إنه إصدار تجريبي كامل الوظائف ، يتضمن الإصدار العادي رمز المصدر C# الكامل.

يمكن العثور على رمز C# لإنجاز نفس الشيء في مقال تحت منتدى MSDN ، https://forums.microsoft.com/msdn/showpost.aspx؟postid=3087899&siteid=1.

أضف هذا إلى الزر الذي تريد عرض مربع الحوار منه. هذا هو صندوق رسالة نموذج مخصص ؛

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

أضف هذا الرمز إلى 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();
    }

حل دانييل نولان ، رمز في 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

فيما يلي مقتطف C# الذي يستخدم خطاف Win32 لتغيير التسميات التوضيحية للزر (مصادر من 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);
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top