1. Hauptnavigation
  2. Navigation des Hauptbereiches
  3. Inhalt der Seite

Windowsprogrammierung


Die Lehrveranstaltung "Windowsprogrammierung" kann im 4. Semester von den Studenten des Studiengangs Medieninformatik als wo-Fach im Umfang von 2/0/2 SWS belegt werden. Es werden Programmierkenntnisse der Programmiersprache C++ vorausgesetzt. Es werden die Grundlagen der Windowsprogrammierung am Beispiel von .NET und C# gelehrt. Vor dem eigentlichen Prüfungszeitraum findet eine praktische Programmierprüfung (APL, 60 Minuten) im Computerlabor statt. Ein Beleg wird nicht gefordert.


Themen der Lehrveranstaltung:


Wir können hier leider nur eine Auswahl der vielen .NET-Klassen besprechen ...
  • eine kurze Einführung 
    - Was muss ich als C++ - Programmierer über C# wissen?
    - Was ist eigentlich .NET ?
    - erste Minimalbeispiele
  • allgemeine Ereignisse und Ereigniss-Bearbeiter 
    - Maus-, Tastatur-, Fenster-, Timer- und Drag&Drop-Ereignisse und
    - parallele Ereignisbearbeitung, ...
  • Steuerelemente
    - klassische Steuerelemente (eine Auswahl)
    - mehrseitige Dialoge mit Steuerelementen
    - Haupt- und Kontext-Menüs
    - Symbol- und Statusleisten
  • GDI, Farben und Schriften
    - Graphics- und GDI-Objekte,
    - effizientes Zeichnen durch Doppelpuffertechniken,
    - Transformationen, ...
  • Standarddialoge und deren Anwendung
    - Filedialoge, Farbdialoge, Fontdialoge, ...
  • die Arbeit mit der Zwischenablage 
    - Text, Bilder, Metafiles, und eigene Formate, ...
  • Netzwerk-Programmierung mit der Klasse Socket
    - synchrone, asynchrone Sockets,
    - Client- Server-Programmierung, ...
  • Drucken
    - Druckdialog, Druckseiten einrichten, Druckvorschau, ...
  • Dateien und Streams
    - binäre Dateien, Textdateien, Dateiattribute, Verzeichnisbäume, ...
  • der Mauszeiger
    - Mauszeiger ändern, vor- und selbstdefinierte Mauszeiger
  • Arbeit mit Threads
    - erzeugen, steuern und synchronisieren paralleler Programmfäden
  • Interfaces, DLL-Dateien, COM-Objekte
  • Nutzung von XML-Dateien
  • Zugriff auf relationale Datenbanken
    - ADO.NET
  • Windows Presentation Foundation (WPF, XAML)


Literatur:

   . Charles Petzold:  Windows Programmierung mit C#
   . Frank Eller: Visual C# 2008
   . Andreas Kuehnel: Visual C# 2008
   . Adam Nathan: Windows Presentation Foundation Unleashed




Praktikumsaufgaben:




Aufgabe 1: eine erste Dialoganwendung

Generieren Sie Ihre erste Dialoganwendung. Das Dialogfenster habe die Überschrift "Erste Dialoganwendung". Geben Sie auf den Koordinaten 10,10 eine Zeichenkette aus. Vergleichen Sie die generierte Klassen mit dem ersten Beispiel in der Vorlesung. Fassen Sie nach Möglichkeit die Implementierungen in einer cs-Datei zusammen. Ändern Sie Ihren Dialog dahingehend, dass er für alle im Praktikum zu lösenden Aufgaben jeweils eine Schaltfläche (Button) besitzt. Jedem dieser Schaltflächen ist ein Ereignishändler zuzuordnen, der dann die Lösung der Aufgabe realisiert, indem er das entsprechende Dialogfenster startet.

prakt_dotnet_prog_a1.png


