MsgBox auf englisch

  • Hallo,

    ich schreibe grade ein Programm mit einer englischsprachigen Oberfläche. Nun sollen ja auch die MsgBoxen auf englisch sein.
    Der Text ist ja kein Thema aber kann man auch die Buttons irgendwie ändern? Ansonsten muss ich wohl die Box selber machen.

  • Messageboxes sind soweit ich weiß immer an die OS Sprache angepasst. Ich bin mir relativ sicher, dass es keinen direkten Weg gibt, die MsgBox mit anderen Buttontexten zu erstellen. Es gibt aber die möglichkeit das nach der Erstellung noch zu beeinflussen.
    Das beste Beispiel dafür findet sich wohl hier: https://autoit.de/index.php?page=Thread&postID=206764. Schau dir mal die ganzen Scripts in diesem Thread an, das sollte im Prinzip das sein was du suchst.

  • Hey,
    ich glaube du hast bei deinen Überlegungen eine Tatsache nicht bedacht: Wenn ein Benutzer dein Programm auf Englisch, statt auf Deutsch benutzt, dann wird er seine in Windows eingestellte Sprache ja wohl oder übel nicht auf Deutsch haben oder? :D Die Beschriftung der Buttons wird von Windows selbst übernommen, das kannst du auch selbst überprüfen, wenn du deine Systemsprache auf englisch stellst... ;)
    LG
    Christoph
    Edit:
    name22 war schneller... :D
    Aber warum die Sprache der Buttons anpassen wenn der Benutzer die Sprache in seinem OS doch selbst eingestellt hat???! :P

    LG
    Christoph :)

  • Weil nur diese Anwenung auf Englisch sein soll. Mir ist schon klar, dass ich das OS umstellen kann. Evtl. soll man auch später die Sprache ändern können, würdest du deswegen immer das OS umstellen? Dann sind die anderen Programme auch in der Sprache, jedenfalls die Controls, welche die Sprache von Windows beziehen.

    Mit ControlSetText wollte ich es ja auch machen, nur mir ist noch nicht eingefallen wie, da ja das Script bei der Box pausiert, außer halt die Timer-Geschichten.

  • Ohne diese Timer wirst du das aber kaum hinkriegen. Wo liegt denn das Problem die zu benutzen? So funktioniert das ganze doch prima. Ist doch genau was du wolltest...

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>
    #include <Timers.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sTitle = "MsgBox Test"
    $iCountTime = 5000
    $fCheck = False
    $hMsgBoxHandleTmp = 0

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd_Parent = WinGetHandle(AutoItWinGetTitle())

    [/autoit] [autoit][/autoit] [autoit]

    _Timer_SetTimer($hWnd_Parent, 20, '_MsgBox_SetButtonText')
    MsgBox(64, $sTitle, "Test!", Default, $hWnd_Parent)
    _Timer_KillAllTimers($hWnd_Parent)

    [/autoit] [autoit][/autoit] [autoit]

    Func _MsgBox_SetButtonText($hWnd, $Msg, $iIDTimer, $dwTime)
    If $hMsgBoxHandleTmp <> 0 Then Return
    $hMsgBoxHandleTmp = _MsgBox_GetHandle($sTitle, $hWnd_Parent)
    ControlSetText($hMsgBoxHandleTmp, "", "[CLASS:Button; INSTANCE:1]", "AutoIt")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _MsgBox_GetHandle($sTitle, $hWnd_Parent)
    $aWinList = WinList("[CLASS:#32770;TITLE:" & $sTitle & "]")
    For $i = 1 To $aWinList[0][0]
    If _WinAPI_GetParent($aWinList[$i][1]) = $hWnd_Parent Then Return $aWinList[$i][1]
    Next
    Return 0
    EndFunc

    [/autoit]
  • Hab es nicht fertig ausprogrammiert, aber hier mal ein gangbarer Weg, um von deutsch nach englisch zu kommen:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Local $hProcMsgBox = DllCallbackRegister("CbtHookProcMsgBox", "int", "int;int;int")
    Local $TIDMsgBox = _WinAPI_GetCurrentThreadId()
    Local $hHookMsgBox = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hProcMsgBox), 0, $TIDMsgBox)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iRet = MsgBox(34, "Select example", "Please select the skin you want to try")

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_UnhookWindowsHookEx($hHookMsgBox)
    DllCallbackFree($hProcMsgBox)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Just for fun!!
    ;##########################################################
    Func CbtHookProcMsgBox($nCode, $wParam, $lParam)
    Local $RET = 0, $hBitmap = 0, $xWnd = 0
    Local $sButtonText
    If $nCode < 0 Then
    $RET = _WinAPI_CallNextHookEx($hHookMsgBox, $nCode, $wParam, $lParam)
    Return $RET
    EndIf
    Switch $nCode
    Case 5 ;5=HCBT_ACTIVATE
    For $i = 3 To 5
    $sButtonText = _WinAPI_GetDlgItemText($wParam, $i)
    Switch $sButtonText
    Case "A&bbrechen"
    _WinAPI_SetDlgItemText($wParam, $i, "Abort")
    Case "Wieder&holen"
    _WinAPI_SetDlgItemText($wParam, $i, "Retry")
    Case "&Ignorieren"
    _WinAPI_SetDlgItemText($wParam, $i, "Ignore")
    EndSwitch
    Next
    EndSwitch
    Return
    EndFunc ;==>CbtHookProcMsgBox

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString)
    Local $aRet = DllCall('user32.dll', "int", "SetDlgItemText", _
    "hwnd", $hDlg, _
    "int", $nIDDlgItem, _
    "str", $lpString)
    Return $aRet[0]
    EndFunc ;==>_WinAPI_SetDlgItemText

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_GetDlgItemText($hDlg, $nIDDlgItem)
    Local $aRet = DllCall('user32.dll', "int", "GetDlgItemText", _
    "hwnd", $hDlg, _
    "int", $nIDDlgItem, _
    "str", "", _
    "int", 50)
    Return $aRet[3]
    EndFunc ;==>_WinAPI_GetDlgItemText

    [/autoit] [autoit][/autoit] [autoit]

    ;##########################################################
    #endregion Just for fun!!

    [/autoit]
  • Also schonmal echt super name22 und funkey. Nur bei dem von funkey kann ich es mit dem X nicht schliessen. Ansonsten würde ich das doch gleich nehmen :thumbup:

  • Die UDF ist super (is ja schließlich von Progandy), nur der Parameter $hwndThreadOwner funktioniert nicht, das Parent-Fenster ist nicht inaktiv wie bei der echten MsgBox. Aber wieso ist die UDF so umständlich als der Vorschlag von funkey?

  • Also schonmal echt super name22 und funkey. Nur bei dem von funkey kann ich es mit dem X nicht schliessen. Ansonsten würde ich das doch gleich nehmen :thumbup:


    Dass man die MsgBox nicht schließen kann, liegt doch nur am Flag!!!
    Bedenke aber, mit meiner Methode musst du alle Strings für alle möglichen Sprachen im Skript mit einschließen, sonst funktioniert es auf z.B. einem brasilianischen WinXP nicht. Wenn du aber das Flag selber abfragst und dementsprechend weißt, was in den Buttons stehen soll, dann kannst du natürlich das Skript universaler gestalten.

  • Wie ist das nun mit dem HWND. Wenn ich als Parent die Gui nehme, funktioniert es ja trotzdem nicht. Welches Flag ist denn das?

  • :rolleyes: Ich dachte du kommst selber drauf! Das hat mit dem Handle aber nichts zu tun!

    Spoiler anzeigen
    [autoit]

    MsgBox(1, "", "Die Buttons sind 'OK und Abbrechen'" & @CRLF & "Diese MsgBox kann ich über 'X' schließen")
    MsgBox(2, "", "Die Buttons sind 'Abbrechen , Wiederholen und Ignorieren'" & @CRLF & "Diese MsgBox kann ich nicht über 'X' schließen")
    MsgBox(3, "", "Die Buttons sind 'Ja, Nein und Abbrechen'" & @CRLF & "Diese MsgBox kann ich über 'X' schließen")
    MsgBox(4, "", "Die Buttons sind 'Ja und Nein'" & @CRLF & "Diese MsgBox kann ich nicht über 'X' schließen")
    MsgBox(5, "", "Die Buttons sind 'Wiederholen und Abbrechen'" & @CRLF & "Diese MsgBox kann ich über 'X' schließen")
    MsgBox(6, "", "Die Buttons sind 'Abbrechen , Wiederholen und Weiter'" & @CRLF & "Diese MsgBox kann ich über 'X' schließen")

    [/autoit]
  • Ähm und was ist mit dem letzten Parameter. Mit einer normalen MsgBox klappt es doch, nur nicht mit der UDF.

  • Ich versteh dich nicht. Der letzte Parameter hat doch einen ganz anderen Grund!

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $hGui = GUICreate("Test", 500, 500, 700, 100)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    Local $hProcMsgBox = DllCallbackRegister("CbtHookProcMsgBox", "int", "int;int;int")
    Local $TIDMsgBox = _WinAPI_GetCurrentThreadId()
    Local $hHookMsgBox = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hProcMsgBox), 0, $TIDMsgBox)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iRet = MsgBox(2, "Can't close with 'X'", "But you can activate the GUI")
    Local $iRet = MsgBox(6, "Can close with 'X'", "And you can activate the GUI")
    Local $iRet = MsgBox(6, "Can close with 'X'", "And you can NOT activate the GUI", 0, $hGui)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_UnhookWindowsHookEx($hHookMsgBox)
    DllCallbackFree($hProcMsgBox)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Just for fun!!
    ;##########################################################
    Func CbtHookProcMsgBox($nCode, $wParam, $lParam)
    Local $RET = 0, $hBitmap = 0, $xWnd = 0
    Local $sButtonText
    If $nCode < 0 Then
    $RET = _WinAPI_CallNextHookEx($hHookMsgBox, $nCode, $wParam, $lParam)
    Return $RET
    EndIf
    Switch $nCode
    Case 5 ;5=HCBT_ACTIVATE
    For $i = 3 To 5
    $sButtonText = _WinAPI_GetDlgItemText($wParam, $i)
    Switch $sButtonText
    Case "A&bbrechen"
    _WinAPI_SetDlgItemText($wParam, $i, "Abort")
    Case "Wieder&holen"
    _WinAPI_SetDlgItemText($wParam, $i, "Retry")
    Case "&Ignorieren"
    _WinAPI_SetDlgItemText($wParam, $i, "Ignore")
    EndSwitch
    Next
    EndSwitch
    Return
    EndFunc ;==>CbtHookProcMsgBox

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString)
    Local $aRet = DllCall('user32.dll', "int", "SetDlgItemText", _
    "hwnd", $hDlg, _
    "int", $nIDDlgItem, _
    "str", $lpString)
    Return $aRet[0]
    EndFunc ;==>_WinAPI_SetDlgItemText

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_GetDlgItemText($hDlg, $nIDDlgItem)
    Local $aRet = DllCall('user32.dll', "int", "GetDlgItemText", _
    "hwnd", $hDlg, _
    "int", $nIDDlgItem, _
    "str", "", _
    "int", 50)
    Return $aRet[3]
    EndFunc ;==>_WinAPI_GetDlgItemText

    [/autoit] [autoit][/autoit] [autoit]

    ;##########################################################
    #endregion Just for fun!!

    [/autoit]
  • Welchen grund denn sonst. Wenn dort das Handle drin steht von der Gui, von wo es aufgerufen wird, ist die Gui solange inaktiv und verarbeitet keine Eingaben, solange die MsgBox geöffnet ist. Es hat doch vorher funktioniert mit dem Standardaufruf.

  • Da ich immer noch nicht weiß, was bei dir nicht funktioniert, hab ich die Funktion nun universal einsetzbar gemacht. War eh leichter als ich dachte:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hHookMsgBox

    [/autoit] [autoit][/autoit] [autoit]

    _MsgBoxEnglish(0, "Title", "Text")
    _MsgBoxEnglish(1, "Title", "Text")
    _MsgBoxEnglish(2, "Title", "Text")
    _MsgBoxEnglish(3, "Title", "Text")
    _MsgBoxEnglish(4, "Title", "Text")
    _MsgBoxEnglish(5, "Title", "Text")
    _MsgBoxEnglish(6, "Title", "Text")
    _MsgBoxEnglish(7, "Title", "Text")

    [/autoit] [autoit][/autoit] [autoit]

    #region English Button text for MsgBox!!
    ;##########################################################
    Func _MsgBoxEnglish($flag, $title, $text, $timeout = 0, $hwnd = 0)
    Local $hProcMsgBox = DllCallbackRegister("CbtHookProcMsgBox", "int", "int;int;int")
    Local $TIDMsgBox = _WinAPI_GetCurrentThreadId()
    $hHookMsgBox = _WinAPI_SetWindowsHookEx($WH_CBT, DllCallbackGetPtr($hProcMsgBox), 0, $TIDMsgBox)

    [/autoit] [autoit][/autoit] [autoit]

    Local $iRet = MsgBox($flag, $title, $text, $timeout, $hwnd)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_UnhookWindowsHookEx($hHookMsgBox)
    DllCallbackFree($hProcMsgBox)
    Return $iRet
    EndFunc ;==>_MsgBoxEnglish

    [/autoit] [autoit][/autoit] [autoit]

    Func CbtHookProcMsgBox($nCode, $wParam, $lParam, $hHookMsgBox)
    Local $RET = 0, $hBitmap = 0, $xWnd = 0
    Local $sButtonText
    If $nCode < 0 Then
    $RET = _WinAPI_CallNextHookEx($hHookMsgBox, $nCode, $wParam, $lParam)
    Return $RET
    EndIf
    Switch $nCode
    Case 5 ;5=HCBT_ACTIVATE
    _WinAPI_SetDlgItemText($wParam, 1, "OK")
    _WinAPI_SetDlgItemText($wParam, 2, "Cancel")
    _WinAPI_SetDlgItemText($wParam, 3, "&Abort")
    _WinAPI_SetDlgItemText($wParam, 4, "&Retry")
    _WinAPI_SetDlgItemText($wParam, 5, "&Ignore")
    _WinAPI_SetDlgItemText($wParam, 6, "&Yes")
    _WinAPI_SetDlgItemText($wParam, 7, "&No")
    _WinAPI_SetDlgItemText($wParam, 8, "Help")
    _WinAPI_SetDlgItemText($wParam, 10, "&Try Again")
    _WinAPI_SetDlgItemText($wParam, 11, "&Continue")
    EndSwitch
    Return
    EndFunc ;==>CbtHookProcMsgBox

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_SetDlgItemText($hDlg, $nIDDlgItem, $lpString)
    Local $aRet = DllCall('user32.dll', "int", "SetDlgItemText", _
    "hwnd", $hDlg, _
    "int", $nIDDlgItem, _
    "str", $lpString)
    Return $aRet[0]
    EndFunc ;==>_WinAPI_SetDlgItemText
    ;##########################################################
    #endregion English Button text for MsgBox!!

    [/autoit]
  • Es ging mir um den letzten Parameter $hWndThreadOwner. Ich hab erstmal den Parameter einfach übernommen in den MsgBox Aufruf am Ende der Funktion. Du funktioniert es erstmal.