Programmieren in C
Transcription
Programmieren in C
Programmieren in C
Teil 2
IDE
Integrierte Entwicklungsumgebung
Editor
Compiler / Linker
Debugger
Hilfe / SDK /API
Verwaltung aller Projektbezogenen Daten
C Dateien
Header
Resourcen
Visual Studio 2008
Aufgaben
Neues Projekt anlegen (Konsolenanwendung)
Neues Projekt
Win32
Konsole
Leeres Projekt
Neue Datei
C++ Datei (Speichern als C-Datei)
Dem Projekt hinzufügen
Beispiel der strcpy()-Funktion programmieren und übersetzen
Benutzung des Debuggers
Haltepunkte
Marken, an denen die Programmausführung angehalten wird
Schrittweite Ausführung des Programms
Überwachung der Variablen
Bei Ausführung des Programms im Debugger wird bei einem
Fehler automatisch die Stelle, an der der Fehler auftrat,
angezeigt
Aufgabe
Fehler im Beispiel strcpy() einbauen
Fehlerhaften Zeiger übergeben
Fehlerhaften String (nicht Null-terminiert) übergeben
Stack
FiLo (First in/Last out)
Z.B. Speicherbereich zum Speichern von
Rücksprungadressen eines Tasks
Benötigte Info
Start-Adresse
Aktuelle Position (Offset)
Länge des Speicherbereichs
Schreiben und lesen passieren an „einer“
Speicherstelle
Start
Start +1
…
Akt. Pos
…
Ende
FiFo
First in/First out
Start
Z.B. Tastatur-Puffer
Ringbuffer
Benötigte Info
Startadresse
…
Länge
Akt. schreiben
Schreibposition
Leseposition
…
Info über „Umbruch“
Schreiben und lesen sind
entkoppelt
Start +1
Start
…
…
…
…
Akt. lesen
Akt. lesen
…
Akt.
schreiben
…
Ende
Verkette Listen
Variabel erweiterbar
Liste wir durch Verknüpfung der einzelnen
Elemente durch Zeiger aufgebaut
Effektiv zum Speichern sich ändernder
Daten (einzig durch Zeigeroperationen)
Einfaches Hinzu-/Einfügen
Löschen
Sortieren
Element 1
….
Element 2
….
Element 3
….
Aufgabe
2. Versuch der Benutzerdatenbank mit verketteten Listen
Windows klassisch
Versteckt – Betriebssystem
Verwaltung von Speicher, Laufwerken, Grafikkarte, CPU usw.
Bereitstellung von Bibliotheken für den Zugriff auf diese Resourcen
Sichtbar – Grafische Oberfläche
Mauszeiger
Fenster
„Multitasking“ (kooperativ, preemptiv)
Arbeitsweise einer grafischen
Oberfläche
Abruf der
Meldung
Meldungen
(Ereignisse)
• Mouse Events
• Keyboard Events
• Aktualisierung
des Fensters
• Timer …
Meldungsschleife
Bearbeitung
der Meldung
Meldungswarteschlange
(Message Queue)
Aufgaben beim Entwickeln eines
Windows Programmes
Implementierung der Meldungsschleife
1mal, sieht quasi immer gleich aus
Implementierung des spezielle Verhaltens der Anwendung
Darstellung des Inhalts des Fensters
Ein Windows Programm
(oder was hat das mit C zu tun?)
#include <windows.h>
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
MSG msg;
WNDCLASS wndclass;
HWND hwndMain;
wndclass.style = (unsigned int) CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_BYTEALIGNWINDOW;
wndclass.lpfnWndProc = (WNDPROC) WndProc;
wndclass.cbClsExtra = (int) 0;
wndclass.cbWndExtra = (int) 5;
wndclass.hInstance = (HINSTANCE) hInstance;
wndclass.hIcon = (HICON) LoadIcon (NULL, "MainIcon");
wndclass.hCursor = (HCURSOR) LoadCursor(NULL, IDC_CROSS);
wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wndclass.lpszMenuName = (char *) NULL;
wndclass.lpszClassName = (char *) szWndClass;
RegisterClass (&wndclass);
if (RegisterClass (&wndclass))
{
hwndMain = CreateWindowEx (0,
szWndClass, // window class name
szWndCaption,
WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
(GetSystemMetrics (SM_CXSCREEN) - 640) / 2,
|
| 14
// window caption
// window style
Das Graphics Device Interface (GDI)
Vereinheitlichte Schnittstelle zur Darstellung der Informationen
Abstrahiert die Art des Geräts (Drucker und Bildschirme sind gleich
anzusprechen)
"Versteckt" die Grafikkarte
Kern ist der Gerätekontext (Device Context – DC)
Ist letztendlich der Grafikkartenspeicher
Enthält den angezeigten Inhalt des Fensters
|
| 15
Das Fenster
Caption
System Menü
0
Fenster Höhe
Client
Rectangle
Border
Fenster Breite
0
|
| 16
Der Gerätekontext
Ist der Client-Bereich
Wenn ein Teil zu aktualisieren ist, wird eine WM_PAINTMeldung gesendet
Mit BeginPaint() wird ein Handle auf den Device-Kontext
angefordert und eine PAINTSTRUCT-Struktur gefüllt
Ein Member der PAINTSTRUCT-Struktur gibt den ungültigen
Bereich an
Ungültige
r Bereich
Muss neu
gezeichnet
werden
|
| 17
typdef struct tagPAINTSTRUCT
{
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
}
PAINTSTRUCT
System-Werte
Vorgaben der Installation für diverse Größen
Darstellbare Pixel
Breite des Rahmens
Größe der Titelleiste
Anzahl der Monitore
Mouse / Mouse-Rad
GetSystemMetrics()
|
| 18
Formatierte Textausgabe
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cyChar;
switch (iMsg)
{
case WM_CREATE:
{
TEXTMETRIC tm;
HDC hdc;
hdc = GetDC (hwnd);
GetTextMetrics (hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC (hwnd, hdc);
return (0);
}
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
char szText[] = "Hello World";
RECT rcClient;
int i = 0;
int iMetric;
char szBuffer[128];
…
Systemmetrics\Systemmetrics.sln
|
| 19
Aufgabe
Alle Systemwerte ausgeben lassen
|
| 20
Arbeiten mit dem DC
Linien zeichnen
LineTo(), MoveToEx(), PolyLine(),…
Kurven, Ellipsen
Arc(), AbgleArc(), Ellipse()…
Bezier-Kurven
PolyBezier(), PolyBezierTo(),…
Zeichenstifte
CreatePen(), CreatePenIndirect(), SelectObject(),…
Pinsel
CreateBrushIndirect(), SelectObject(),…
Koordinatensysteme
SetViewportOrgEx(), MapWindowPoints(), SetWorldTransform(),..
Regionen/Clipping
CreateRectRgn(),…
|
| 21
WICHTIG!
Alle GDI-Objekte, die neu erzeugt werden, müssen auch wieder
freigegeben werde!
Objekte, z.B. erzeugt mit CreateBrush(), CreatePen(),
CreateBitmap(),…, werden durch DeleteObject() wieder
freigegeben
DCs werden mit unterschiedlichen Funktionen freigegeben, abhängig
von der Art der Erzeugung
Welche Funktion zum Freigeben benutzt werden muss, steht in der
Beschreibung zur jeweiligen Create…() Funktion
Werden Objekte nicht freigeben, führt die zu
Speicher Leck
Keine freien Handels (neue Objekte können nicht mehr erzeugt
werden)
Programm-Absturz
|
| 22
Aufgabe
Funktion f(x)=x^2 in einem Fenster mit Koordinatensystem
plotten lassen
Fensterklassen
Fensterklassen definieren Eigenschaften eines Fensters
Z.B. Cursor
Menü
…
Legen eine Funktionalität fest
WndProc()
Von jeder Klasse können mehrere "Instanzen" existieren
Erzeugt wird die Instanz mit CreateWindow()
WndProc sollte so programmiert sein, dass es keine Konflikte gibt
Eine mit RegisterClass() registrierte Fensterklasse kann von
jedem Windows Programm benutzt werden
|
| 24
Was sind Steuerelement
Element, die i.d.R. innerhalb von Dialogen zur
Benutzerinteraktion benutzt werden
Buttons
Statics
Edit-Control
Combo-Boxes
Ab Windows 95 kommen die "Common Controls" dazu
List-View
Tree-View
…
|
| 25
Benutzung von Steuerelementen
Steuerelemente sind Fenster, deren Fenster-Prozedur für die
wesentliche Funktionalität schon existiert
Diese Fenster können innerhalb des eigenen Fensters integriert werden
Beispiel: Edit-Control
case WM_CREATE:
{
HINSTANCE hInstance;
hInstance = GetWindowLong (hwnd, GWL_HINSTANCE);
hwndEdit = CreateWindowEx (0, "EDIT", "", WS_CHILD | WS_VISIBLE |
ES_MULTILINE,0, 0, 0, 0, hwnd, NULL,
hInstance, NULL);
return (0);
}
|
| 26
Edit\Edit.sln
Gängige Fensterklassen
Edit-Control
Combo-Boxes
Buttons
Push Button
Radio Button
Check Box
Klassen\Klassen.sln
|
| 27
Aufgaben
Einfachen Texteditor programmieren
Benutzen der Fensterklasse EDIT
Common Controls
Erweiterung seit Windows 95
Explorer-Styles
Tab-Reiter
Bilder/Animationen usw.
Muss zur Benutzung initialisiert werden!
InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
Mit lpInitCtrls können die gewünschten Controls ausgewählt
werden
ICC_WIN95_CLASSES für alle
Definiert in <commctrl.h>
Weiterhin muss im Projekt die zugehörige Library angegeben
werden
Commctl32.lib
|
| 29
Aufgaben
Fenster mit den Edit-Control, List Box, Combo-Box und Buttons
Programmieren
Unterschiedliche Styles auspropieren (WS_..., ES_..., LBS_...,
CBS…, BS_...)
"Kommunikation" zwischen Hauptfenster und Control über Meldungen
(WM_..., EM_..., LM_..., BM_...)
Text in Listbox/Combobox einfügen
|
| 30
Standard Dialoge
Message Boxes
Information für den Benutzer, einfache Auswahl
Common Dialogs (Common Dialog Library)
Farbauswahl
Speichern/Laden
Auswahl von Schriftarten
Drucker Dialog
Druck-Eigenschaften Dialog
Text suchen
"Eigene" Dialoge
Modal
Modeless
|
| 31
Modale Dialog
Dialoge sind fangen alle Eingaben ab, das übergeordnete Fenster ist
nicht mehr erreichbar
Fast alle gängigen Dialoge sind modal (Speichern/Laden, Drucken, usw.)
Synchron (d.h. der Code "läuft" erst weiter, wenn der Dialog geschlossen
wurde)
Erstellen des Dialogs
"Malen" im Resource-Editor
Schreiben einer Dialogbox Prozedur (DlgProc)
Leicht unterschiedlich zur Fensterprozedur
Wird dargestellt durch Aufruf von DialogBox() oder
DialogBoxParam()
Font2.dsw
|
| 32
Kommunikation zwischen Dialog und
Control
Kommunikation zwischen Dialog und Controls über Meldungen
Abfragen von Controls z.B. mit der Funktion SendDlgItemMessage()
Benachrichtigung der Dialog Prozedur über Änderungen eines
Controls über
WM_COMMAND Meldung
WM_NOTIFY Meldung
Alle Controls kennen außer der Standard-Meldungen noch
spezielle Meldungen
Buttons: BM_... / BN_...
Edit: EM_.../EN_...
…
|
| 33
Modeless Dialoge
Eingaben an das übergeordnete Fenster werden weitergereicht
Das übergeordnete Fenster "arbeitet weiter"
Nur wenige Anwendungen benötigen diese Funktionalität (z.B.
"Suchen/Ersetzen")
Asynchron (d.h. der Code läuft weiter, auch wenn der Dialog noch
geöffnet ist)
Verwendung genau wie modale Dialoge, außer
Darstellung durch CreateDialog() oder CreateDialogParam()
Das WS_VISIBLE Flag muss explizit gesetzt werden oder der Dialog
muss durch den Aufruf von ShowWindow() explizit dargestellt werden
Schließen mit DestroyWindow()
|
| 34
Aufgabe
Uhr programmieren
Umschaltbar zwischen digital und analog (Menü)
Weitere benötigte Funktion time(),…
Weitere benötigte Library math.h (für sin() und cos())
|
| 35