Tutorial
Erste Schritte in der WinAPI mit Freebasic und FBEdit
von stephanbrunker | Seite 4 von 13 |
Radiobutton und Checkbox
Wenn der Benutzer eine Auswahlmöglichkeit haben soll, dann geht das mit Radiobuttons. Über den Einsatz der Steuerelemente hat sich Microsoft durchaus Gedanken gemacht, es gibt dazu eine richtige Designrichtlinie in der MSDN: Design-RadioButtons Wenn man sich zwei davon auf sein Fenster zieht, funktionieren die natürlich nicht von alleine. Die Logik verlangt zwar, dass man von dem einen zum anderen umschalten kann, aber das weiß unser Programm nicht unbedingt von alleine.
Unser neuer Dialog (Dialog und Window sind für unsere Belange übrigens das selbe, selbst ein Button ist für Windows ein Window):
Abhängig von den Radiobuttons soll der Text beim Druck auf den Button entweder links oder rechts erscheinen.
Mit diesen Elementen:
Dialog.bi
'Define the Identifiers for the Window Elements
#Define IDD_DLG1 1000
#Define IDC_BTN1 1001 'Button
#Define IDC_EDT1 1002 'Editbox left
#Define IDC_EDT2 1003 'Editbox right
#Define IDC_RBN1 1004 'Radiobutton left
#Define IDC_RBN2 1005 'Radiobutton right
müssen wir etwa solchen Code schreiben:
Dialog.bas
Case WM_INITDIALOG
'Intialize the Radiobuttons: Default Button "Left"
SendDlgItemMessage(hWin,IDC_RBN1,BM_SETCHECK,BST_CHECKED,NULL)
Case WM_COMMAND 'Message sent by Usercommand
Select Case HiWord(wParam)
Case BN_CLICKED 'Left Mousebutton
Select Case LoWord(wParam)
'Toggle Radiobuttons (manually, instead of BS_AUTORADIOBUTTON)
Case IDC_RBN2
'Button "Right" clicked: Uncheck Button "Left"
'SendDlgItemMessage(hWin,IDC_RBN1,BM_SETCHECK,BST_UNCHECKED,NULL)
Case IDC_RBN1
'Button "Left" clicked: Uncheck Button "Right"
'SendDlgItemMessage(hWin,IDC_RBN2,BM_SETCHECK,BST_UNCHECKED,NULL)
Case IDC_BTN1 'Click on BTN1
'Send text to Editboxes in regard of the Radiobuttons
If SendDlgItemMessage(hWin,IDC_RBN1,BM_GETCHECK,0,0) = BST_CHECKED Then
SetDlgItemText(hWin,IDC_EDT1,@"Hello" )
SetDlgItemText(hWin,IDC_EDT2,@"" )
ElseIf SendDlgItemMessage(hWin,IDC_RBN2,BM_GETCHECK,0,0) = BST_CHECKED Then
SetDlgItemText(hWin,IDC_EDT1,@"" )
SetDlgItemText(hWin,IDC_EDT2,@"Hello" )
End If
End Select
End Select
Wir müssen die Buttons erst einmal initialisieren, das geht beim Aufbau des Fensters - das dabei die WM_INITDIALOG Message sendet. Vom Start weg sollte ja einer der Buttons voreingestellt sein, laut Designrichtlinie der oberste. Das geht mit BM_SETCHECK und BST_CHECKED. Wenn dann einer der Radiobuttons angeklickt wird, muss der jeweils andere gelöscht werden, dafür gibt es eine automatische oder eine manuelle Version, die hier auskommentiert ist. Wenn man im Resourceneditor für den ersten Button einer Gruppe den Style "WS_GROUP" und für alle Buttons "BS_AUTORADIOBUTTON" wählt, dann macht Windows das Umschalten automatisch. Wird dann unser "Push me" Button gedrückt, fragt das Programm mit BM_GETCHECK den Status der Radiobuttons ab und sendet dann den Text an das gewünschte Editfeld. Statt Elseif hätte man natürlich auch Else nehmen können ohne die Abfrage, das ist eine Frage des Programmierstils, inwieweit man eine Fehlerabfrage einprogrammiert.
Tutorial3.zip
Wenn man die Radiobuttons kann, dann gehen die Checkboxes genau nach dem gleichen Prinzip und mit den gleichen Message: BM_GETCHECK und BM_SETCHECK und BN_CLICKED (auch die Checkbox ist ein Button!). Es ist nur ein Designunterschied: Bei den Radiobuttons ist immer einer aktiv, der Benutzer wählt genau eine der möglichen Optionen. Bei den Checkboxes kann der Benutzer für jedes Element entscheiden, ob es aktiv sein soll oder nicht - in der MSDN sehr ausführlich beschrieben. Für unseren Code heißt das, dass entweder etwas passiert wenn die Box geklickt wird - sie sendet eine WM_COMMAND -> BN_CLICKED Message - und wir dabei mit BM_GETCHECK den aktuellen Status erfragen oder es passiert erst einmal nichts uns wir machen die Abfrage später im Programm. Wir könnten mit folgendem Code:
Case WM_COMMAND 'Message sent by Usercommand
Select Case HiWord(wParam)
Case BN_CLICKED 'Left Mousebutton
Select Case LoWord(wParam)
Case IDC_CHK1
If SendDlgItemMessage(hWin,IDC_CHK1,BM_GETCHECK,0,0) = BST_CHECKED Then
EnableWindow(GetDlgItem(hWin,IDC_EDT1),TRUE)
Else
EnableWindow(GetDlgItem(hWin,IDC_EDT1),FALSE)
EndIf
End Select
unsere Editbox deaktiveren oder aktivieren. Wenn ich hier scheinbar die gesamte Select Case Anweisung kopiere, stimmt das in der Realität natürlich nicht, denn unter BN_CLICKED wäre ja noch der Case für unseren IDC_BTN1 ... ich will nur zeigen, wo genau der Code hingehört.
Von der Tastaturbedienung her ist wieder der Button als Defaultbutton definiert, die Radiobuttons sind TabIndex 1, und Editboxen und Checkbox sind Tabstop=FALSE, damit ergibt sich eine schlüssige Tastaturbedienung für unser Nonsens-Programm.
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|