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