Nutzen und erweitern Sie das hier erstellte Programm (Projekt) bei der Lösung aller zukünftigen Aufgaben: Jede weitere Aufgabe wird durch eine neue Klasse realisiert, die von der Systemklasse Form erbt.
     class Aufg2 : Form { ...}
						
Im Ereignishandler der Schaltfläche für die neue Aufgabe wird ein Objekt der Klasse erzeugt und zur (modalen) Anzeige gebracht:
     m_aufg2 = new Aufg2(); m_aufg2.ShowDialog();
						
Die Funktionalität für die entsprechende Aufgabenstellung kann jetzt in die Klasse programmiert werden.





Aufgabe 2: Reaktion auf Ereignisse

Erweitern Sie Ihr Projekt aus der ersten Aufgabe dahingehend, dass es auf Ereignisse reagiert.

Nutzen Sie den "ClassWizard" (d.h. die Eigenschaften der Fensterklasse zur Aufgabe 2) um für die möglichen Mausereignisse jeweils verschiedene Ereignishandler einzufügen. Diese geben an der Mausposition, an der das Ereignis ausgelöst wurde, den Namen des Ereignisses auf dem Bildschirm aus. Erweitern Sie Ihre Programm um einen Ereignishandler für das Ereignis OnMouseMove, der die aktuellen Mauskoordinaten an der Position 10,10 ausgibt. Mit gedrückter Maustaste soll eine (Freihand-)Linie gezeichnet werden können.

Fügen Sie in Ihr Programm Ereignishandler für die Ereignisse OnResize, OnKeyDown und OnKeyPress ein. Der OnResize-Ereignishandler dient zur Ermittlung der Fenstergröße. Geben Sie in der Mitte des Fensters (dessen Größe geändert werden kann!) den Buchstaben 'x' aus.

Mit den Cursortasten (d.h. dem OnKeyDown-Ereignishandler) soll dieser Buchstabe im Fenster bewegt werden können. Über den OnKeyPress-Ereignishandler kann der darzustellende Buchstabe geändert werden.

prakt_dotnet_prog_a2.png


Was müssen Sie ändern, damit die Ausgaben erhalten bleiben, wenn das Fenster vom System (WM_PAINT) neu gezeichnet wird (zum Beispiel nach einer Überdeckung)? Versuchen Sie die änderungen in der verbleibenden Praktikumszeit.




Aufgabe 3: klassische Standardsteuerelemente

Generieren Sie eine Dialoganwendung mit einem "statischen Text", über den der Name, die Matrikelnummer, das Fach und die Fachnote eines Studenten angezeigt werden. Der Name und die Matrikelnummer des Studenten sind jeweils über ein Editierfeld einzugeben. Das Fach soll mit einem Kobinationsfeld gewählt werden können, das entsprechend sinnvolle Vorgaben macht. Die Note soll über ein Gruppenfeld mit "Radio-Buttons" eingeben werden.

Zusätzlich soll das Engagement des Studenten für die Lehrveranstaltung über einen horizontalen Scrollbalken in einem Bereich von 0 bis 100 % einstellbar sein. Verwenden Sie TextBoxOnTextChanged-Ereignisse, um eine quasi simultane Darstellung der Eingaben im Textfeld zu erreichen.

Bei einem Engagement von über 90% wird die Note 5 inaktiv ;-)

prakt_dotnet_prog_a3.png





Aufgabe 4: weitere Steuerelemente

Generieren Sie eine neue Dialoganwendung mit den folgenden Steuerelementen: In zwei Textfeldern wird die Auswahl aus einer Listen- und einer Baumansicht angezeigt. Die Listenansicht enhalte zunächst die Namen der Studenten, die im Praktikum in der gleichen Reihe mit Ihnen sitzen. Die Baumansicht enthalte für jede Reihe einen Teilbaum mit den jeweiligen Studentennamen. Bei Auswahl einer Reihe werden die entsprechenden Studenten aus der Baumansicht in die Listenansicht übertragen. Erweitern Sie Ihr Listenansicht (gern auch die Baumansicht) um beliebige Icons, die den Namen zugeordnet sind.

