![]() |
|
|
|
Die Grundlagen der Windows-Programmierung PowerBASIC for Windows erzeugt echte 32-bit Windows-Programme mit den für Windows üblichen grafischen Bedienoberflächen mit Pull-Down-Menüs, Eingabefeldern, Schaltflächen, Kontrollkästchen und vielen weiteren Windows-Steuerelementen. Anstelle der einfachen unter PB/DOS genutzten Befehle (LOCATE, PRINT, etc.) stehen unter PB/WIN weitaus leistungsfähigere Befehle zur Verfügung. Sehr wesentlich ist aber, dass sich unter Windows der Programmaufbau grundlegend unterscheidet, zumindest wenn man mit PB/WIN Programme mit Windows-Bedienoberfläche entwickeln möchte. Umsteiger von PB/DOS sollten sich also zunächst einige Stunden Zeit nehmen, um das Konzept der ereignisgesteuerten Programmierung zu verstehen. Beim ersten Kontakt mit der Windows-Programmierung scheint dies immer die größte Hürde zu sein. Es ist zunächst nicht notwendig, genau zu verstehen, warum diese ungewohnte Art der Programmierung zwingend geboten ist. Überhaupt sollte man als Einsteiger auf keinen Fall den Ehrgeiz haben, alles verstehen zu wollen. Zu groß wäre die Gefahr, nicht nur das neu angeschaffte PB/WIN, sondern auch den Vorsatz zum Einstieg in die Windows-Programmierung frustriert in die Ecke zu legen, noch bevor die ersten kleinen funktionierenden Programme die beim Programmieren so wichtige Begeisterung wachsen lassen. Die folgende Anleitung soll also möglichst schnell zum ersten kleinen Windows-Programm hinführen, wobei wir uns nicht mit einer einfachen MessageBox mit der Anzeige von "Hello World!" begnügen wollen. Also frisch ans Werk .... Die Installation von PB/WIN hat noch nie ein Problem verursacht. CD-ROM rein und die Installation startet automatisch mit den üblichen und bekannten Schritten. Erforderlich ist die Eingabe der Seriennummer, welche in der Rechnung bzw. auf dem rückseitigen Aufkleber der CD-Hülle zu finden ist. Bereits wenige Augenblicke später sollte man die PB/WIN IDE auf dem Bildschirm zu sehen bekommen. Ganz rechts in der Symbolleiste findet sich das Symbol (Handbuch mit Fragezeichen) zum Aufruf der Online-Hilfe. Natürlich sollte sich jeder Neuanwender zunächst zumindest einen Überblick über die vorhandenen Themen verschaffen. Für Umsteiger von PowerBASIC/DOS (oder ähnlichen Programmiersprachen) könnte eine Durchsicht von "Command Summary" interessant sein, um gleich einmal festzustellen, welche längst vertrauten Befehle und Funktionen vorhanden sind und welche Befehle vollkommen unbekannt erscheinen. Ganz wichtig ist der Abschnitt "Data Types". Zumindest die wichtigsten Datentypen müssen jedem Programmierer unbedingt geläufig sein. Glücklicherweise sind zumindest den Umsteigern von DOS schon viele Themen bestens bekannt. Berechnungen und Vergleichsoperationen, der Umgang mit Dateien, WHILE/WEND oder IF/THEN/ELSE Strukturen und die vielen Funktionen im Zusammenhang mit Stringvariablen sind entweder vollkommen gleich geblieben oder haben sich nur wenig geändert. Natürlich sind auch neue Funktionen hinzugekommen. Man muss aber nicht alle neuen Möglichkeiten sofort ausschöpfen. Den Abschnitt "The PowerBASIC COM Browser" können Sie jetzt überspringen und eine deutliche Mehrheitl der PowerBASIC-Nutzer wird sich auch in Zukunft niemals damit beschäftigen müssen. Auch die Ausführungen zu sehr speziellen Themen wie "Serial Communications", "TCP and UDP Communications" und "The Inline Assembler" werden viele Programmierer vermutlich niemals benötigen. Dynamic Dialog Tools (DDT) Empfehlen möchte ich aber im Abschnitt "Programming Reference" die Erläuterungen zu "Dynamic Dialog Tools (DDT)". Bereits in der Übersicht "Command Summary" findet man in der Gruppe "Dynamic Dialog Tools" etwa einhundert zugehörige Befehle und Funktionen beschrieben. Viele der DDT-Anweisungen beginnen mit den Schlüsselwörtern CONTROL oder DIALOG. Interessant wird es beim Mausklick auf das "leere Blatt" (Create new file) ganz links in der Symbolleiste. Es erscheint ein vierzeiliges Programmgerüst und sogleich macht man Bekanntschaft mit einem weiteren kleinen Unterschied gegenüber PB/DOS. Ausführbarer Code muss sich bei PB/WIN immer innerhalb einer Funktion befinden. Die Funktion PBMAIN hat dabei eine besondere Bedeutung. Die Ausführung des Programmes beginnt mit der Funktion PBMAIN als Einsprungpunkt und das Programm wird beendet beim Erreichen der zugehörigen Zeile END FUNCTION oder notfalls frühzeitig mittels EXIT FUNCTION. Den bei PB/DOS benutzen Befehl END zum Beenden der Programmausführung gibt es unter PB/WIN nicht. #DIM All sollte man sich angewöhnen, weil es zu mehr Disziplin zwingt und so manchen Fehler vermeiden hilft Natürlich könnten Sie jetzt einige Variablen deklarieren und schnell einmal ausprobieren, wie lange eine FOR/NEXT-Schleife mit zehnmillionen Durchläufen dauert. Als Erfolgssignal könnten Sie eine Meldung als MessageBox ausgeben. Also ein erster Versuch beispielsweise in der folgenden Form: |
|||||||||||
|
|
|||||||||||
|
Sofort nach ALT-R und "Compile and Execute" sollten Sie das Ergebnis am Bildschirm sehen. Falls nicht, hat sich einen kleiner Tippfehler eingeschlichen und Sie finden eine entsprechende Meldung im unteren Bildschirmbereich. Sie können übrigens die IDE über "Window"-"Options..." nach Ihrem persönlichen Geschmack etwas anpassen, was Sie sofort machen sollten, wenn Sie die voreingestellte Schriftgröße als zu klein empfinden. Jetzt geht es aber richtig los .... Für ein echtes Windows-Programm brauchen wir zunächst einmal ein Fenster, welches wirklich leicht zu erzeugen ist. Es reichen als Mindestvorgabe die Breite und Höhe des Fensters sowie der Text für die Titelleiste und eine DWORD-Variable, in der Windows die Kennziffer (Handle) des neuen Fensters ablegt. Mit dieser Kennziffer ist das neue Fenster in allen weiteren Aktionen klar ansprechbar. Zusätzlich könnte man noch die Positionierung der linken oberen Ecke angeben, falls keine mittige Ausrichtung am Bildschirm gewünscht ist. |
|||||||||||
|
|
|||||||||||
|
Was man jetzt nach "Compile and Execute" zu sehen bekommt, ist bestimmt noch nicht beeindruckend. Ein sehr einfaches Fenster mit keinen weiteren Möglichkeiten. Sie können das Fenster höchstens noch mit der linken Maustaste an der Titelleiste festhalten und über den Bildschirm ziehen. Zum Glück hilft Windows mit der Tastenkombination ALT-F4 beim Schließen des Fensters. Wenn Sie Lust haben, können Sie sich mit der weiteren Gestaltung dieses Fensters etwas beschäftigen. In der Dokumentation zu DIALOG NEW findet man eine Anzahl von möglichen Stilparametern. Also einmal auf "NEW" oder "DIALOG" klicken und danach die Funktionstaste F1 drücken. Es erscheint eine Auswahl mit den gefundenen Themen - wählen Sie "DIALOG NEW statement". In der Erläuterung zu style& findet man eine Anzahl von Stilparametern, welche nicht nur das Aussehen, sondern auch das Verhalten des Fensters bestimmen. Eine derart große Auswahl an Möglichkeiten für eine auf den ersten Blick einfache Angelegenheit ist typisch für Windows. Auch hier empfehle ich, zunächst nicht zuviel Ehrgeiz zu zeigen. Wer bei der Windows-Programmierung immer sofort alles verstehen möchte, kommt nur sehr, sehr langsam zum gewünschten Ergebnis. Ergänzen wir aber trotzdem in der Zeile DIALOG NEW den Stilparameter %WS_SYSMENU wie folgt: Wichtige Windows-Steuerelemente Zu den am meisten genutzten Windows-Steuerelementen zählen sicher die Schaltflächen und die Editfenster, welche ein- oder mehrzeilig sein können. Auch die einfachen Textfenster werden häufig verwendet. Diese sind nur zur Textausgabe oder zur Beschriftung anderer Elemente gedacht und sind deshalb besonders einfach zu handhaben. Wir ergänzen also unser kleines Beispiel mit einer kleinen Auswahl dieser einfachen Steuerelemente: |
|||||||||||
|
|
|||||||||||
|
Im Quellcode fällt zunächst die Liste der bezeichneten Konstanten auf. Genauso wie das Fenster selbst mit dem Handle hDlg benötigen auch die im Dialog-Fenster eingebundenen Elemente jeweils eine eindeutige Kennung und über die Kennziffer hDlg natürlich auch die Zuordnung zum beherbergenden Fenster (parent). Die gewählte Namensgebung für die Konstanten hat sich allgemein bewährt und wird in dieser Art auch von PB/Forms benutzt. Nach dem Kompilieren macht das Dialog-Fenster schon einen ganz netten optischen Eindruck. Wer sich daran stört, dass für die Eingabe von Länge und Breite auch Buchstaben anstelle von Ziffern möglich sind, kann dies leicht durch Hinzufügen des Stilparameters %ES_NUMBER ändern: |
|||||||||||
![]() |
|||||||||||
|
Es gäbe natürlich noch viele weitere Möglichkeiten, das Windows-Dialogfenster und die Steuerelemente anders zu gestalten. Versuchen Sie auch hier nicht alle Besonderheiten sofort zu verstehen und alle Möglichkeiten zu beherrschen. Wissen sollte man vielleicht noch, dass sich leider nicht alle Windows-Versionen absolut gleich verhalten. So kann etwa die Positionierung der Steuer-Elemente geringfügig abweichen. Setzen Sie deshalb die Steuerelemente nicht zu knapp an den Rand des Dialogfensters. Das Fenster rechnet nicht ! Selbstverständlich müssen wir noch die Formel für die Rechteckfläche irgendwo im Programm unterbringen. Entsprechend der Gestaltung unseres Windows-Dialogfensters sollte eine Berechnung nach dem Anklicken der Schaltfläche "Berechnung" erfolgen und danach das Ergebnis in das Feld "Fläche" geschrieben werden. Wir benötigen also eine Möglichkeit, das Anklicken einer Schaltfläche zu erkennen, um daraufhin die gewünschte Berechnung einzuleiten. Gerade dies ist unter Windows kein großes Problem. Windows überwacht alle möglichen Aktivitäten und meldet eine Vielzahl von Ereignissen in genau festgelegter Form. Die Benachrichtigung enthält immer die Kennziffer (Handle) des zugehörigen Dialogfensters, eine Kennziffer für die Art der Nachricht und zwei weitere Werte, deren Bedeutung von der Art der Nachricht abhängt. Unser Programm muss also nur auf ausgewählte Nachrichten reagieren, welche auf für uns interessante Ereignisse hinweisen. Bei der Programmierung im PowerBASIC-DDT-Stil - also mit den Dynamic Dialog Tools - erfolgt die Erkennung von Windows-Nachrichten und die entsprechende Auswertung innerhalb einer CALLBACK FUNCTION. In der Literatur (z.B. C++) wird eine Funktion mit dieser Aufgabe übrigens meist als Window-Prozedur bezeichnet. Die CALLBACK FUNCTION wird entweder einem einzelnem Steuerelememt (z.B. einer Schaltfläche) zugeordnet oder sie ist für die Auswertung aller Nachrichten eines Dialogfensters zuständig. Eine CALLBACK FUNCTION dürfen Sie niemals über eine Befehlszeile (z.B. mit CALL) direkt aus Ihrem Programm heraus aufrufen. Der Aufruf erfolgt immer über Windows selbst. Nach Annähernd jede in einem Windows-Programm ausgeführte Aktion ist eine Reaktion auf eine Windows-Nachricht, welche aufgrund eines bestimmten Ereignisses generiert wurde. Dieses Konzept der ereignisgesteuerten Programmierung ist ganz wesentlich für die Windows-Programmierung und zwar unabhängig mit welcher Programmiersprache man arbeitet. Übrigens kann ein Ereignis die vielfältigsten Ursachen haben. Nicht nur ein Mausklick oder ein Tastendruck oder die Bewegung der Maus lösen entsprechende Windows-Nachrichten aus. Auch das Verstreichen einer bestimmten Zeitspanne kann ein zeitabhängiges Ereignis auslösen. Zusätzlich gibt es noch die von Windows automatisch generierten Nachrichten und natürlich auch die durch das Programm selbst erzeugten Nachrichten. Allein in der Include-Datei WIN32API.INC findet man mehr als einhundert bezeichnete Konstanten mit möglichen vordefinierten Ereignissen. Damit sich niemand von diesen vielen Möglichkeiten erdrückt fühlt, möchte ich auch hier wieder darauf hinweisen, was sich Einsteiger immer vor Augen halten sollten: Man muss nicht alle Hintergründe verstehen, um brauchbare einfache Windows-Programme entwickeln zu können. Kaum ein Programmierer ist mit allen Möglichkeiten vertraut. Folgen Sie zunächst dem immer gleichen Schema und Sie werden Windows-Programme mit dem allgemein üblichen Aussehen schon nach kurzer Einarbeitungszeit erstellen können. Wie ist die CALLBACK FUNCTION aufgebaut? Die CALLBACK FUNCTION wird durch Windows aufgerufen, sobald eine Nachricht aufgrund eines für uns noch unbekannten Ereignisses vorliegt. Weil viele Ereignisse für eine bestimmte Aufgabenstellung vollkommen ohne Bedeutung sind (z.B. in unserem Beispiel die Bewegung der Maus), muss innerhalb der CALLBACK FUNCTION zuerst einmal festgestellt werden, ob es sich um eine für das Programm interessante Nachricht handelt. PowerBASIC stellt eine Anzahl von Funktionen (CBMSG, CBCTL, CBCTLMSG, CBHNDL, CBLPARAM, CBWPARAM) zur Verfügung, mit deren Hilfe man die Bedeutung einer Nachricht relativ leicht herausfinden kann. Üblicherweise benutzt man SELECT-Strukturen, um sich den erwarteten Ereignissen zu nähern. Erkennt man das erwartete Ereignis (in unserem Beispiel das Anklicken der Schaltfläche "Berechnung"), muss nur noch die dafür vorgesehene Befehlsfolge ausgeführt werden. In einfachen Windows-Programmen geht es überwiegend um Nachrichten vom Typ %WM_COMMAND, welche immer bei Ereignissen im Zusammenhang mit Windows-Steuerelementen ausgelöst werden. Wird also in unserem Beispiel eine der beiden Schaltflächen angeklickt, wird als Folge in jedem Fall eine %WM_COMMAND-Nachricht übermittelt. Für die Erkennung der Nachricht innerhalb einer CALLBACK FUNCTION hilft uns PB/WIN mit der Funktion CBMSG. Im nächsten Schritt untersuchen wir, welches Steuerelement die %WM_COMMAND-Nachricht verursacht hat. PB/WIN bietet dafür die Funktion CBCTL, welche wir ebenfalls über eine SELECT-Struktur einsetzen. In unserem Dialogfenster gibt es nur zwei Schaltflächen. Innerhalb der SELECT-Struktur setzen wir für jede Schaltfläche eine CASE-Bedingung. Unter idealen Bedingungen könnten wir mit diesem Minimum an Programmschritten schon auf das Anklicken der Schaltfläche reagieren. Windows wäre aber nicht Windows, wenn es nicht Situationen gäbe, welche noch eine weitere Prüfung notwendig machen. Man sollte deshalb immer sicherstellen, ob auch wirklich das vermutete Ereignis stattgefunden hat. Mit der Funktion CBCTLMSG können wir überprüfen, ob tatsächlich die Schaltfläche gedrückt wurde, d.h. ob mit der Nachricht der entsprechende Wert (%BN_CLICKED) übergeben wurde. Wer hier wegen der Notwendigkeit dieser weiteren Prüfung Zweifel hegt, kann diese im nachfolgenden Listing testweise weglassen und bei der Schaltfläche "Berechnung" die Stilparameter %BS_NOTIFY und %WS_TABSTOP ergänzen: Es gibt sogar sehr seltene Situationen, für die noch eine weitere zweite Prüfung notwendig ist. Um ganz sicher zu gehen, sollte man deshalb immer noch als zweite Bedingung CBCTLMSG=1 hinzufügen. In gleicher Weise behandeln wir noch die Schaltfläche für das Programmende. Dabei kommt die Funktion CBHNDL zum Einsatz, welche uns die Kennziffer (Handle) des Dialogfensters mitteilt. Diese Kennziffer wird für den Befehl DIALOG END benötigt, um das Dialog-Fenster zu beenden. Der von CBHNDL gelieferte Wert ist natürlich identisch mit der innerhalb der FUNCTION PBMAIN über den Befehl DIALOG NEW zugeteilten Kennziffer hDlg. Innerhalb der CALLBACK FUNCTION steht hDlg jedoch nicht zur Verfügung, weil hDlg nur als lokale Variable innerhalb der FUNCTION PBMAIN deklariert wurde. In manchen Listings wird hDlg als globale Variable deklariert und steht dadurch mit der immer gleichen Bezeichung im ganzen Programm zur Verfügung. Nachdem es in einfachen Programme oftmals ohnehin nur ein einziges Dialogfenster gibt, wird diese Methode von manchen Programmierern bevorzugt. Andere Programmierer empfinden die Benutzung von globalen Variablen (ähnlich dem Befehl GOTO) als schlechten Programmierstil und lehnen die Verwendung von GLOBAL grundsätzlich ab. So oder so haben wir das ereignisgesteuerte Programmgerüst jetzt fertig und der Quellcode sollte zwischendurch auch einmal getestet werden: |
|
|
|
Dem sehr aufmerksamen Leser sind vermutlich einige kleinere Ergänzungen aufgefallen? In der Zeile CALLBACK FUNCTION DlgProc() habe ich das Klammernpaar () angefügt, weil damit zum Ausdruck kommt, dass die Funktion einen Wert übergibt. Für die CALLBACK FUNCTION ist das zwar nicht unbedingt notwendig, aber schaden kann die Einhaltung der sonst üblichen Regeln auch nicht. Nach der erfolgreichen Verarbeitung einer %WM_COMMAND-Nachricht sollte die CALLBACK FUNCTION immer den Wert TRUE (also nicht Null) an Windows zurückgeben, um eine weitere Behandlung durch Windows zu verhindern. Dies optimiert die Programmausführung und verhindert Fehler aufgrund mehrfacher Ereignisbehandlung. Bei der Beschriftung der Schaltflächen habe ich jeweils ein "&" eingefügt. Dies ermöglicht das Auslösen der Schaltflächen durch die Tastenkombinationen ALT-B bzw. ALT-E Rechteckfläche = Länge * Breite Um das bisher erarbeitete Programmgerüst - welches in abgewandelter Form für viele weitere Aufgaben genutzt werden kann - möglichst übersichtlich und verständlich darzustellen, wurde die Berechnung zunächst zurückgestellt. Dort wo jetzt der Aufruf der MessageBox als Reaktion auf das Anklicken der Schaltfläche "Berechnung" zu finden ist, fügen wir die paar Zeilen ein, welche den eigentlichen Zweck unseres Programms ausmachen. Das Konzept für die notwendigen Schritte ist schnell überlegt. Wir lesen zunächst die Werte für Länge und Breite aus den Eingabefeldern, berechnen die Rechteckfläche und schreiben das Ergebnis in das Feld "Fläche". Fertig! Für das Lesen des Textes aus dem Eingabefeld benutzt man den PowerBASIC-Befehl Wenn aber ohnehin keine Fließkommawerte bei der Eingabe erlaubt sind, können wir uns bei der Wahl des Variablentyps für eine ganzzahlige DWORD-Variable entscheiden. In einem echten Programm würde man natürlich noch prüfen, ob die Eingabedaten im erlaubten Bereich liegen. Zweifellos liegt bei Berechnungen unter PB/WIN gegenüber PB/DOS mehr Verantwortung beim Programmierer. Fehlermeldungen wie z.B. "Division durch Null" gibt es unter PB/WIN nicht. In einer sorgfältig programmierten Anwendung werden derartig Sonderfälle sowieso immer besonders behandelt. Nach der Berechnung schreiben wir die Fläche in das vorgesehene Feld mit dem Befehl |
|
|
|
[Startseite] [Compiler] [TOOLS] [FORUM] [Preisliste] [Kontakt] |