Die Standard Message-Box unter VB, die man über die Funktion
MsgBox aufrufen kann, um dem Benutzer etwas mitzuteilen
oder ihn etwas zu fragen lassen manchmal etwas zu wünschen übrig. So stehen
nur 6 verschiedene Schaltflächenbeschriftungen zur Verfügung auf die man jedoch
keinen Einfluss hat: Ja, Nein, OK, Abbrechen, Wiederholen und Ignorieren, was
diese Funktion nicht gerade sehr flexibel macht. In dem meisten Fällen genügt
das auch, aber eben nur in den meisten. Will man dem Benutzer andere Optionen
bieten, muss ein eigenes Formular ran.
Meine Intention bei der Programmierung dieses Codes war, eine Message-Box
zu bauen, die genauso aussieht wie das Original und sich ebenso verhält, aber
eben mit frei definierbaren Schaltflächenbeschriftungen.

Die Form ist schnell erstellt. Man benötigt nur drei Schalflächen, ein Label-Element,
in Image-Element, sowie eine Image-List, in der die vier möglichen Bilder für
die Symbole "Frage", "Information", "Hinweis" und "kritischer Hinweis" abgelegt
sind. Die Form erhält zudem folgende Eigenschaften:
- Property Let Title (Titel der Form)
- Property Let Message (anzuzeigende Nachricht)
- Property Let Symbol (Long-Wert des anzuzeigenden Symbols)
- Property Let DefaultButton (welche Schaltfläche erhält den Focus)
- Property Let Button1 (Beschriftung der ersten Schaltfläche)
- Property Let Button1 (Beschriftung der zweiten Schaltfläche)
- Property Let Button1 (Beschriftung der dritten Schaltfläche)
Um während der Programmierung einer Anwendung sich nicht um die Form kümmern
zu müssen, gibt es eine aufrufende Funktion, deren Parameter und Namen sich
an das Original anlehnt: MsgBoxEx.
Public Function MsgBoxEx( _
strMessage As String, _
lngSymbol As enMsgSymbol, _
strButton1 As String, _
Optional strButton2 As String, _
Optional strButton3 As String, _
Optional intDefaultButton As Integer, _
Optional strTitle As String) As Integer
Dim frm As New frmMsgBox
frm.Message = strMessage
frm.Symbol = lngSymbol
frm.DefaultButton = intDefaultButton
If Len(Trim$(strTitle)) = 0 Then strTitle = App.Title
frm.Title = strTitle
frm.Button1 = strButton1
frm.Button2 = strButton2
frm.Button3 = strButton3
frm.Show vbModal
MsgBoxEx = pintMsgBoxExReturn
End Function
Der Einfachheit halber existiert die globale Variable pintMsgBoxExReturn, die im Code der Form gesetzt wird, je nachdem welche
Schaltfläche gedrückt wurde, und den Rückgabewert der Funktion darstellt.
Eines der Probleme bestand nun darin den übergebenen Text und die Schaltflächen
mit ihrer benutzerdefinierte Beschriftung einigermaßen ansehnlich auf die Form
zu bekommen. Dabei sollten die Seitenabstände, ebenso wie die Schaltflächen
und der Text selbst, akkurat und gleichmäßig aussehen, was bei der zumeist verwendeten
Schriftart "MS Sans Serif" nicht trivial ist, denn die einzelnen Buchstaben
haben nicht die gleiche Laufweite. Aus diesem Grund war die Hilfsfunktion
CalcStringLenght vonnöten, die anhand der durchschnittlichen
Laufweite der Buchstaben die Länge eines Textes in Twips errechnet:
Public Function CalcStringLenght( _
ByVal strValue As String, _
Optional ByVal lngMinimum As Long) As Long
'Längenermittlung in Twips für die Schriftart "MS Sans Serif"
Dim i As Integer
Dim lngLen As Long
For i = 1 To Len(strValue)
Select Case Mid(strValue, i, 1)
Case "i", "j", "l", "'"
lngLen = lngLen + 420
Case " "
lngLen = lngLen + 450
Case "f", "r", "t", "I", "!", "(",")"
lngLen = lngLen + 570
Case ",", ".", ";", ":", "-"
lngLen = lngLen + 570
Case "*"
lngLen = lngLen + 720
Case "s", "x", "y", "z", "J"
lngLen = lngLen + 870
Case "a", "b", "d", "e", "h", "k","n", "o", "p", "q"
lngLen = lngLen + 1020
Case "u", "v", "F", "L", """","\", "/"
lngLen = lngLen + 1020
Case "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "_", "+", "="
lngLen = lngLen + 1020
Case "c", "A", "B", "C", "E", "K","P", "S", "T", "V", "X", "Y", "Z"
lngLen = lngLen + 1170
Case "m", "w", "D", "G", "H", "N","O", "Q", "R", "U", "%"
lngLen = lngLen + 1320
Case "M"
lngLen = lngLen + 1470
Case "W"
lngLen = lngLen + 1470
Case Else
lngLen = lngLen + 1000
End Select
Next
CalcStringLenght = lngLen / 10
If CalcStringLenght < lngMinimum Then
CalcStringLenght = lngMinimum
End If
End Function
Mit dieser Funktion lässt sich nun beim OnLoad-Event
der Form (kompletter Code siehe Download) die korrekte Breite der einzelnen
Schaltflächen bestimmen. Die Breite und die Höhe der Message-Box ist jedoch
vor allem abhängig vom darzustellenden Text, d.h von der Zeilenanzahl und der
maximalen Zeilenlänge. Aus diesem Grund wird der Text zunächst an eventuell
vorhandenen Zeilenumbrüchen auseinander geschnitten. Jedes der Teile wird in
einzelne Worte zerlegt und über eine Schleife wird für jedes Wort die Länge
in Twips errechnet und mit dem Text eine Zeile zusammengebaut, bis die maximale
Zeilenlänge erreicht ist.
Aus der sich so ergebenden Zeilenanzahl und der maximalen Zeilenlänge wird
die Breite und die Höhe der Form und des Label-Elements errechnet. Die Anzahl
der anzuzeigenden Schaltflächen richtet sich danach, welchen Button-Eigenschaften
Werte zugewiesen wurden. Diese werden dann am unteren Rand der Form zentriert
angebracht.
Downloads
MsgBoxEx.zip