Über ein Textfeld kann dem Baum in der markierten Reihe ein Eintrag hinzugefügt werden. Desweiteren befindet sich in Ihrem Dialog ein Schieberegler und eine Fortschrittsanzeige. Über einen Schieberegler kann ein Wert zwischen 0 und 100 eingestellt werden, der als Zahl in einem Textfeld und in der Fortschrittsanzeige (0=0% ... 100=100%) dargestellt wird.

prakt_dotnet_prog_a4.png





Aufgabe 5: Tooltips und mehrseitige Dialoge

Erweitern Sie den Dialog aus der vorangegangenen Aufgabe um einen Options-Button. Mit diesem Button soll ein mehrseitiger Options-Dialog gestartet werden. Auf der ersten Seite befindet sich nur statischer Text, der (quasi als Hilfetext) über den Dialog informiert. Auf der zweiten Seite kann der Nutzer zwischen zwei Sprachen wählen (z.B. Deutsch oder Englisch). Entsprechend der hier gewählten Sprache, werden die Tooltips für die Steuerelemente des Dialogs aus der vorangegangenen Aufgabe ausgegeben. Die Funktionalität von Tooltips kann mit einer Checkbox aktiviert und deaktiviert werden.

prakt_dotnet_prog_a5.png





Aufgabe 6: ein einfacher Texteditor

Generieren Sie eine Dialoganwendung mit mehreren Buttons. Die Ereignishandler für die Buttons "Load File" und "Save File"starten einen Filedialog, mit dem "*.txt"-und "*.rtf"-Dateien geladen und gespeichert werden können. Der "Exit-Button" dient dem Verlassen des Dialogs. Der Inhalt der vom Nutzer gewählten Datei wird in einem RichTextBox-Steuerelement angezeigt und kann vom Nutzer editiert/verändert werden. Die Textfarbe soll änderbar sein (benutzen Sie hierzu den Standard-Color-Dialog). Versuchen Sie auch, Text über die Zwischenablage in Ihr Dokument einzufügen. Informieren Sie sich in der Online-Hilfe über weitere (in der Vorlesung nicht behandelte) Member der Klasse RichTextBox. Wenden Sie mindestens eine davon in Ihrem Programm an.

prakt_dotnet_prog_a6.png


Die Auswahl der Schrift wird mit Hilfe eines Standard-Font-Dialoges vorgenommen. Der Dialog unterstützt Drag&Drop, d.h. rtf- bzw. txt-Dateien können auf das Dialogfenster gezogen und damit zur Anzeige gebracht werden.





Aufgabe 7: ein erstes Zeichenprogramm

Implementieren Sie ein einfaches Zeichenprogramm. Über ein geeignetes Steuerelement kann der Nutzer wählen, ob eine Freihandzeichnung, eine Linie, eine Ellipse, ein Rechteck, Text oder eine Bitmap gezeichnet werden soll. Mit Hilfe der Maus und deren Ereignishandler erfolgt der Zeichenvorgang, der jedoch auf die Zeichenfläche zu begrenzen ist. Erweitern Sie Ihre Lösung dahingehend, dass die Farbe mit der Sie zeichnen, über einen Standard-Color-Dialog gewählt werden kann. Der Zeichensatz mit dem Sie Text ausgeben können, soll über einen Standard-Font-Dialog zur Laufzeit vom Nutzer ausgewählt werden. Die zu zeichnende Bitmap wird über einen FileOpen-Dialog ausgewählt. Nutzen Sie die Doppelpuffertechnik zum "Aufziehen" der Grafik im Ereignishandler OnMouseMove (siehe Vorlesung). Dies soll auch für Bitmaps unterstützt werden.<

prakt_dotnet_prog_a7.png


