Abfrage des Textes von MessageBoxButtons

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von volti.

    Abfrage des Textes von MessageBoxButtons

    Moin Leute,
    zur Lokalisierung eines Programms würde ich bei einer YesNoCancel-MessageBox den Text, der auf den Buttons steht, beim MessabeBox-Text direkt einbauen:

    Quellcode

    1. result = MessageBox.Show(" ...
    2. Yes - tue dies
    3. No - tue jenes
    4. Cancel - tue noch was anderes",
    5. "Titel", MessageBoxButtons.YesNoCancel)
    Also "Yes" durch "Ja", "No" durch "Nein" usw. ersetzen.
    Bei einer vom Programm nicht unterstützten Sprache kommt bei mir per Default englisch, nur auf der MessageBox steht die Beschriftung in einer anderen Sprache.
    Gibt es da eine Möglichkeit der Abfrage dieser Strings in den lokalen Language-Settings?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe gerade fix im dotnet Quellcode geschaut, ob da was ist. Ich hätte jetzt nämlich fuchsigerweise erwartet, dass die eine Überladung von ToString() für die jeweiligen Typen haben.
    Gefunden habe ich jedoch auf die Schnelle nichts.

    Vielleicht ist es ja drin.
    Ich gehe mal stark davon aus, dass dein System auf Deutsch ist. Was kommt denn raus, wenn du MessageBoxButtons.YesNoCancel.ToString() aufrufst? Wäre ja ein ganz banaler Versuch.

    Evtl. kann ja auch der @loeffel was dazu sagen?
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)

    siycah schrieb:

    Was kommt denn raus, wenn du MessageBoxButtons.YesNoCancel.ToString() aufrufst?
    Nicht das erwartete:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich hab hier noch was gefunden: vbforums.com/showthread.php?66…-not-using-SystemLanguage

    Scheint wohl gar nicht so trivial zu sein, aber evtl. kannst du damit was anfangen?
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    @RodFromGermany Wäre das nicht was für die API TaskDialogIndirect -> learn.microsoft.com/en-us/wind…mmctrl-taskdialogindirect Soweit ich weis ist der TaskDialog ab NET5 OnBoard. Hier kannst Du auf dem Dialog die Standard-Buttons & Beschriftung für Yes, No usw oder Custom-Buttons mit eigenem Text anzeigen lassen. Also anstatt zu versuchen den Buttontext auszulesen, den Buttontext selbst vorgegeben.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Hallo,

    die Messagebox mit anderen Buttontexten zu versehen oder ein anderes Icon dort anzeigen zu lassen ist mit ein paar API-Befehlen schnell gemacht.

    Hier mal ein Minimalbeispiel dazu, allerdings für VBA. Weiter unten noch ein Link, der aufzeigt, wie man auch vier Button in einer MsgBox platzieren kann (allerdings auch VBA).

    VB.NET-Quellcode

    1. Private Declare PtrSafe Function SetDlgItemTextA Lib "user32" ( _
    2. ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long, ByVal lpString As String) As Long
    3. Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
    4. Private Declare PtrSafe Function MessageBoxA Lib "user32" ( _
    5. ByVal hwnd As LongPtr, ByVal lpText As String, ByVal lpCaption As String, _
    6. ByVal wType As Long) As Long
    7. Private Declare PtrSafe Function SetWindowsHookExA Lib "user32" ( _
    8. ByVal idHook As Long, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, _
    9. ByVal dwThreadId As Long) As LongPtr
    10. Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" ( _
    11. ByVal hHook As LongPtr) As Long
    12. Dim hHook As LongPtr
    13. Dim giDlgStyle As Long
    14. Dim sBtns() As String
    15. Function MsgBoxHookProc(ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    16. ' Funktion versieht die Buttons mit neuen Texten
    17. Dim iBtn As Integer
    18. If uMsg = 5 Then
    19. For iBtn = 1 To 5: SetDlgItemTextA wParam, iBtn, sBtns(iBtn): Next iBtn
    20. UnhookWindowsHookEx hHook
    21. End If
    22. End Function
    23. Function MsgboxEx(sMsgTxt As String, _
    24. Optional ByVal iDlgStyle As Long, _
    25. Optional sCaption As String = "Micosoft Excel", _
    26. Optional sButtons As String = "OK") As String
    27. ' Funktion gibt den Text zum gedrückten Button zurück
    28. sBtns = Split("," & sButtons & ",,,,", ",")
    29. sBtns(5) = sBtns(3): sBtns(3) = sBtns(1): sBtns(4) = sBtns(2)
    30. giDlgStyle = (iDlgStyle And &HFFFF8) Or (UBound(sBtns) - 5)
    31. hHook = SetWindowsHookExA(5, AddressOf MsgBoxHookProc, 0&, GetCurrentThreadId())
    32. MsgboxEx = Replace(sBtns(MessageBoxA(Application.hwnd, _
    33. Replace(sMsgTxt, "¶", vbLf), sCaption, giDlgStyle)), "&", "")
    34. End Function
    35. Sub MeinMsgBoxTest1()
    36. MsgBox MsgboxEx("Habe die Datei nicht gefunden,¶Mail trotzdem absenden?", _
    37. vbCritical Or vbMsgBoxSetForeground, "Mailversand", "&Senden,&Mailen,A&bbrechen")
    38. End Sub


    clever-excel-forum.de/Thread-M…r-Button-und-eigenem-Icon


    Gruß
    Karl-Heinz
    MB_GetString?

    C#-Quellcode

    1. public partial class Form1 : Form {
    2. public Form1() {
    3. InitializeComponent();
    4. }
    5. private void button1_Click(object sender, EventArgs e) {
    6. MessageBox.Show("My local 'Yes' text is: " + WinApi.MbGetString(WinApi.WButton.Amp_Yes));
    7. }
    8. }
    9. public static class WinApi {
    10. [DllImport("user32.dll", EntryPoint = "MB_GetString")]
    11. private static extern IntPtr InternalMbGetString(WButton wBtn);
    12. public static string MbGetString(WButton wBtn) {
    13. return Marshal.PtrToStringAuto(WinApi.InternalMbGetString(wBtn));
    14. }
    15. public enum WButton {
    16. OK,
    17. Cancel,
    18. Amp_Abort,
    19. Amp_Retry,
    20. Amp_Ignore,
    21. Amp_Yes,
    22. Amp_No,
    23. Amp_Close,
    24. Help,
    25. Amp_TryAgain,
    26. Amp_Continue,
    27. }
    28. }


    Die mit Amp_ haben ein & Zeichen am Anfang, weiß nicht wieso. Hotkey?

    Bluespide schrieb:

    Die mit Amp_ haben ein & Zeichen am Anfang, weiß nicht wieso. Hotkey?
    Jupp, damit wird der Buchstabe unterstrichen angezeigt der dann per Tastatur mit ALT + Buchstabe ausgeführt werden kann.
    Mfg -Franky-

    Bluespide schrieb:

    Die mit Amp_ haben ein & Zeichen am Anfang, weiß nicht wieso. Hotkey?
    sofern dieser Text als Text auf einem Botton erscheint.
    Jou, genau das war es. :thumbup:

    Fehlt noch der Test an fremdsprachigen Rechnern.
    ====
    Merkwürdigerweise knallt es, wenn EntryPoint = "MB_GetString" weggelassen wird.
    ====
    @volti Angesichts der eleganten Lösung von Bluespide ist die VBA-Lösung doch etwas oversized. Trotzdem Danke.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    -Franky- schrieb:

    Interesse an einem TaskDialog
    Klar, Interesse habe ich. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RedFromGermany,

    vielen Dank für Deine Rückmeldung.

    Es sollte auch nur eine Beispielaufzeigung sein, was wie möglich wäre.
    In Excel, Word usw. und meiner alten Programmiersprache PowerBasic wird Basic verwendet, wobei aber hier ja hauptsächlich die API aufgerufen wird.

    Ob ich die o.a. C#-Variante auch nach VBA portieren kann, müsste ich mal probieren. :)

    Gruß aus Hessen
    KH

    volti schrieb:

    Ob ich die o.a. C#-Variante auch nach VBA portieren kann, müsste ich mal probieren.
    Klar kannst Du das, ist ja eine ganz normale API: learn.microsoft.com/en-us/windows/win32/dlgbox/mb-getstring Die ganzen Dialog Box Command IDs findest Du auch in der winuser.h. Die API gibt Dir einen Pointer auf den String zurück.
    Auf die schnelle für VB6

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private Enum DialogBoxCommandIDs
    3. IDOK = 1
    4. IDCANCEL = 2
    5. IDABORT = 3
    6. IDRETRY = 4
    7. IDIGNORE = 5
    8. IDYES = 6
    9. IDNO = 7
    10. IDCLOSE = 8
    11. IDHELP = 9
    12. IDTRYAGAIN = 10
    13. IDCONTINUE = 11
    14. End Enum
    15. ' ----==== User32.dll Declarations ====----
    16. Private Declare Function MB_GetString Lib "User32.dll" ( _
    17. ByVal wBtn As DialogBoxCommandIDs) As Long
    18. ' ----==== Kernel32.dll Declarations ====----
    19. Private Declare Sub CopyMemory Lib "kernel32.dll" _
    20. Alias "RtlMoveMemory" ( _
    21. ByRef pTo As Any, _
    22. ByRef uFrom As Any, _
    23. ByVal lSize As Long)
    24. Private Declare Function lstrlenW Lib "kernel32.dll" ( _
    25. ByVal lpString As Long) As Long
    26. Private Sub Command1_Click()
    27. Debug.Print GetDialogBoxButtonText(IDABORT)
    28. End Sub
    29. Private Function GetDialogBoxButtonText(ByVal CommandID As DialogBoxCommandIDs) As String
    30. GetDialogBoxButtonText = Ptr2Str(MB_GetString(CommandID - 1))
    31. End Function
    32. Private Function Ptr2Str(ByVal lpStr As Long) As String
    33. If lpStr <> 0& Then
    34. Dim lngLen As Long
    35. Dim bytBuffer() As Byte
    36. lngLen = lstrlenW(lpStr) * 2
    37. If lngLen > 0 Then
    38. ReDim bytBuffer(lngLen - 1)
    39. Call CopyMemory(bytBuffer(0), ByVal lpStr, lngLen)
    40. Ptr2Str = bytBuffer
    41. End If
    42. End If
    43. End Function
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Super, danke Franky,

    für das Beispiel... Werde mich mal damit beschäftigen.

    Für die API-Funktionen, Konstanten, Office-Funktionen usw. habe ich mir einen API-Viewer gebastelt, der auch weit mehr Funktionen enthält als die Windows64API_Declares.txt beinhaltet.
    clever-excel-forum.de/Thread-API-Viewer

    Bis auf die MB_GetString, sind mir alle verwendeten Funktionen und Konstanten bekannt. Die MB_GetString ist auch noch nicht in meinem API-Viewer, werde ich noch aufnehmen. :)

    Tja, man lernt nie aus....

    Gruß KH

    Nachtrag: Ich bin mit 64-Bit unterwegs, da muss dann noch einiges angepasst werden.....

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „volti“ ()