문제

사용자 정의 버튼 캡션으로 vb.net에 MessageBox를 쉽게 표시 할 수있는 방법이 있습니까? 나는 만났다 관리 된 C ++에서 사용자 정의 버튼 텍스트로 MessageBox를 만드는 쉬운 방법은 무엇입니까?, 스택 오버플로 아카이브에서는 C ++ 관리.

도움이 되었습니까?

해결책

아니요 MessageBox의 기본 버튼 텍스트에 액세스하거나 리디렉션하는 방법은 없습니다.

이를 수행하는 유일한 방법은 자신의 코드를 코딩하거나 인터넷에서 많은 무료를 사용하는 것입니다.

무료 msgboxgo!

다른 팁

아니.
당신은 맞춤형 양식을 만들어야합니다 FormBorderType = FixedDialog.
다음은 작은 자습서입니다.

.NET에서 대화 상자 생성

2007 년 6 월 12 일, James D. Murray, 70-526 미만

Microsoft 인증 시험 : 70-526 (MCTS)
목표 : Windows Forms 응용 프로그램에서 사용자 정의 대화 상자를 작성하고 사용합니다.
언어 : Visual Basic 2005 (이 항목의 C# 버전을 보려면 여기를 클릭하십시오)

C#에 작성한 .NET 응용 프로그램에서 대화 상자를 처음 만들어야 할 때를 처음 기억합니다. 오랜 시각적 기본 프로그래머이기 때문에 Visual Studio.net에 포함 된 대화 상자 템플릿을 사용하여 쉽게 달성 할 수 있다고 가정했습니다. 놀랍게도 C#에는 그러한 양식 템플릿이 존재하지 않았지만 Visual Basic 2005에 대해서는 그렇지 않았습니다. Windows Forms 2.0 프로그래밍에 대한 정보로 채워진 여러 책과 웹 페이지를 통해 넘어간 후 기본 단계 세트가 수동으로 변환하기 위해 나에게 분명해졌습니다. .NET 양식 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의 닫기 이벤트에 이벤트 핸들러를 추가해야합니다.

    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는 다른 창과 마찬가지로 엉망이 될 수있는 일반 창을 사용합니다. 이것은 이미 20 년이 넘는 시간 동안 창에서 가능했습니다. 그래도 기술은 모호 해지고 있습니다. 기본 Winapi를 숨기고 당신이 할 수있는 모든 것을 노출시키지 않는 너무 많은 친절한 클래스 포장지. 따라서 프로그래머는 이제 Upvoted 답변에서 알 수 있듯이 이것이 가능하지 않다고 자동으로 가정합니다. Petzold가 그의 주요 "프로그래밍 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 Visual 설정을 조정할 수 있습니다.

완전한 해결책 : 확장 된 MessageBox .NET 어셈블리http://www.news2news.com/vfp/?solution=5

완전 기능 시험판이며 일반 버전에는 완전한 C# 소스 코드가 포함되어 있습니다.

C# 코드 동일한 작업을 수행하기위한 C# MSDN Forum의 기사에서 찾을 수 있습니다. 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();
    }

Daniel Nolan의 솔루션, 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

다음은 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);
        }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top