Mit Hilfe eines Kontextmenüs soll das Speichern und erneute Laden einer Zeichnung in den vom .NET-Framework unterstützten Datenformaten möglich sein. Ihr Kontextmenü enthalte weiterhin zwei Einträge, um das aktuelle Bild in die Zwischenablage zu legen, oder es von dort zu holen. Testen Sie diese Funktionalität mit Hilfe eines weiteren Grafikprogramms. Ein weiterer Menüpunkt startet einen Druckdialog und ermöglicht Ausdrucke der gezeichneten Grafik :-)




Aufgabe 8: graphische Benutzeroberflächen mit Bitmaps

Laden Sie in Ihr Fenster ein Hintergrundbild und darauf mehrere Teilbilder (grafische Buttons) unter Nutzung einer Transparenzfarbe. Erkennen Sie bei Mausbewegungen den "Kontakt" zu einer solchen Schaltfläche und wechseln Sie dabei die Bitmap im Sinne einer Signalisierung ("ich bin eine aktivierbare Schaltfläche", siehe Beispiel). Behandeln Sie die Aktivierung dieser Schaltfäche mit der linken Maustaste durch eine entsprechende MessageBox.

Implementieren Sie ein flimmerfreies "drag-and-drop"-Verhalten für Ihre grafischen Steuerelemente unter Nutzung der Doppelpuffertechnik. Die Bitmapgrafiken werden Ihnen im Praktikum im Ordner I:/prakt/bruns/Spriteprogrammierung zur Verfügung gestellt. Gern können Sie aber auch eigene Dateien verwenden.


prakt_dotnet_prog_a8.png


Tipp: Nachhaltig (d.h. wiederverwendbar) wird Ihre Lösung erst dann, wenn Ihre Implementierung in einer eigenen Klasse Sprite (natürlich unter Nutzung der .NET - Bitmap-Klasse) zusammengefasst wird :-)  Die Objekte dieser Klasse repäsentieren jeweils ein grafisches Element im Fenster. (Das Hintergrundbild ist auch ein Spriteobjekt.) Mindestens folgende Methoden halte ich für sinnvoll:
  • Load: Lädt eine Bitmapdatei und speichert die Information über die Größe eines Sprites.
  • SetPos, GetPos: ändert die Position des Sprites auf dem Bildschirm oder fragt diese ab. Dies können Sie natürlich auch über entsprechende Eigenschaften implementieren
  • Select: Wählt ein Sprite aus der Grafikdatei aus.
  • HitTest: überprüft, ob ein Punktwert (z.B. die Mauskoordinaten) über dem Sprite liegt. 
  • Draw: Zeichnet ein Sprite an die entsprechende Position eines Graphics-Kontextes. Im Sinne der Doppelpuffertechnik kann dieser Graphics-Kontext auch von einer Bitmap stammen :-)





Aufgabe 9: Datenaustausch über Sockets

Im Skripteordner finden Sie Quellcode für jeweils eine funktionierende Forms-Klasse für Clients und einen Server. Es handelt sich um das in der Vorlesung besprochene Beispiel.

Erweitern Sie Ihr Praktikumsprojekt um zwei weitere Buttons zum Starten des Serverfenster und von Clients. Wenn Sie die Fensterobjekte hierzu nicht mit ShowDialog() sondern nur mit Show() starten, dann könnten Sie Client (oder auch mehrere Clients) und den Server gleichzeitig starten, anzeigen und testen ;-)

prakt_dotnet_prog_a9b.png


Machen Sie sich das (funktionierende) Beispiel klar und experimentieren Sie eigenen Daten, die zum Beispiel aus Textfeldern stammen und versuchen Sie den Datenaustausch geeignet (im Sinne eines Chatverlaufs) darzustellen.





Aufgabe 10: die Arbeit mit Threads

Generieren Sie eine Dialoganwendung mit einem Start- und einem Stop-Button. Der Ereignishandler des Startknopfes startet einen "Worker-Thread", der alle Primzahlen kleiner 100000 berechnen, in einem Vektor speichern und (indirekt!) in einer Textbox ausgeben soll. Der Fortschritt soll in einer Fortschrittsanzeige dargestellt werden. Mit dem Stopp-Button kann der Thread vorzeitig gestoppt werden. Bevor der Thread jedoch terminiert, soll er die berechneten Ergebnisse in eine Textdatei schreiben. Steuern Sie den Thread über eine Klassenvariable.Die Berechnung kann zusätzlich mit einem Pause- und einem Fortsetzen-Button gesteuert werden.

prakt_dotnet_prog_a10.png





Aufgabe 11: Nutzen einer DLL-Bibliothek, Interoperabilität

Ihnen wird im Verzeichniss "I:\prakt\bruns" eine Dll-Datei mit nachfolgenden Funktionen bereitgestellt:
    void teste0();
    void teste1(int);
    char* teste2();
                        
Binden Sie diese Funktionen zur Laufzeit an Ihr Programm und testen deren Aufruf.


prakt_dotnet_prog_a11a.png

prakt_dotnet_prog_a11b.png

prakt_dotnet_prog_a11c.png


Erzeugen Sie nun selbst eine eigene DLL-Datei, die in C bzw. C++ implementiert ist und binden Sie diese Funktionalität zur Laufzeit an Ihr C#-Programm.  Gern helfe ich Ihnen hierbei indem wir diesen Aufgabenteil am Beamer gemeinsam lösen.





Aufgabe 12: Windows Presentation Foundation

Implementieren Sie den in Aufgabe 3 beschriebenen Dialog noch einmal mit WPF-Steuerelementen in einem neuen WPF-Projekt.

prakt_dotnet_prog_a3.png


Nutzen Sie dazu zunächst nur XAML und erreichen Sie die Ausgaben auf der rechten Seite mit Databinding. Bemerken Sie das Problem mit den Radio-Buttons?

Arbeiten Sie nun wieder mit C# und koppeln Sie die rechte und linke Seite mit entsprechenden Ereignishandlern (mindestens für die Radio-Buttons).

Nun benötigen wir noch eine Schaltfläche mit der Aufschrift "Speichern". Die Funktionalität des Speicherns wird ebenfalls durch die "Code-Behind"-Datei implementiert, wobei die eingetragenen Daten an eine Textdatei angehängt werden. Machen Sie sich klar, dass Sie auch in WPF-Anwendungen ganz normal die Funktionalität von C# und .NET zurückgreifen können.

Rufen Sie nun die neu erzeugte exe-Datei aus Ihren bisherigen Praxisprojekt auf.
     System.Diagnostics.Process.Start("Aufgabe12.exe");
						
Optional: Sie können sich nun an die Entwicklung von Windows-Apps bzw. Windows Phone Apps machen. Entsprechende Projektvorlagen finden Sie in Ihrer Entwicklungsumgebung. Auch hier nutzen Sie (in fast gleicher Weise) XAML und Teile der WPF :-)




Zeitplan für Praktika und Prüfung - Sommersemester 2024:

11. KW: 1. Vorlesung, keine Praktika
12. KW: Aufgabe 1, Aufgabe 2
13. KW: Karfreitag
14. KW: Aufgabe 2, Aufgabe 3
15. KW: Aufgabe 3, Aufgabe 4
16. KW: Aufgabe 4, Aufgabe 5
17. KW: Aufgabe 5, Aufgabe 6
18. KW: Aufgabe 6, Aufgabe 7
19. KW: Christi Himmelfahrt (Brückentag)
20. KW: Aufgabe 7, Aufgabe 8
21. KW: Aufgabe 8
22. KW: Aufgabe 9, Aufgabe 10
23. KW: Aufgabe 10, Aufgabe 11
24. KW: Aufgabe 11, Aufgabe 12 (optional)
25. KW: Aufgabe 12 (optional)
28.06.2024: Prüfung (15:10 Uhr, Raum Z355)


Wenn Sie alle diese Aufgaben gelöst haben, sind Sie bestens auf die Prüfung vorbereitet :-)