Sie sind auf Seite 1von 1112

Inhaltsbersicht

Teil 1 Die Entwicklungsumgebung . . . . . . . . . . . . . . . . . . . . . . . . . . 19


1

Visual C++ und Visual Studio . . . . . . . . . . . . . . . . . . . . . . . . 21

1.1

Visual Studio: berblick ber die Entwicklungsumgebung . . . . . . . . . . . . 22

1.2

Die grundlegenden Arbeitsschritte . . . . . . . . . . . . . . . . . . . . . . . . . 28

1.3

Kommandozeilen-Hilfsmittel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

1.4

Neuerungen in der Version 6.0. . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

1.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Arbeitsbereiche und Projekte . . . . . . . . . . . . . . . . . . . . . . . . . 41

2.1

Projekte und Arbeitsbereiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

2.2

Das Arbeiten mit Unterprojekten . . . . . . . . . . . . . . . . . . . . . . . . . . 43

2.3

Projekte erstellen und bearbeiten . . . . . . . . . . . . . . . . . . . . . . . . . . 45

2.4

Projekte konfigurieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

2.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Die Assistenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

3.1

Der Anwendungsassistent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

3.2

Weitere Anwendungsassistenten und Projekttypen . . . . . . . . . . . . . . . . 56

3.3

Der Klassen-Assistent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

Inhaltsverzeichnis

3.4

Die Klasseninformationsdatei . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

3.5

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Browser und Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

4.1

Der Quellcode-Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

4.2

Der Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

4.3

Weitere Debug-Techniken und -Tools . . . . . . . . . . . . . . . . . . . . . . . . 88

4.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

5.1

Der Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

5.2

Der Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

5.3

Der Visual Studio Analyzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

5.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

Wiederverwenden von Programmcode mit der


Komponentensammlung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

6.1

Die Komponentensammlung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

6.2

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

Teil 2 Windows-Grundlagen und API . . . . . . . . . . . . . . . . . . . . . . . . 109


7

Betriebssystembersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

7.1

Fenster und Nachrichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

7.2

Nachrichten und Multitasking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

7.3

Windows-Funktionsaufrufe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

7.4

Plattformunterschiede. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

7.5

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Das API-Anwendungsgerst . . . . . . . . . . . . . . . . . . . . . . . . . . 135

8.1

Das wahre Hello-World-Programm . . . . . . . . . . . . . . . . . . . . . . . . 135

8.2

Eine einfache Nachrichtenschleife: Senden und Hinterlegen von Nachrichten . 137

8.3

Fensterfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

Inhaltsverzeichnis

8.4

Mehrere Nachrichtenschleifen und Fensterfunktionen . . . . . . . . . . . . .

143

8.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

147

Fenster, Dialogfelder und Steuerelemente . . . . . . . . . . . . . . 149

9.1

Die Fensterhierarchie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

150

9.2

Fensterverwaltung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

153

9.3

Zeichnen der Inhalte eines Fensters . . . . . . . . . . . . . . . . . . . . . . . .

158

9.4

Fensterverwaltungsnachrichten . . . . . . . . . . . . . . . . . . . . . . . . . .

160

9.5

Fensterklassen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

162

9.6

Dialogfelder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

170

9.7

Standarddialoge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

174

9.8

Steuerelemente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

182

9.9

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

188

10

Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

191

10.1

Elemente einer Ressourcendatei. . . . . . . . . . . . . . . . . . . . . . . . . .

192

10.2

Kompilieren und Verwenden von Ressourcenskripten . . . . . . . . . . . . .

202

10.3

Lokalisation von Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

10.4

Ressourcenvorlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

10.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

11

Zeichnen und Gertekontexte . . . . . . . . . . . . . . . . . . . . . . . 207

11.1

Das GDI, Gertetreiber und Ausgabegerte . . . . . . . . . . . . . . . . . . .

11.2

Gertekontexte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

11.3

Koordinaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11.4

Zeichenobjekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222

11.5

Clipping. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11.6

Zeichenfunktionen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234

11.7

Hinweise zum Drucken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

11.8

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

207

211

231

241

Inhaltsverzeichnis

12

Threads und Prozesse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

12.1

Multitasking in der Win32-Umgebung . . . . . . . . . . . . . . . . . . . . . . . 244

12.2

Programmierung mit Prozessen und Threads . . . . . . . . . . . . . . . . . . . 249

12.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

13

DLLs Dynamische Bibliotheken . . . . . . . . . . . . . . . . . . . . . 263

13.1

Arten von Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

13.2

Programmieren mit DLLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

13.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

14

Speicherverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

14.1

Prozesse und der Speicher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

14.2

Von 16- zu 32-Bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

14.3

Einfache Speicherverwaltung. . . . . . . . . . . . . . . . . . . . . . . . . . . . 279

14.4

Virtueller Speicher und erweiterte Speicherverwaltung . . . . . . . . . . . . . . 281

14.5

Threads und Speicherverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . 290

14.6

Zugriff auf den physikalischen Speicher und die E/A-Schnittstellen . . . . . . 292

14.7

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

15

Dateiverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

15.1

bersicht ber das Dateisystem . . . . . . . . . . . . . . . . . . . . . . . . . . 296

15.2

Win32-Dateiobjekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

15.3

Low-Level-Ein-/Ausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

15.4

Ein-/Ausgabestrom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307

15.5

Spezielle Gerte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309

15.6

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

Die Windows-Zwischenablage . . . . . . . . . . . . . . . . . . . . . . . 313

16.1

Die Formate der Zwischenablage. . . . . . . . . . . . . . . . . . . . . . . . . . 313

16.2

Zwischenablageoperationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316

311

Inhaltsverzeichnis

16.3

Eine einfache Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . 320

16.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324

17

Die Registrierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

17.1

Die Struktur der Registrierung . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

17.2

Manuelle Bearbeitung der Registrierung . . . . . . . . . . . . . . . . . . . . . 329

17.3

Allgemein verwendete Registrierungsschlssel . . . . . . . . . . . . . . . . .

330

17.4

Anwendungen und die Registrierung . . . . . . . . . . . . . . . . . . . . . . .

333

17.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338

18

Ausnahmebehandlung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341

18.1

Ausnahmebehandlung in C und C++ . . . . . . . . . . . . . . . . . . . . . . . .

18.2

C- und C++-Ausnahmefehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

18.3

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

341

Teil 3 Die MFC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355


19

Microsoft Foundation Classes: Eine bersicht . . . . . . . . . . . . 357

19.1

MFC und Anwendungen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357

19.2

MFC-Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359

19.3

Fensteruntersttzungsklassen . . . . . . . . . . . . . . . . . . . . . . . . . . . 364

19.4

Anwendungsarchitekturklassen . . . . . . . . . . . . . . . . . . . . . . . . . . 370

19.5

Verschiedene Klassen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373

19.6

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377

20

Das MFC-Anwendungsgerst . . . . . . . . . . . . . . . . . . . . . . . . 379

20.1

Ein einfaches MFC-Anwendungsgerst . . . . . . . . . . . . . . . . . . . . . .

379

20.2

Hinzufgen von Programmcode zur Anwendung . . . . . . . . . . . . . . . . .

398

20.3

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402

10

Inhaltsverzeichnis

21

Die Arbeit mit Dokumenten und Ansichten . . . . . . . . . . . . . . . 403

21.1

Die CDocument-Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403

21.2

Die CView-Klasse. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414

21.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420

22

Dialoge und Registerdialoge . . . . . . . . . . . . . . . . . . . . . . . . 423

22.1

Erstellen von Dialogen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424

22.2

Dialog-Datenaustausch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434

22.3

Dialoge und Nachrichtenbearbeitung . . . . . . . . . . . . . . . . . . . . . . . 438

22.4

Registerdialoge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439

22.5

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448

23

MFC-Untersttzung fr Standarddialoge und


Standardsteuerelemente . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451

23.1

Standarddialoge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452

23.2

Standardsteuerelemente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460

23.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473

24

Gertekontext und GDI-Objekte . . . . . . . . . . . . . . . . . . . . . . 477

24.1

Gertekontexte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

24.2

Untersttzung von GDI-Objekten in der MFC . . . . . . . . . . . . . . . . . . . 493

24.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499

25

Serialisierung: Datei- und Archivobjekte . . . . . . . . . . . . . . . . 501

25.1

Die CFile-Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501

25.2

Die CArchive-Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507

25.3

Serialisierung in MFC-Applikationsrahmen-Anwendungen . . . . . . . . . . . 513

25.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515

26

Container-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517

26.1

CObject-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517

26.2

Weitere Listen-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524

Inhaltsverzeichnis

11

26.3

Weitere Array-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525

26.4

Zuordnungen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526

26.5

Auf Templates basierende Objekt-Container . . . . . . . . . . . . . . . . . . .

26.6

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539

27

Ausnahmen, Multithreading und andere MFC-Klassen . . . . . . 541

27.1

Verwenden von Ausnahmen in MFC-Anwendungen . . . . . . . . . . . . . . .

542

27.2

MFC und Multithreading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

551

27.3

Weitere MFC-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556

27.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

531

561

Teil 4 Die Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563


28

OLE, ActiveX und das Komponentenobjektmodell . . . . . . . . . 565

28.1

OLE-Grundlagen und das Komponentenobjektmodell. . . . . . . . . . . . . .

28.2

OLE und Verbunddokumente. . . . . . . . . . . . . . . . . . . . . . . . . . . . 572

28.3

Anwendung von COM und OLE . . . . . . . . . . . . . . . . . . . . . . . . . . . 576

28.4

Ein einfaches Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578

28.5

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586

29

OLE-Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589

29.1

Server-Konzepte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589

29.2

Erstellen einer Server-Anwendung mit der MFC . . . . . . . . . . . . . . . . .

590

29.3

Bearbeiten eines Server-Gersts . . . . . . . . . . . . . . . . . . . . . . . . .

599

29.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605

30

OLE-Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607

30.1

Erstellen einer Container-Anwendung mit dem Anwendungsassistenten . . .

30.2

Bearbeiten der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620

30.3

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627

565

607

12

Inhaltsverzeichnis

31

OLE-Drag&Drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629

31.1

Drag&Drop-Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629

31.2

Erstellen einer Container-Anwendung . . . . . . . . . . . . . . . . . . . . . . . 630

31.3

Drag&Drop-Untersttzung hinzufgen . . . . . . . . . . . . . . . . . . . . . . 634

31.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643

32

Automatisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645

32.1

Erstellen eines Automatisierungs-Servers. . . . . . . . . . . . . . . . . . . . . 645

32.2

Standardmethoden und Standardeigenschaften . . . . . . . . . . . . . . . . . 659

32.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664

33

Erstellen von ActiveX-Steuerelementen mit der MFC . . . . . . . 667

33.1

Erstellen eines Steuerelementgersts mit dem Anwendungsassistenten . . . 669

33.2

Bearbeiten des Steuerelements . . . . . . . . . . . . . . . . . . . . . . . . . . 682

33.3

Hinzufgen eines Eigenschaftendialogs . . . . . . . . . . . . . . . . . . . . . . . 691

33.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696

34

Verwenden der ActiveX-Templatebibliothek . . . . . . . . . . . . . 697

34.1

Warum ATL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697

34.2

Erstellen eines ActiveX-Steuerelements mit der ATL . . . . . . . . . . . . . . . 699

34.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716

35

ActiveX-Steuerelemente verwenden . . . . . . . . . . . . . . . . . . . 717

35.1

Hinzufgen von ActiveX-Steuerelementen zu Ihrer Anwendung . . . . . . . . 719

35.2

Visual-C++-ActiveX-Steuerelemente . . . . . . . . . . . . . . . . . . . . . . . . 727

35.3

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728

Teil 5 Datenbankprogrammierung . . . . . . . . . . . . . . . . . . . . . . . . . 729


36

Datenbankprogrammierung mit ODBC. . . . . . . . . . . . . . . . . . 731

36.1

ODBC im Einsatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732

36.2

Der SQL-Standard und ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742

Inhaltsverzeichnis

13

36.3

ODBC in MFC-Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746

36.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 760

37

DAO Datenzugriffsobjekte . . . . . . . . . . . . . . . . . . . . . . . . . 761

37.1

DAO-bersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37.2

Erstellen einer DAO-Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . 763

37.3

DAO-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775

37.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779

38

OLE DB und ADO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781

38.1

OLE DB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 782

38.2

Ein OLE-DB-SDK-Arbeitsbeispiel . . . . . . . . . . . . . . . . . . . . . . . . . . 784

38.3

Ein OLE-DB-MFC-Anwendungsbeispiel . . . . . . . . . . . . . . . . . . . . . . 789

38.4

ActiveX-Datenobjekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797

38.5

bersicht der ADO-Objekte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797

38.6

Ein Arbeitsbeispiel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799

38.7

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802

39

Datenbank- und Abfragendesign, SQL-Debugging . . . . . . . . . 803

39.1

Visual-Datenbankwerkzeuge . . . . . . . . . . . . . . . . . . . . . . . . . . . . 803

39.2

Arbeiten mit einer Datenbank . . . . . . . . . . . . . . . . . . . . . . . . . . . 807

39.3

SQL Server anwenden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823

761

811

Teil 6 Internet- und Netzwerkprogrammierung . . . . . . . . . . . . . . . . 825


40

Anwenden der WinInet-API . . . . . . . . . . . . . . . . . . . . . . . . . 827

40.1

Internet-Protokolle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828

40.2

Die WinInet-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833

40.3

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839

14

Inhaltsverzeichnis

41

MFC-Internet-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 841

41.1

Internet-Untersttzungsklassen . . . . . . . . . . . . . . . . . . . . . . . . . . 841

41.2

Die MFC-Internet-Klassenarchitektur . . . . . . . . . . . . . . . . . . . . . . . 841

41.3

Aufbau von Internet-Verbindungen . . . . . . . . . . . . . . . . . . . . . . . . 842

41.4

MFC-Internet-Klassen in Anwendungen verwenden . . . . . . . . . . . . . . . 847

41.5

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 850

42

Nachrichtenfhige Anwendungen mit MAPI . . . . . . . . . . . . . . 851

42.1

Die Architektur von MAPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852

42.2

MAPI-APIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856

42.3

MAPI-Untersttzung in MFC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864

42.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865

43

TCP/IP-Programmierung mit WinSock. . . . . . . . . . . . . . . . . . 867

43.1

TCP/IP-Netzwerke und OSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867

43.2

Die WinSock-API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 874

43.3

Ein einfaches Beispiel mit WinSock . . . . . . . . . . . . . . . . . . . . . . . . 881

43.4

Programmieren mit Sockets und die Microsoft Foundation Classes . . . . . . 883

43.5

Weiterfhrende Informationen . . . . . . . . . . . . . . . . . . . . . . . . . . . 886

43.6

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 888

44

Telefonie-Anwendungen mit TAPI . . . . . . . . . . . . . . . . . . . . . . 891

44.1

bersicht zu TAPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 891

44.2

TAPI-Software-Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 896

44.3

TAPI-Dienste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900

44.4

Beispiel einer Datenkommunikation . . . . . . . . . . . . . . . . . . . . . . . . 905

44.5

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

911

Inhaltsverzeichnis

15

45

Netzwerkprogrammierung mit Pipes und Aufruf von


Remote Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913

45.1

Kommunizieren mit Pipes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

913

45.2

Ein Arbeitsbeispiel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

917

45.3

Microsoft Remote Procedure Calls. . . . . . . . . . . . . . . . . . . . . . . . .

919

45.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 929

Teil 7 Multimedia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931


46

Multimedia-Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . 933

46.1

Videos abspielen mit einem Funktionsaufruf . . . . . . . . . . . . . . . . . . .

934

46.2

Grundlagen der Multimedia-Programmierung . . . . . . . . . . . . . . . . . .

936

46.3

Programmieren mit MCIWnd . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938

46.4

Die Mediensteuerschnittstelle . . . . . . . . . . . . . . . . . . . . . . . . . . . 945

46.5

Fortgeschrittene Schnittstellen . . . . . . . . . . . . . . . . . . . . . . . . . .

46.6

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 953

47

Die Grafikbibliothek OpenGL . . . . . . . . . . . . . . . . . . . . . . . . 955

47.1

bersicht zu OpenGL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956

47.2

Erstellen von OpenGL-Windows-Anwendungen in C . . . . . . . . . . . . . . .

47.3

OpenGL in MFC-Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 965

47.4

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 970

48

Hochleistungsgrafik und Ton . . . . . . . . . . . . . . . . . . . . . . . . 973

48.1

Die APIs von DirectX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 974

48.2

Ein einfaches Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 982

48.3

Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 990

951

961

Teil 8 Anhnge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993


A

Erzeugen eigener Anwendungsassistenten . . . . . . . . . . . . . . 995

A.1

Wie funktioniert der Anwendungsassistent? . . . . . . . . . . . . . . . . . . .

996

16

Inhaltsverzeichnis

A.2

Ein Beispiel: der HelloWizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997

A.3

Weitere Eigenschaften des Anwendungsassistenten . . . . . . . . . . . . . . 1009

A.4

Zusammenfassung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1013

bersicht zu C/C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015

B.1

Der Prprozessor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015

B.2

Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1019

B.3

Kompilieren und Programmausfhrung . . . . . . . . . . . . . . . . . . . . . . 1035

Die Standard-Laufzeitbibliothek . . . . . . . . . . . . . . . . . . . . . . 1037

C.1

Zugriff auf Argumente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037

C.2

Manipulieren von Puffern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037

C.3

Klassifizieren der Bytes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038

C.4

Klassifizieren der Zeichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038

C.5

Datenumwandlung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038

C.6

Debug-Untersttzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038

C.7

Verzeichniskontrolle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038

C.8

Ausnahmebehandlung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1039

C.9

Dateibehandlung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1039

C.10

Untersttzung fr Fliekommazahlen . . . . . . . . . . . . . . . . . . . . . . . 1039

C.11

Eingabe und Ausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1040

C.12

Internationalisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1041

C.13

Speicherzuweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1041

C.14

Steuerung der Prozesse und der Umgebung . . . . . . . . . . . . . . . . . . . 1041

C.15

Suchen und Sortieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042

C.16

Strings manipulieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042

C.17

Systemaufrufe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042

C.18

Zeitverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1042

C.19

Die ANSI-C-Laufzeitbibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . 1043

Inhaltsverzeichnis

17

Die Standard-C++-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . 1057

D.1

Die C++-Laufzeitbibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1057

D.2

STL und MFC im Vergleich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1091

Zur CD-ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095

Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097
Stichwortverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1099

Die Entwicklungsumgebung

Teil I
1.
2.
3.
4.
5.
6.

Visual C++ und Visual Studio


Arbeitsbereiche und Projekte
Die Assistenten
Browser und Debugger
Optimierung
Wiederverwenden von Programmcode
mit der Komponentensammlung

Visual C++ und


Visual Studio

Kapitel
D

as Visual Studio 6.0, die aktuelle Version des Microsoft Developer Studios, stellt eine integrierte Entwicklungsumgebung dar,
in der die verschiedenen Visual-C++-Tools zur Anwendungsentwicklung (Quelltexteditor, Ressourceneditoren, Compiler, Linker, Debugger etc.) eingebettet sind. Der Vorteil fr Sie besteht darin, da Sie bei
der Anwendungserstellung nicht zwischen mehreren Dienstprogrammen mit eigenen Hauptfenstern hin- und herspringen mssen, sondern alle anfallenden Aufgaben direkt innerhalb der IDE erledigen knnen. Dabei kann das Visual Studio nicht nur Visual C++, sondern auch
anderen MS-Entwicklertools, wie z.B. Visual J++ als Front-End dienen
was insbesondere den Programmierern zugute kommt, die in mehreren Programmiersprachen gleichzeitig entwickeln.
An die Arbeit im Visual Studio gewhnt man sich recht schnell, doch
kann die komplexe Umgebung fr den Einsteiger etwas verwirrend
sein. Dieses Kapitel bietet Ihnen daher eine kurze bersicht ber den
Aufbau des Visual Studios, beschreibt den grundlegenden Ablauf einer
Arbeitssitzung mit dem Visual Studio und stellt Ihnen die interessantesten Neuerungen der 6.0-Version vor.

22

Kapitel 1: Visual C++ und Visual Studio

1.1

Visual Studio: berblick ber


die Entwicklungsumgebung

Abbildung 1.1:
Das Visual
Studio

Windows-Programme bestehen selten aus einer einzigen Datei. Meist


wird der Code auf mehrere Quelltextdateien verteilt, und je umfangreicher das Programm, um so mehr Quelltextdateien umfat es. Zu einer
leistungsfhigen Entwicklungsumgebung gehrt daher neben Compiler
und Editor auch eine Orientierungshilfe, die es dem Programmierer erlaubt, die bersicht ber die Dateien seines Programms zu behalten.
Im Visual Studio ist dies das Arbeitsbereichfenster, das standardmig
fr alle Projekte, die Sie im Visual Studio bearbeiten, angezeigt wird.
(In Abbildung 1.1 sehen Sie links das Arbeitsbereichfenster und rechts
ein maximiertes Editorfenster mit dem Inhalt der Quelldatei My.cpp.
Geffnet wurde die Datei durch Doppelklick auf den Dateinamen im
Arbeitsbereichfenster.)
Auer dem Arbeitsbereich- und den Editorfenstern gibt es noch weitere Fenster, die Ihnen im Visual Studio als Schnittstelle zu den in die
Entwicklungsumgebung integrierten Tools dienen.

23

Visual Studio: berblick ber die Entwicklungsumgebung

Das Arbeitsbereichfenster Projekte verwalten


Abbildung 1.2:
Das Arbeitsbereichfenster

Das Arbeitsbereichfenster dient der Verwaltung von Projekten und Arbeitsbereichen (siehe Kapitel 2). Gleichzeitig ist es die zentrale Schaltstelle, ber die man Quelltext- und Ressourcendateien zur Bearbeitung
in die jeweiligen Editoren laden kann. Haben Sie es einmal aus Versehen geschlossen, knnen Sie es ber den Befehl ANSICHT/ARBEITSBEREICH wieder einblenden lassen.
Das Arbeitsbereichfenster welches per Voreinstellung in den linken
Rahmen des Visual Studios integriert ist, aber auch frei im Visual Studio verschoben werden kann verfgt ber mehrere Registerseiten.
(Welche Registerseiten konkret angezeigt werden, hngt von der Art
des Projekts ab.)
Registerseite

Beschreibung

DATEIEN

Zeigt Ihnen die Arbeitsbereich-Hierarchie mit den zugehrigen Projekten und Quelldateien an. Mit den Befehlen
aus den Kontextmens der verschiedenen Knoten knnen
Sie die Quelldateien verwalten, Unterverzeichnisse fr die
Anzeige einrichten, die Projekte erstellen, Knoten konfigurieren.
Per Doppelklick auf eine Datei knnen Sie diese in einen
passenden Editor laden. Neue Dateien knnen Sie ber
den Befehl DATEI/NEU in ein Projekt aufnehmen. Bestehende Dateien knnen Sie ber den Befehl BEARBEITEN/
LSCHEN aus einem Projekt entfernen.

RESSOURCEN

Zeigt Ihnen die in den Ressourcendateien des Projekts abgelegten Ressourcen nach Ressourcentypen geordnet
an. Mit den Befehlen aus den Kontextmens der Knoten
knnen Sie neue Ressourcen anlegen, die Ressourcen-IDs
bearbeiten, etc.

Tabelle 1.1:
Die Registerseiten

24

Kapitel 1: Visual C++ und Visual Studio

Registerseite

Beschreibung
Per Doppelklick auf eine Ressource knnen Sie diese in
einen passenden Editor laden. Neue Ressourcen knnen
Sie ber den Befehl EINFGEN aus dem Kontextmen aufnehmen. Bestehende Ressourcen knnen Sie ber den
Befehl BEARBEITEN/LSCHEN entfernen.

KLASSEN

Gibt Ihnen einen berblick ber die in Ihrem Programm


deklarierten Klassen (einschlielich der Klassenelemente)
und globalen Symbole. Mit den Befehlen aus den Kontextmens der verschiedenen Knoten knnen Sie sich weitere
Informationen anzeigen lassen, in Deklarationen und Definitionen springen, Klassenelemente hinzufgen, Haltepunkte setzen, etc.
Ein Doppelklick auf einen Klassennamen ffnet die zugehrige Quelltextdatei, die die Klassendeklaration enthlt,
und setzt die Schreibmarke auf den Anfang der Klassendeklaration. Gleiches gilt sinngem fr Doppelklicke auf
Klassenelemente und globale Bezeichner.
Die Anzeige der Klassen und Klassenelemente wird stndig gem den nderungen an Ihren Quelltexten aktualisiert. Sowie Sie also ein Klassenelement in eine Klassendeklaration aufnehmen oder aus dieser entfernen,
bernimmt das Visual Studio diese nderung in die Klassenansicht.

In frheren Versionen verfgte das Arbeitsbereichfenster zustzlich


ber die Seite InfoView, die die Schnittstelle zum Hilfesystem bildete. In der 6.0-Version wurde die Integration des Hilfesystems in
die Entwicklungsumgebung aufgegeben. Die Hilfe wird zwar weiterhin ber das Hilfe-Men des Visual Studio aufgerufen, erscheint
dann aber in einem eigenen Hauptfenster.
Die Editorfenster Quelltexte und Ressourcen erstellen
Die Editorfenster dienen dem Aufsetzen und Bearbeiten von Quelltexten und Ressourcen. Um eine Datei in ein Editorfenster zu laden, bedient man sich blicherweise des Arbeitsbereichfensters, indem man in
der Dateien-Ansicht einfach auf den Knoten der zu ffnenden Datei
doppelklickt. Mchte man gezielt zur Deklaration einer Klasse oder der
Definition einer Elementfunktion einer Klasse springen, kann man diese in der Klassen-Ansicht des Arbeitsbereichfensters anklicken.

Visual Studio: berblick ber die Entwicklungsumgebung

25

Abbildung 1.3:
Anweisungsvervollstndigung

Der Quelltexteditor verfgt ber eine bersichtliche Syntaxhervorhebung sowie neuerdings eine Anweisungsvervollstndigung, d.h., der
Editor kann Ihnen whrend des Eintippens Ihres Quellcodes Vorschlge fr anzusprechende Klassen/Strukturelemente oder Aufrufparameter machen (siehe Abbildung 1.3).
C Wenn Sie nach dem Namen einer Klasseninstanz einen Zugriffsoperator (., ->) eintippen, springt ein Listenfeld auf, in dem die
verschiedenen Elemente der Klasse aufgefhrt werden. Wenn Sie
weitertippen, wird das Listenfeld zu dem Eintrag gescrollt, der Ihrer bisherigen Buchstabenfolge am besten entspricht. Durch Drkken der Eingabetaste knnen Sie das aktuell ausgewhlte Listenelement in den Quelltext einfgen lassen, wobei etwaige
Tippfehler in Ihrer Buchstabenfolge korrigiert werden.
C Wenn Sie nach einem Funktionsnamen eine ffnende Klammer
eingeben, springt ein Listenfeld auf, in dem Ihnen die zu der Funktion gehrenden Parameter angezeigt werden eine Option, die
Ihnen ab und an das Nachschauen in der Online-Hilfe ersparen
kann. Die Parameteranzeige untersttzt auch berladene Funktionen.
C Zur Konfiguration des Quelltexteditors rufen Sie den Befehl EXTRAS/OPTIONEN auf.

26

Kapitel 1: Visual C++ und Visual Studio

Abbildung 1.4:
Ressourceneditor fr Symbole

Wenn Sie eine bestimmte Ressource erstellen oder zur Bearbeitung


ffnen, wird automatisch der zu dem jeweiligen Ressourcentyp passende Ressourceneditor geladen (siehe Abbildung 1.4).
Je nach Art und Konfiguration des aufgerufenen Ressourceneditors
wird die Menstruktur des Ressourceneditors in die Menleiste des Visual Studios integriert (fr den Symboleditor beispielsweise die PopupMens EINFGEN und BILD) und es werden die zugehrigen Werkzeugleisten angezeigt.
Das Ausgabefenster der Compiler meldet sich
Abbildung 1.5:
Das Ausgabefenster

Das Ausgabefenster wird von verschiedenen integrierten Tools zur


Ausgabe von Meldungen verwendet. Fr die verschiedenen Tools werden jeweils eigene Seiten verwendet. Die Ausgaben des Compilers und
des Linkers erscheinen beispielsweise auf der Seite ERSTELLEN, die Debug-Ausgaben werden auf die Seite DEBUG umgeleitet, etc.
Per Voreinstellung ist das Ausgabefenster in den unteren Rahmen des
Visual Studios integriert.
Die Debug-Fenster Status eines Programms kontrollieren
Der Debugger verfgt ber eine ganze Reihe von Ausgabefenster, die
Sie bei der berwachung des debuggten Programms untersttzen und
in denen Sie jeweils verschiedene Informationen zum Status Ihres Programms abfragen knnen.

Visual Studio: berblick ber die Entwicklungsumgebung

27

Die einzelnen Fenster knnen ber den Befehl ANSICHT/DEBUG-FENSTER aufgerufen werden und werden im Kapitel 4 besprochen. Die
Men-Befehle des Debuggers finden Sie im Popup-Men DEBUG, das
kurz nach Beginn einer Debug-Sitzung (Befehl ERSTELLEN/DEBUG
STARTEN) eingeblendet wird.
Auch der Quelltexteditor arbeitet mit dem Debugger zusammen. Whrend einer Debug-Sitzung knnen Sie beispielsweise den Inhalt von
Variablen abfragen, indem Sie den Mauszeiger einfach auf ein Vorkommen des entsprechenden Variablennamens bewegen. (Voraussetzung ist, da die Variable in dem Gltigkeitsbereich, in dem das Programm angehalten wurde, gltig ist.)
Die Assistentenleiste
Abbildung 1.6:
Die Assistentenleiste

Die Assistentenleiste gehrt zu den Symbolleisten des Developer Studios. Sie besteht aus drei Listenfeldern, die der Auswahl einer Klasse
oder einer Klassenmethode dienen, und einer Befehlsliste (Pfeilsymbol
am rechten Ende der Leiste). Mit den Befehlen dieser Liste knnen Sie
zur Deklaration oder Definition der ausgewhlten Klassenmethode
oder Klasse springen, Klassen neu anlegen oder Klassen um Methoden
erweitern.
1. Lassen Sie die Assistentenleiste anzeigen. Die Assistentenleiste
aktivieren Sie ber das Kontextmen des Developer Studios (klikken Sie beispielsweise in den Hintergrund einer der angezeigten
Symbolleisten).
2. Markieren Sie eine Klasse. Whlen Sie die Klasse im ersten Listenfeld (C++-Klasse der Assistentenleiste) aus.
3. Markieren Sie eine Methode. Whlen Sie eine Methode im dritten
Listenfeld (C++-Elemente der Assistentenleiste) aus.
4. Rufen Sie einen passenden Befehl auf. Klicken Sie zum Aufruf der
Befehlsliste auf das rechts gelegene Pfeilsymbol.

28

Kapitel 1: Visual C++ und Visual Studio

1.2

Die grundlegenden
Arbeitsschritte

Der Umstieg von einem Compiler auf einen anderen ist stets mit einer
gewissen Eingewhnungszeit verbunden die sich um so lnger hinzieht, je deutlicher sich die Arbeitsumgebung des bis dato verwendeten
Compilers von der neuen Arbeitsumgebung unterscheidet. Um all denjenigen Lesern, die zum ersten Mal mit dem Visual-C++-Compiler arbeiten, den Einstieg zu erleichtern, sollen in diesem Abschnitt anhand
der Erstellung eines kleinen Beispielprogramms die grundlegenden Arbeitsschritte und die Einbindung der verschiedenen Entwicklertools des
Visual Studios in den Erstellungsproze demonstriert werden.
Abbildung 1.7:
Das Fenster des
Beispielprogramms

Bei dem im folgenden zu erstellenden Beispielprogramm handelt es


sich um ein Windows-Programm, das aus wenig mehr als einem
Hauptfenster besteht und mit Hilfe der MFC (aber ohne Assistentenuntersttzung, siehe Kapitel 3) implementiert wird.
1. Schritt: Projekt anlegen
Die Arbeit an einem neuen Programm beginnt immer mit dem Anlegen eines Projekts. In dem Projekt werden die verschiedenen Dateien
des Programms (Quelltextdateien (.cpp), Header-Dateien (.h), Ressourcedateien (.res, etc.) u.a.) verwaltet. ber die Projekteinstellungen wird
festgelegt, wie die Dateien des Projekts zu einer ausfhrbaren Datei
kompiliert und gelinkt werden sollen. Fr jede ausfhrbare Datei (.exe
oder .dll) bentigt man ein eigenes Projekt. Projekte selbst werden in
Arbeitsbereichen verwaltet was vor allem dann interessant ist, wenn
zu einem Programm mehrere ausfhrbare Dateien gehren.

Die grundlegenden Arbeitsschritte

Als Ausgangspunkt fr das Beispielprogramm werden zuerst ein Anwendungsbereich und ein leeres Projekt erstellt:
1. Rufen Sie den Befehl DATEI/NEU auf, und markieren Sie auf der
Seite Projekte den Eintrag WIN32-ANWENDUNG.
2. Geben Sie auf der rechten Seite des Dialogfensters einen Titel fr
das Projekt ein (bspw. Hallo), whlen Sie das bergeordnete Verzeichnis aus, und lassen Sie einen zugehrigen, neuen Arbeitsbereich erstellen.
3. Lassen Sie von dem Assistenten ein leeres Projekt erstellen und
wechseln Sie dann in die DATEIEN-Ansicht des Arbeitsbereichfensters.
4. ber den Menbefehl PROJEKT/DEM PROJEKT HINZUFGEN/NEU
(oder alternativ DATEI/NEU) legen Sie innerhalb des Projekts eine
C++-Quellcodedatei (namens Applik.cpp) und eine C/C++-Header-Datei (namens Applik.h) an.
2. Schritt: MFC einbinden
Standardmig werden Win32-Anwendungs-Projekte ohne Einbindung der MFC erstellt. Da aber kein API-Programm, sondern ein
MFC-Programm erstellt werden soll, mu fr die Einbindung der MFC
gesorgt werden:
1. Rufen Sie das Dialogfenster PROJEKTEINSTELLUNGEN auf (Befehl
PROJEKT/EINSTELLUNGEN), und whlen Sie im Feld MICROSOFT
FOUNDATION CLASSES auf der Seite ALLGEMEIN eine der Optionen
zur Verwendung der MFC aus. (Links im Dialogfeld mu der Projektknoten HALLO ausgewhlt sein.)
2. Fhren Sie diese Einstellung fr die Debug- und die Release-Version durch.
3. Schritt: Quellcode aufsetzen
Das Grundgerst der Anwendung besteht aus einem Anwendungs- und
einem Rahmenfensterobjekt.
Das Anwendungsobjekt. Zuerst mssen die bentigten Header-Dateien per Include-Anweisung eingebunden und ein Objekt fr die Anwendung erstellt werden.
1. Doppelklicken Sie im Arbeitsbereichfenster auf den Knoten der
Header-Datei (Applik.h).
2. Nehmen Sie per Include-Anweisung die Deklarationen der MFCKlassen auf.

29

30

Kapitel 1: Visual C++ und Visual Studio

3. Leiten Sie eine eigene Anwendungsklasse von der MFC-Klasse


CWinApp ab. berschreiben Sie in dieser Klasse die Methode InitInstance().
// Header-Datei Applik.h
#include <afxwin.h>
class CMyApp : public CWinApp {
public:
virtual BOOL InitInstance();
};

4. In der Quelltextdatei mssen Sie ein Objekt Ihrer Anwendungsklasse erzeugen und fr die Implementierung der berschriebenen
Elementfunktion InitInstance() sorgen.
// Quelltextdatei Applik.cpp
#include "Applik.h"
// Anwendungs-Objekt erzeugen
CMyApp Anwendung;
// Anwendung initialisieren
BOOL CMyApp::InitInstance()
{
return TRUE;
}

Das Hauptfenster. Der nchste Schritt besteht darin, ein Fenster als
Schnittstelle zum Anwender einzurichten. Wir begngen uns hier mit
einem Rahmenfenster (ohne untergeordnete View-Fenster).
1. In der Header-Datei wird von CFrameWnd eine eigene Rahmenfensterklasse abgeleitet und ein Konstruktor deklariert:
// Header-Datei Applik.h
#include <afxwin.h>
class CRahmenfenster : public CFrameWnd {
public:
CRahmenfenster();
};

2. In der Quelltextdatei wird die Definition des Konstruktors aufgesetzt und in der CMyApp-Methode InitInstance() fr die Erzeugung
und Anzeige des Fensters gesorgt.
Im Konstruktor wird die Methode Create() aufgerufen, die fr die
Anmeldung und Einrichtung des Fensters unter Windows sorgt:
CRahmenfenster::CRahmenfenster()
{
LPCTSTR classname = NULL;
// Fenster erzeugen
Create(classname,
"Erstes Programm",
WS_OVERLAPPEDWINDOW,
rectDefault,
0,

//
//
//
//
//

0 fr MFC-Vorgabe
Titel
Stil
keine def. Groesse
kein bergeordn. Fenster

Die grundlegenden Arbeitsschritte

0,
0,
0);

// kein Men
// kein erw. Stil
// kein Doc/View

3. In der CMyApp-Methode InitInstance() wird der Konstruktor der


Rahmenfensterklasse aufgerufen und somit das Rahmenfensterobjekt erzeugt.
Damit die Anwendung zusammen mit dem Hauptfenster geschlossen wird, mu der zurckgelieferte Zeiger an das CMyApp-Datenelement m_pMainWnd bergeben werden (beachten Sie, da damit eine
Umwandlung in ein Objekt der Klasse CWinThread verbunden ist).
Zum Anzeigen des Fenster wird die Methode ShowWindow() aufgerufen.
// Anwendung initialisieren
BOOL CMyApp::InitInstance()
{
// Rahmenfenster-Objekt erzeugen und Fenster anzeigen
CRahmenfenster *pMainWnd = new CRahmenfenster;
m_pMainWnd = pMainWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}

4. Schritt: Ressource bearbeiten


Unter Windows verfgt blicherweise jedes Programm ber ein Symbol (Ikon) zur grafischen Prsentation. Windows verwendet dieses
Symbol in verschiedenen Kontexten (Titel des Hauptfensters, Anzeige
in Explorer, Task-Leiste) in jeweils verschiedenen Gren. Aufgabe jeder ordentlichen Windows-Anwendung ist es daher, ein entsprechendes Symbol bereitzustellen.
Erstellen Sie zuerst die Bitmap fr das Anwendungssymbol
1. ber den Menbefehl PROJEKT/DEM PROJEKT HINZUFGEN/NEU
legen Sie innerhalb des Projekts ein Ressourcenskript (namens
Applik.rc) an.
2. In die Ressourcenskriptdatei fgen Sie ber den Befehl EINFGEN
aus dem Kontextmen des Applik.rc-Knotens eine neue Icon-Ressource ein.
3. Zeichnen Sie Ihr Symbol.
4. Speichern Sie die Ressource und die Ressourcenskriptdatei. Der
Ressourceneditor legt daraufhin automatisch eine .ico-Datei fr das
Symbol und eine resource.h-Datei mit der Deklaration der Ressourcen-IDs an.

31

32

Kapitel 1: Visual C++ und Visual Studio

Danach wird das Symbol mit der Anwendung verbunden


1. Machen Sie die Ressourcen-IDs in Ihrem Programm bekannt,
indem Sie eine entsprechende Include-Anweisung in die HeaderDatei Applik.h aufnehmen. (Wenn Sie mchten, knnen Sie die
Header-Datei resource.h zudem ber den Befehl PROJEKT/DEMPROJEKT HINZUFGEN/DATEIEN in Ihre Projektverwaltung aufnehmen.)
2. Im Konstruktor der Rahmenfensterklasse mu das Symbol mit dem
Fenster verbunden werden. Zu diesem Zweck wird zuerst
die Icon-Ressource geladen (AfxFindResourceHandle und LoadIcon),
dann wird mit Hilfe der Funktion PreCreateWindow die Windows-Klasse abgefragt, die das MFC-Gerst bereits fr das
Hauptfenster der Anwendung vorgesehen hat,
schlielich wird eine Kopie dieser Fensterklasse erzeugt, mit
dem Icon verbunden und mit Hilfe der Funktion AfxRegisterWndClass registriert.
Beim Aufruf der Funktion Create() wird das Rahmenfenster
nunmehr nach Magabe dieser Fensterklasse und somit auch
mit dem fr diese Fensterklasse definierten Symbol erzeugt.
CRahmenfenster::CRahmenfenster()
{
LPCTSTR classname = NULL;
HINSTANCE hInst = AfxFindResourceHandle(IDI_ICON1,
RT_GROUP_ICON);
HICON hIcon = ::LoadIcon(hInst,
MAKEINTRESOURCE(IDI_ICON1));
if(hIcon != NULL)
{
CREATESTRUCT cs;
memset(&cs, 0, sizeof(CREATESTRUCT));
PreCreateWindow(cs);
WNDCLASS wndcls;
if (cs.lpszClass != NULL &&
GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass,
&wndcls) )
{
// register a very similar WNDCLASS
classname = AfxRegisterWndClass(wndcls.style,
wndcls.hCursor,
wndcls.hbrBackground, hIcon);
}
}
// Fenster erzeugen
Create(classname, "Erstes Programm (ohne Doc/View)");
}

Kommandozeilen-Hilfsmittel

ber weitere Mglichkeiten zur Konfiguration eines Fensters knnen Sie sich unter den Stichwrtern PreCreateWindow, CREATESTRUCT,
LoadFrame, SetClassLong in der Online-Hilfe informieren.
5. Schritt: Kompilieren
Kompilieren Sie das Projekt, und fhren Sie das Programm aus.
1. Rufen Sie dazu einfach den Befehl ERSTELLEN/AUSFHREN VON...
((Strg) + (F5)) auf.
6. Schritt: Debuggen
Sollten Fehler bei der Ausfhrung des Programms auftreten, versuchen
Sie es zu debuggen (siehe Kapitel 4). Zur Ausfhrung des Programms
unter Kontrolle des Debuggers rufen Sie den Befehl ERSTELLEN/DEBUG STARTEN/AUSFHREN auf ((F5)).
7. Schritt: Fertige Version erstellen
Ist das Programm fertig und luft fehlerfrei, sollten Sie eine ReleaseVersion erstellen.
Standardmig werden vom Visual Studio fr jedes Projekt zwei Konfigurationen angelegt: eine Debug- und eine Release-Version. Die Debug-Version ist so eingestellt, da bei der Kompilation spezielle DebugInformationen mit in die Zieldatei (.exe, .dll) aufgenommen werden.
Bei der Release-Version wird dagegen auf die Debug-Informationen
verzichtet. Statt dessen wird der Code vom Compiler optimiert.
1. Rufen Sie den Befehl ERSTELLEN/AKTIVE KONFIGURATION FESTLEGEN auf, und whlen Sie im erscheinenden Dialogfeld die ReleaseKonfiguration.
2. Lassen Sie das Projekt danach neu erstellen. Die resultierende
EXE-Datei wird standardmig in dem Unterverzeichnis Release
abgelegt.

1.3

Kommandozeilen-Hilfsmittel

Obwohl Visual Studio die Schnittstelle fr den Zugriff auf die Features
von Viusal C++ bildet, knnen der C/C++-Compiler und andere
Komponenten auch ber die Kommandozeile gesteuert werden. Diese
Vorgehensweise ist bisweilen mit einem geringeren Aufwand verbunden als der Weg ber die integrierte Entwicklungsumgebung, so z.B.,
wenn einfache Testprogramme kompiliert werden sollen. Dann ist

33

34

Kapitel 1: Visual C++ und Visual Studio

man mit der Eingabe einiger einfacher Kommandozeilenanweisungen


wie z.B. cl myprog.c wesentlich schneller am Ziel und kann sich das
Einrichten und Konfigurieren eines Visual-C++-Projekts, das Hinzufgen von Dateien zu dem Projekt sowie das Kompilieren und Ausfhren
in der Entwicklungsumgebung sparen.
Wann jedoch wrden Sie Kommandozeilen-Hilfsmittel verwenden? Ich
mchte Ihnen dazu gerne einige Anregungen geben: Ist Ihr Projekt
derart komplex, da eine Make-Datei erforderlich ist, verwenden Sie
die Entwicklungsumgebung mit der integrierten Projektverwaltung.
Mchten Sie Ihr Programm interaktiv debuggen oder verfgt Ihr Programm ber eine umfangreiche Ressourcendatei, sollten Sie ebenfalls
die Entwicklungsumgebung verwenden.
Wenn Sie jedoch lediglich ein Beispiel mit zehn Zeilen aus einem Buch
eingeben und testen, sind die Kommandozeilen-Hilfsmittel vllig ausreichend. Viele Beispiele dieses Buches knnen bequemer ber die
Kommandozeile kompiliert werden (natrlich knnen diese auch in ein
Visual-C++-Projekt geladen werden).
Die Ausfhrung einiger Kommandozeilen-Hilfsmittel ist von dem Pfad
der entsprechenden Visual-C++-Verzeichnisse sowie von korrekt eingerichteten
Umgebungsvariablen
abhngig.
Verwenden
Sie
Windows NT als Entwicklungsplattform, bietet Ihnen das Installationsprogramm die Registrierung der Umgebungsvariablen an, so da diese
automatisch in dem Fenster der Eingabeaufforderung aufgefhrt werden. Arbeiten Sie mit Windows 95, mssen Sie die Batch-Datei
VCVARS32.BAT
ausfhren lassen (Verzeichnis PROGRAMME\DEVSTUDIO\VC\BIN), um die Variablen zu registrieren und
mit den Kommandozeilen-Hilfsmitteln arbeiten zu knnen. Beachten
Sie bitte, da Sie mglicherweise die Umgebungswerte fr das DOSFenster vergrern mssen (selektieren Sie dazu den Eintrag EIGENSCHAFTEN aus dem Systemmen des DOS-Fensters, und ffnen Sie
dort das Register SPEICHER), bevor VCVARS32.BAT erfolgreich ausgefhrt werden kann.
Der C/C++-Compiler
Der Visual-C++-Compiler wird mit der Anweisung cl ber die Kommandozeile aufgerufen. Werden dem Compiler lediglich der Name der
Quelldatei und keine weiteren Parameter bergeben, kompiliert er die
Datei und ruft anschlieend den Linker auf, um die ausfhrbare Datei
zu erstellen.
Wenn Sie in der Kommandozeile die Namen von Objektdateien oder
Bibliothekdateien angeben, werden diese dem Linker bergeben.

Kommandozeilen-Hilfsmittel

CL HELLO.C MYFUNC.OBJ MYLIB.LIB


Geben Sie diese Zeile ein, kompiliert der Visual-C++-Compiler HELLO.C und ruft anschlieend den Linker mit den Dateien HELLO.OBJ
und MYFUNC.OBJ auf. Auerdem bergibt der Compiler den Namen
der Bibliothekdatei MYLIB.LIB an den Linker, der die darin enthaltene Bibliothek und alle Standardbibliotheken verwenden wird, um nach
Bibliotheksfunktionen zu suchen.
Mchten Sie lediglich eine Datei kompilieren, ohne daraus eine ausfhrbare Datei erzeugen zu lassen, verwenden Sie die Option /c:
CL /C HELLO.C
Beachten Sie bitte, da Sie sowohl den Schrgstrich als auch den Bindestrich verwenden knnen, um Kommandozeilen-Optionen anzugeben.
Weitere ntzliche Optionen sind:
C /MT (mit der Multithread-Version der Laufzeitbibliothek binden)
C /MD (mit der DLL-Version der Laufzeitbibliothek binden)
C /LD (erstellt eine DLL)
C Weitere Optionen knnen Sie durch Eingabe von cl /? anzeigen
lassen
Mchten Sie komplexe Optionen bestimmen, sollten Sie von Visual
Studio aus kompilieren.
Die von dem Visual-C++-Compiler generierten Objektdateien werden
im COFF-Dateiformat abgelegt (Common Object File Format).
Der Linker
Der Linker LINK.EXE ist ein Programm, dem Dateien im COFF-Format, 32-Bit-Objektmodulformat (OMF), Bibliothekdateien und andere
Dateien bergeben werden knnen. Er erzeugt daraus ausfhrbare
Win32-Dateien oder DLLs. Die folgende Zeile zeigt einen einfachen
Aufruf des Linkers mit einer Objektdatei:
LINK HELLO.OBJ
Der Linker akzeptiert viele Kommandozeilen-Optionen. Eine dieser
Optionen ist /subsystem, die den Typ der zu erzeugenden ausfhrbaren Datei angibt. Bestimmen Sie beispielsweise die Option /subsystem:windows, wird eine ausfhrbare Windows-Datei erstellt. Gewhnlich mu diese Option jedoch nicht angegeben werden. Die
Voreinstellung des Linkers lautet entweder /subsystem:console, wenn

35

36

Kapitel 1: Visual C++ und Visual Studio

die Objektdatei eine Definition der Main-Funktion (oder der UnicodeZeichenversion WMain) enthlt, oder /subsystem:windows, wenn eine
WinMain- oder wWinMain-Funktion vorhanden ist.
Mchten Sie eine DLL anstelle einer ausfhrbaren Datei erstellen, benutzen Sie die Option /DLL. Diese Option wird automatisch verwendet, wenn der Linker von dem Compiler aufgerufen und diesem die
Option /MD bergeben wurde.
Andere Optionen steuern, wie die bergebenen Dateien bearbeitet
werden, welche Standardbibliotheken verwendet werden sollen und
bestimmen weiterhin den Typ und den Inhalt der Ausgabedateien. Zustzlich zu den ausfhrbaren Dateien kann der Linker Debug-Dateien
(wie z.B. Map-Dateien) erzeugen. Sie knnen auerdem bestimmen,
ob die ausfhrbare Datei Debug-Informationen enthalten soll oder
nicht.
Der Bibliothekmanager
Der Bibliothekmanager LIB.EXE wird zur Erstellung von Bibliotheken
aus COFF-Objektdateien verwendet. Er kann auerdem zur Erzeugung
von Exportdateien und Importbibliotheken fr DLLs genutzt werden.
LIB.EXE wird gewhnlich mit mehreren Objektdateinamen ber die
Kommandozeile aufgerufen. Das Programm verwendet den Namen
der ersten Objektdatei als Dateiname fr die Bibliothekdatei und erstellt (oder aktualisiert) eine Bibliothek, die aus den angegebenen Objektdateien besteht. Der Name der Ausgabedatei kann mit Hilfe der
Option /OUT berschrieben werden.
Mit der Option /REMOVE knnen Sie spter Objektdateien aus der Bibliothek entfernen. Die Option /EXTRACT wird zum Extrahieren der
Inhalte einer Objektdatei in eine gesonderte Datei verwendet.
Um mit dem Bibliothekmanager eine Ausgabedatei und eine Eingabebibliothek zu erstellen, verwenden Sie die Option /DEF. Beachten Sie
bitte, da Sie diese Option nur gelegentlich nutzen werden, da der Linker die Exportdatei und Eingabebibliothek gewhnlich automatisch erzeugt. Der Bibliothekmanager wird berwiegend in Situationen eingesetzt, die das Exportieren aus sowie das Importieren in derselben
Bibliothek verlangen.
NMAKE
Das Hilfsmittel zur Programmberprfung, das kurz Make-Werkzeug
genannt wird (NMAKE.EXE), berprft die Abhngigkeiten in MakeDateien und fhrt Befehle zur Programmgenerierung aus. Eine einfache Make-Datei knnte wie folgt aufgebaut sein:

Kommandozeilen-Hilfsmittel

test.exe:
link
test.obj:
cl /c

test.obj
test.obj
test.c
test.c

In allen Make-Dateien berprft das Make-Werkzeug die generierten


Dateien in der Reihenfolge ihrer Abhngigkeiten und aktualisiert die
Dateien, wenn diese lter als deren Abhngigkeiten sind.
Zustzlich zu den Zieldateien und Abhngigkeiten knnen Make-Dateien weitere Features enthalten, wie z.B. Makros und Ableitungsregeln.
Diese Features machen Make-Dateien zu leistungsfhigen und flexiblen
Werkzeugen.
Wichtige Optionen von NMAKE.EXE sind /a (alle Zieldateien uneingeschrnkt erstellen), /n (das Make-Werkzeug zeigt Befehle lediglich an
und fhrt diese nicht aus) und /f (bestimmt den Namen der Make-Datei).
Andere Kommandozeilen-Hilfsmittel
Weitere Kommandozeilen-Hilfsmittel, die mit Visual C++ ausgeliefert
werden, sind rc.exe, bscmake.exe, dumpbin.exe, aviedit.exe und
editbin.exe.
Der Ressource-Compiler rc.exe kompiliert Ressource-Dateien und bereitet diese fr die Anbindung an die Objektdateien Ihres Projekts vor.
Sie bergeben dem Ressource-Compiler in der Kommandozeile den
Namen der Ressource-Datei (mit der Endung .rc) und optionale Schalter. Ihnen stehen die Schalter /d (definiert ein Symbol fr den Prprozessor), /fo (spezifiziert den Namen der Ausgabedatei) und /v (fr die
ausfhrliche Ausgabe) zur Verfgung. Sie erhalten eine vollstndige
Liste der Kommandozeilen-Optionen, indem Sie rc.exe mit der Option
/? ausfhren lassen.
Das Browse-Informationswerkzeug bscmake.exe wird verwendet, um
Browse-Informationsdateien (BSC) aus SBR-Dateien zu erzeugen, die
wiederum whrend des Kompilierens erstellt werden. Visual Studio
kann Browse-Informationsdateien anzeigen.
Der Binrdateimonitor dumpbin.exe zeigt Informationen ber COFFObjektdateien an.
aviedit.exe ist ein einfaches Programm zur Bearbeitung von AVI-Dateien. Verwenden Sie diese Anwendung, um eine Animationsdatei aus
mehreren Bitmaps zu generieren.
Der Binrdatei-Editor editbin.exe wird verwendet, um bestimmte Eigenschaften von COFF-Objektdateien einzusehen und zu modifizieren.

37

38

Kapitel 1: Visual C++ und Visual Studio

Einige Optionen dieses Programms sind das Verndern der Basisadresse einer Datei sowie das ndern der Standard-Heap-Gre und
der Standard-Stack-Gre.

1.4

Neuerungen in der
Version 6.0

Die 6.0-Version des Visual C++-Compilers wurde in mancherlei Hinsicht verbessert und mit einer Vielzahl zustzlicher Optionen ausgestattet. Statt die neuen Optionen und Mglichkeiten einzeln aufzulisten,
mchte ich Sie gezielt auf einige ausgesuchte Neuerungen hinweisen.
Compiler
C Der Compiler ist schneller geworden: laut Hersteller gegenber Visual C++ 5.0 sogar um bis zu 30%.
C Mit dem Schlsselwort __forceinline kann der Programmierer die
Inline-Kompilierung von Funktionen erzwingen, sofern eine InlineKompilierung nur irgendwie mglich ist (siehe Online-Hilfe). Ausgesuchte Funktionen knnen damit beispielsweise effektiver vor
Crackern geschtzt werden.
Editor und Arbeitsbereich
C Der Quelltexteditor bietet eine interaktive Hilfe zur Anweisungsvervollstndigung.
C Die Klassen-Ansicht basiert fortan nicht mehr auf den kompilierten
Dateien, sondern zieht sich ihre Informationen direkt aus den
Quelltexten. Die Anzeige wird daher whrend der Bearbeitung der
Quelltexte stndig aktualisiert.
Debugger
C Der Programmierer kann nun whrend des Debuggens Code abndern und dann ohne erneute Kompilierung den genderten
Code austesten.
C Die Optionen zur Darstellung und Formatierung verschiedener Variablen (Varianten, GUIDs, Funktionszeiger etc.) wurden ausgeweitet und verbessert.
Assistenten
C Anwendungs- und Klassenassistent wurden ausgebaut.
C Neue Assistenten und Projekttypen sind hinzugekommen.

Zusammenfassung

MFC
Die MFC wurde um eine Reihe von Klassen erweitert, insbesondere
um Klassen fr
C die Internet-Explorer-4.0-Steuerelemente
C eine HTML-View
C OLE DB-Klassen
Tools
C Die Enterprise-Edition wird mit dem Visual Modeler ausgeliefert.
Der Visual Modeler ist ein CASE-Tool fr OOD (objektorientiertes
Design), verfgt im Vergleich zu professionellen Tools allerdings
nur ber einen sehr eingeschrnkten Leistungsumfang.
Hilfe
C Die Online-Hilfe wurde ganz auf MSDN umgestellt.
Wenn Sie sich detailliert ber die Neuerungen in der 6.0-Version
des Visual C++-Compilers informieren wollen, schlagen Sie bitte in
der Online-Hilfe (MSDN) unter dem Ordner zu Visual C++ nach.

1.5

Zusammenfassung

Visual Studio ist der Kern des Visual-C++-Entwicklungssystems. Es bildet eine grafische Schnittstelle zu den wichtigsten Tools der Anwendungsentwicklung, beispielsweise:
C der Projektverwaltung (Arbeitsbereichfenster und Men PROJEKT)
C dem Quelltexteditor (Editorfenster und Men BEARBEITEN)
C den Ressourceneditoren (Editorfenster und verschiedene Mens)
C dem Compiler (Ausgabefenster und Men ERSTELLEN)
C dem Debugger (Debug-Fenster und Men DEBUG)
Eine groe Anzahl verschiedener Visual-C++-Komponenten knnen
auch ber die Kommandozeile aufgerufen werden. Ein einfaches Programm mit der Bezeichnung HELLO kann beispielsweise mit der Anweisung cl hello.c kompiliert werden. Weitere Kommandozeilen-Hilfsmittel sind der Linker, der Bibliothekmanager und das Hilfsmittel zur
Programmberprfung (Make-Werkzeug).

39

Arbeitsbereiche
und Projekte

Kapitel

rere Programme sind zumeist in mehrere Module aufgeteilt,


d.h. Quelltexteinheiten, die jeweils fr sich kompiliert werden
und dann erst vom Linker zu einer ausfhrbaren Datei zusammengebunden werden. Die Erstellung eines solchen Programms kann sehr
aufwendig sein:
C Die einzelnen Quelltexteinheiten mssen einzeln kompiliert werden,
C unter Umstnden bedrfen die einzelnen Einheiten individueller
Compiler-Einstellungen,
C verschiedene Quelltexte bedrfen unterschiedlicher Compiler (z.B.
Ressourcen-Compiler fr Windows-Ressourcen),
C beim Linken mssen alle einzubindenden Objektdateien angegeben werden etc.
Um sich die wiederholte Tipparbeit zu sparen, arbeiten die meisten
Compiler mit Make-Dateien, in denen die Einstellungen festgehalten
werden. Die Projektverwaltung von Visual C++ geht noch darber hinaus, indem Ihnen die Erstellung dieser Make-Dateien abgenommen
wird. Smtliche Informationen zu dem Projekt werden in der .dsp-Datei des Projekts abgespeichert.
Der Aufbau des Projekts wird im Arbeitsbereichfenster, Seite DATEIEN,
grafisch angezeigt. ber die Befehle in den Mens DATEI und PROJEKT
sowie die Kontextmens der Seite DATEIEN des Arbeitsbereichfensters
knnen Sie Ihre Projekte bearbeiten, Dateien hinzufgen oder entfernen, die Kompilierung beeinflussen, das Projekt konfigurieren, etc.
und die entsprechenden nderungen werden automatisch in der .dspDatei festgehalten und zur Erstellung des Projekts herangezogen. Die

Projektdateien
enthalten die
Informationen
zur Programmerstellung

42

Kapitel 2: Arbeitsbereiche und Projekte

Erstellung und Bearbeitung umfangreicher Programme gestaltet sich


damit ebenso einfach wie die Erstellung einfacher Programme aus einem Modul.

2.1

Projekte und Arbeitsbereiche

In Visual C++ werden Projekte immer in Arbeitsbereichen verwaltet.


Dies zahlt sich vor allem dann aus, wenn mehrere zusammengehrende Projekte in einem Arbeitsbereich untergebracht werden (beispielsweise die im Laufe der Zeit immer weiterentwickelten Versionen eines
Programms oder Programme, die aus einer EXE mit mehreren DLLs
bestehen).
Arbeitsbereiche mit einem Projekt
Wenn es Ihnen lediglich darum geht, ein Projekt fr ein Programm zu
erstellen (und Sie nicht beabsichtigen, spter weitere gleichberechtigte
Projekte in den Arbeitsbereich aufzunehmen), brauchen Sie nicht zwischen Projekt und Arbeitsbereich zu unterscheiden:
Legen Sie den Arbeitsbereich implizit im Zuge der Projekterstellung
an, indem Sie auf der Seite PROJEKTE im Dialogfeld NEU (Aufruf ber
DATEI/NEU) die Option NEUEN ARBEITSBEREICH ERSTELLEN aktivieren.
Arbeitsbereich und Projekt tragen dann den gleichen Namen und teilen sich auf der Festplatte ein gemeinsames Verzeichnis.
Arbeitsbereiche mit mehreren Projekten
Wenn Sie in einem Arbeitsbereich mehrere gleichberechtigte Projekte
verwalten wollen, sollten Sie vor dem Anlegen des ersten Projekts zuerst einen leeren Arbeitsbereich einrichten:
1. Legen Sie zuerst auf der Seite ARBEITSBEREICH im Dialogfeld NEU
(Aufruf ber DATEI/NEU) einen leeren Arbeitsbereich an.
2. Danach legen Sie auf der Seite PROJEKTE des Dialogfelds das oder
die Projekte an (wobei Sie darauf achten, da die Option HINZUFGEN ZU AKT. ARBEITSBEREICH markiert ist).
Arbeitsbereich und Projekte haben dann unterschiedliche Namen, und
die Verzeichnisse der Projekte werden standardmig dem Verzeichnis
des Arbeitsbereichs untergeordnet.
Ein Projekt Von den verschiedenen Projekten eines Arbeitsbereichs ist immer nur
aktivieren eines aktiv (durch Fettschrift im Arbeitsbereichfenster hervorgehoben).

Auf dieses Projekt beziehen sich die Menbefehle (beispielsweise zur


Kompilation und Erstellung).

Das Arbeiten mit Unterprojekten

43

ber den Menbefehl PROJEKT/AKTIVES PROJEKT FESTLEGEN knnen


Sie die verschiedenen Projekte eines Arbeitsbereichs aktivieren.
Arbeitsbereiche konfigurieren
Um die allgemeinen Einstellungen fr die Arbeitsbereiche festzulegen,
rufen Sie den Befehl EXTRAS/OPTIONEN auf, und wechseln Sie zur Seite ARBEITSBEREICH. Hier knnen Sie beispielsweise festlegen,
C welche Fenster beim ffnen automatisch in den Rahmen integriert
werden sollen,
C ob die bei der letzten Sitzung geffneten Fenster automatisch mit
dem Arbeitsbereich geffnet werden sollen oder
C ob und wie viele der zuletzt bearbeiteten Dateien und Arbeitsbereiche im Men Datei (entweder direkt oder in Untermens) aufgelistet werden sollen.

2.2

Das Arbeiten mit


Unterprojekten

Unterprojekte verwendet man blicherweise dann, wenn die Zieldatei


eines Projekts B als Quelldatei eines anderen Projekts A dienen soll. In
solchen Fllen wrde man Projekt B als Unterprojekt von Projekt A
einrichten.
Abbildung 2.1:
Projekt mit
Unterprojekt

44

Kapitel 2: Arbeitsbereiche und Projekte

Ein sinnvolles Beispiel fr die Verwendung von Unterprojekten sind


statische Bibliotheken. Angenommen, Sie haben fr ein greres Kalkulationsprogramm eine umfangreiche Sammlung von Funktionen fr
mathematische Berechnungen zusammengestellt, die Sie zur besseren
Wiederverwertung in Form einer statischen Bibliothek (Extension .lib)
zur Verfgung stellen wollen. In einem solchen Fall bietet es sich an,
die statische Bibliothek als Unterprojekt des Kalkulationsprogramms
(oder anderer Programme, die die Funktionen der Bibliothek nutzen
sollen) einzurichten.
Beispiel Um beispielsweise eine statische Bibliothek Bib als Unterprojekt zu

einem Hauptprogramm Applik einzurichten, kann man wie folgt vorgehen:


1. Erstellen Sie ber den Befehl DATEI/NEU ein ganz normales
Win32-Projekt (hier Applik), vgl. Kapitel 1.2.
2. Erstellen Sie ein abhngiges Unterprojekt (hier Bib). Rufen Sie den
Befehl PROJEKT/DEM PROJEKT HINZUFGEN/NEU auf, wechseln
Sie auf die Seite PROJEKTE, und nehmen Sie dort folgende Einstellungen vor:
Whlen Sie WIN32-BIBLIOTHEK (STATISCHE) als Zieltyp aus.
Geben Sie einen Projektnamen an (hier Bib).
Aktivieren Sie die Option HINZUFGEN ZU AKT. ARBEITSBEREICH.
Aktivieren Sie die Option ABHNGIGKEIT VON und whlen Sie
Applik als bergeordnetes Projekt aus.
3. Setzen Sie die Quelltexte fr beide Projekte auf.
4. Stellen Sie die ntigen externen Abhngigkeiten her. Nehmen wir
an, da im Quelltext von Applik.cpp auf eine in Bib.cpp definierte
Funktion zugegriffen werden soll. Dafr, da die Definition dieser
Funktion im Programm Applik zur Verfgung steht, sorgt die Einrichtung von Bib als Unterprojekt. Allerdings mu die Funktion
noch mit Hilfe einer Deklaration im Modul Applik.cpp bekanntgemacht werden. Nehmen Sie daher eine Include-Anweisung zur Einbindung der Header-Datei Bib.h in Applik.h auf.
5. Erstellen Sie das bergeordnete Projekt. Danach werden die externen Abhngigkeiten im Arbeitsbereichfenster angezeigt. (Die
angezeigten Abhngigkeiten beruhen immer auf dem letzten
Erstellungsproze.)
Bei der Erstellung eines bergeordneten Projekts werden zuerst alle
eingerichteten Unterprojekte erstellt.

45

Projekte erstellen und bearbeiten

Um Unterprojekte auszuschlieen, ohne sie gleich aus dem Arbeitsbereich lschen zu mssen, rufen Sie den Befehl PROJEKTE/ABHNGIGKEITEN auf, und deaktivieren Sie das Kontrollkstchen des entsprechenden Unterprojekts.

2.3

Projekte erstellen und


bearbeiten

Wegen der zentralen Bedeutung der Projektverwaltung fr die Anwendungsentwicklung im Visual Studio finden Sie in der folgenden Tabelle
noch einmal die wichtigsten Projektbefehle zusammengefat.
Aktion

Befehl

Neues Projekt anlegen

Rufen Sie den Befehl DATEI/NEU auf.


Ist aktuell noch ein Arbeitsbereich geffnet,
knnen Sie in dem erscheinenden Dialogfeld festlegen, ob das Projekt dem aktuellen
Arbeitsbereich hinzugefgt werden soll.

Bestehendes Projekt ffnen

Rufen Sie den Befehl DATEI/ARBEITSBEREICH FFNEN auf. Legen Sie innerhalb des
Arbeitsbereichs das aktive Projekt fest.

Aktives Projekt festlegen

Whlen Sie das Projekt ber den Befehl


PROJEKT/AKTIVES PROJEKT FESTLEGEN aus.

Projekt erstellen

Rufen Sie einen der Befehle ERSTELLEN/


PROJEKTNAME ERSTELLEN oder ERSTELLEN/ALLES NEU ERSTELLEN auf, je nachdem, ob Sie das Projekt aktualisieren oder
komplett neu kompilieren lassen wollen.

Projekt lschen

Markieren Sie den Projektknoten im Arbeitsbereichfenster, und rufen Sie den Befehl BEARBEITEN/LSCHEN auf ((Entf)).

Neue Datei hinzufgen

Rufen Sie den Befehl PROJEKT/DEM PROauf.

JEKT HINZUFGEN/NEU

Bestehende Datei hinzufgen

Rufen Sie den Befehl PROJEKT/DEM PROauf.

JEKT HINZUFGEN/DATEIEN

(Der Befehl DATEI/FFNEN ffnet eine Datei ohne sie dem Projekt einzugliedern.)

Tabelle 2.1:
Projekte
bearbeiten

46

Kapitel 2: Arbeitsbereiche und Projekte

Aktion

Befehl

Datei in Editor laden

Doppelklicken Sie im Arbeitsbereichfenster auf den Knoten der Datei.

Datei lschen

Markieren Sie die Datei im Arbeitsbereichfenster, und rufen Sie den Befehl BEARBEITEN/LSCHEN auf ((Entf)).

2.4

Projekte konfigurieren

Die Konfiguration Ihrer Projekte erfolgt auf verschiedenen Ebenen.


C Beim Anlegen des Projekts whlen Sie bereits Plattform und Art
der zu erstellenden Zieldatei aus (Seite PROJEKTE im Dialogfeld
NEU).
C Durch Hinzufgen von Dateien (Befehl PROJEKT/DEM PROJEKT
HINZUFGEN) richten Sie die einzelnen Module des Projekts ein.
C ber das Dialogfeld PROJEKTEINSTELLUNGEN knnen Sie auf die
Kompilation der einzelnen Quelldateien und die Erstellung des gesamten Projekts einwirken.

2.4.1

Das Dialogfeld Projekteinstellungen

ber den Befehl PROJEKT/EINSTELLUNGEN rufen Sie das Dialogfeld


PROJEKTEINSTELLUNGEN auf. Alle Einstellungen, die Sie in diesem Fenster vornehmen, beziehen sich auf die Konfiguration (siehe unten), die
im Feld EINSTELLUNGEN FR angezeigt wird, und auf den Knoten, der
in der darunter gelegenen Baumansicht ausgewhlt ist.
Tabelle 2.2:
Einstellungen fr
Projekte

Registerseite

Beschreibung

Allgemein

Auf dieser Seite knnen Sie entscheiden, ob und wie die


MFC eingebunden werden soll, und in welche Verzeichnisse die im Laufe des Erstellungsprozesses erzeugten temporren und binren Dateien geschrieben werden sollen.

Debug

ber diese Seite knnen Sie den Debugger konfigurieren


(beispielsweise durch Angabe von Kommandozeilenargumenten zu dem zu debuggenden Programm).
Interessant ist auch das Feld AUSFHRBARES PROGRAMM
FR DEBUG-SITZUNG. Sie werden sich nun bestimmt fragen,
wieso Sie in dieses Feld eine andere Datei eintragen sollten,
als die des aktuellen Programms? Die Antwort ist sehr einfach: Sie knnen hier auch DLLs oder andere Komponenten angeben, die nicht direkt von der Kommandozeile aus
aufgerufen werden knnen.

Projekte konfigurieren

Registerseite

Beschreibung
Verwenden Sie Visual C++ beispielsweise, um einen MAPITransport-Provider zu entwickeln, geben Sie den Namen
des MAPI-Spooler MAPISP32.EXE, als ausfhrbare Datei
an, da dieses Programm Ihre Transport-Provider-DLL ldt.
Erstellen Sie ein OLE-Steuerelement (OCX-Datei), bestimmen Sie eine ActiveX-Steuerelement-Container-Applikation, wie z.B. die mit Visual C++ ausgelieferte Anwendung
TSTCON32.EXE, als ausfhrbare Datei.

C/C++

ber diese Seite konfigurieren Sie den Compiler. Gehen


Sie die verschiedenen Kategorien nacheinander durch, um
die bersetzung des Projekts durch den Compiler anzupassen. Die Umsetzung Ihrer Einstellungen in Compiler-Optionen wird Ihnen im Feld PROJEKT OPTIONEN angezeigt.
Eine interessante Kategorieseite ist mit VORKOMPILIERTE
HEADER bezeichnet. Dort geben Sie an, wie der Compiler
vorkompilierte Header-Dateien (PCH) whrend des Kompilierens erstellen und verwenden soll. Das Verwenden vorkompilierter Header ist sehr wichtig, da auf diese Weise die
Performance des Compilers erhht wird.
Die Kategorieseite bietet zwei wesentliche Optionen. Selektieren Sie VORKOMPILIERTE HEADER AUTOMATISCH VERWENDEN, sucht und erkennt der Compiler die Header in Ihrer
Projektdatei und erzeugt daraus die entsprechenden vorkompilierten Header.
Projekte, die von einem Anwendungs-Assistenten generiert
wurden, verwenden jedoch keine automatisch vorkompilierten Header. Fr solche Projekte mssen Sie die Erstellung
und Verwendung vorkompilierter Header explizit vornehmen. Sie haben jedoch die Mglichkeit, einen vorkompilierten Header nur einmal erstellen zu lassen und allen anderen
Dateien zuzuweisen. Dazu verwenden Sie eine beliebige
Datei Ihres Projekts (z.B. STDAFX.CPP), aus der der Compiler den vorkompilierten Header erstellt. Alle anderen
Quelltextdateien werden so eingerichtet, da sie diesen vorkompilierten Header verwenden.

Linker

ber diese Seite konfigurieren Sie den Linker. Gehen Sie


die verschiedenen Kategorien nacheinander durch, um die
Bindung der Module zum ausfhrbaren Programm anzupassen. Die Umsetzung Ihrer Einstellungen in Linker-Optionen
wird Ihnen im Feld PROJEKT OPTIONEN angezeigt.

Ressourcen

ber diese Seite konfigurieren Sie den Ressourcen-Compiler. Die Umsetzung Ihrer Einstellungen in Compiler-Optionen wird Ihnen im Feld PROJEKT OPTIONEN angezeigt.

47

48

Kapitel 2: Arbeitsbereiche und Projekte

Registerseite

Beschreibung

Midl

Optionen fr den MIDL-Compiler.

Browse-Informationen

Optionen zur Erstellung von Informationen fr den Browser.

BenutzerdefiHier haben Sie die Mglichkeit, eigene Befehle fr die


niertes Erstellen Erstellung der Zieldatei vorzugeben (beispielsweise das Anlegen einzelner Sicherungsdateien oder das Aufrufen externer Tools).
Enthlt Ihr Projekt beispielsweise eine Datei zur grammatikalischen Spezifizierung, die mit GRAM.Y bezeichnet ist
und von dem yacc-Parser bearbeitet werden mu, mchten
Sie mglicherweise ein benutzerdefiniertes Verfahren fr
diese Datei definieren.
Linker-Vorstufe Hier knnen Sie Befehle eingeben, die vor Aufruf des Linkers ausgefhrt werden.
Bearbeiten
nach dem
Erstellen

2.4.2

Hier knnen Sie Befehle eingeben, die nach Abschlu des


Erstellungsvorgangs ausgefhrt werden.

Arbeiten mit Konfigurationen

Damit Sie nicht stndig im Dialogfeld PROJEKTEINSTELLUNGEN von Seite zu Seite springen mssen, um die Projekterstellung an Ihre augenblicklichen Bedrfnisse anzupassen, haben Sie die Mglichkeit, alle im
Dialogfeld PROJEKTEINSTELLUNGEN vorgenommenen Einstellungen als
Konfiguration abzuspeichern.
Indem Sie sich verschiedene Konfigurationen fr Standardaufgaben
anlegen, brauchen Sie statt der Anpassung der Optionen nur noch die
gewnschte Konfiguration auszuwhlen.
Konfigurationen 1. Legen Sie eine neue Konfiguration an. Rufen Sie dazu den Befehl
einrichten
ERSTELLEN/KONFIGURATIONEN auf, und klicken Sie in dem erschei-

nenden Dialogfeld auf den Schalter HINZUFGEN.


2. Geben Sie einen Namen fr die neue Konfiguration an. Zustzlich
knnen Sie noch eine bereits bestehende Konfiguration auswhlen, auf deren Einstellungen Sie aufbauen wollen.
3. Schicken Sie die Dialogfelder ab.
4. Passen Sie die neue Konfiguration an. Rufen Sie dazu den Befehl
PROJEKT/EINSTELLUNGEN auf, und whlen Sie im Feld EINSTELLUNGEN fr Ihre neue Konfiguration aus. berarbeiten Sie dann
die Optionen.

Zusammenfassung

Standardmig wird jedes Projekt mit den beiden Konfigurationen


Win32 Release (erzeugt optimierten Code ohne Debug-Informationen) und Win32 Debug (erzeugt Debug-Informationen) ausgestattet.

2.5

Zusammenfassung

Ein Arbeitsbereich kann ein oder mehrere Hauptprojekt(e) enthalten,


die wiederum aus mehreren untergeordneten Projekten bestehen knnen. Visual Studio fhrt zu jedem Projekt verschiedene Konfigurationen. Eine Projekt-Konfiguration setzt sich aus Einstellungen zusammen, die zur Erstellung des Projekts verwendet werden. Erstellen Sie
beispielsweise mit Hilfe des MFC-Anwendungs-Assistenten ein neues
Projekt, erzeugt der Assistent zwei Konfigurationen: eine fr den Debug-Vorgang und eine fr den Vorgang des Kompilierens.
Die Projekteinstellungen knnen nach Aufruf des Befehls EINSTELLUNGEN aus dem Men PROJEKT modifiziert werden. Der Dialog PROJEKTEINSTELLUNGEN ist ein komplexer Dialog mit mehreren Eigenschaftenseiten und verschiedenen untergeordneten Seiten. Die vorgenommenen Einstellungen beziehen sich jeweils auf den ausgewhlten Knoten
(Projekt oder Datei) sowie die ausgewhlte Konfiguration.

49

Die Assistenten

Kapitel
S

tatt Ihre Programme von Grund auf selbst zu schreiben, knnen


Sie fr die am hufigsten bentigten Anwendungstypen sogenannte Assistenten zu Hilfe nehmen. Bei diesen Assistenten handelt es
sich um dienstbare Geister, die als einzige Schnittstelle zum Anwender
eines oder mehrere Dialogfelder anzeigen, ber die Sie auf die Arbeit
des Assistenten einwirken knnen. Nach dem Abschicken Ihrer Angaben erstellt der Assistent fr Sie ein passendes Projekt, legt die ersten
Dateien an und setzt ein Code-Gerst auf, das Sie von den formelleren
Programmieraufgaben (Anlegen eines Doc/View-Gersts fr MFC-Anwendungen oder MFC-DLLs, Einrichten einer Datenbankanbindung
oder Typbibliothek, Registrierung fr ActiveX-Steuerelemente, etc.)
befreit, so da Sie gleich mit der kreativen Arbeit beginnen knnen.
Projekte, die mit einem der MFC-Anwendungsassistenten erstellt wurden, knnen darber hinaus mit dem Klassenassistenten vielfach weiterverarbeitet werden.
Dieses Kapitel beschreibt kurz den MFC-Anwendungsassistenten und
den Klassenassistenten und gibt Ihnen einen berblick ber die verschiedenen Projekttypen, die Ihnen im Dialogfeld DATEI/NEU angeboten werden.
Ein praktisches Beispiel fr den Einsatz des MFC-Anwendungsassistenten und des Klassenassistenten finden Sie im Kapitel zur
Erstellung eines MFC-Anwendungsgersts.

52

Kapitel 3: Die Assistenten

Grundstzlich gilt, da die Verwendung eines Assistenten Sie nicht


von der Aufgabe befreit, sich mit dem generierten Code detailliert
auseinanderzusetzen. Ohne ein grndliches Verstndnis des erzeugten Anwendungsgersts ist jeder Versuch, auf diesem Gerst
aufzubauen oder es abzuwandeln, zumindest als gefhrlich einzustufen.

3.1

Der Anwendungsassistent

Abbildung 3.1:
Der MFC-Anwendungsassistent

Der MFC-Anwendungsassistent ist unzweifelhaft der leistungsfhigste


der angebotenen Assistenten, da er nicht nur ein direkt kompilier- und
ausfhrbares MFC-Projekt anlegt, sondern auf dem Weg ber eine Reihe von Dialogfeldern es dem Programmierer sogar erlaubt, das zu erzeugende Projekt in vielfltiger Weise an seine Bedrfnisse anzupassen
und beispielsweise mit
C Doc/View-Untersttzung
C Datenbankanbindung
C OLE- und ActiveX-Features
C verschiedenen Fensterdekorationen
C etc.
auszustatten.

53

Der Anwendungsassistent

Den Grundtyp Ihrer Anwendung legen Sie dabei gleich auf der ersten Alle AnwenDialogseite fest, wo Sie sich fr eine der folgenden Anwendungen ent- dungsassistenten werden ber
scheiden knnen:
Datei/Neu aufge-

C EINZELNES DOKUMENT (SDI), eine Anwendung mit einem Rahmenrufen


fenster, in dem immer nur ein Dokumentfenster zur Zeit angezeigt
werden kann (vgl. Notepad-Editor)
C MEHRERE DOKUMENTE (MDI), eine Anwendung mit einem Rahmenfenster, in dem mehrere Dokumentfenster verwaltet werden
knnen (vgl. Word fr Windows)
C DIALOGFELDBASIEREND, eine Anwendung mit einem Dialogfeld als
Rahmenfenster (vgl. Visual-C++-Assistenten)
Seite

Beschreibung

Auf der ersten Seite legen Sie den grundlegenden Typ Ihrer Anwendung fest (SDI, MDI oder Dialog siehe oben) und whlen
eine Sprache fr die anzulegenden Ressourcen.
Seit VC 6.0 gibt es die Mglichkeit, auf Doc/View-Untersttzung zu verzichten. Doc/View ist ein Programmiermodell, das
sich rein auf die Implementierung eines Programms bezieht und
die Idee propagiert, da fr bestimmte Anwendungen die saubere Trennung der Daten (Doc) und deren Darstellung (View)
Vorteile bringt (insbesondere dann, wenn ein und dieselben Daten auf unterschiedliche Weise angezeigt werden sollen).
Anmerkung! Meinen Erfahrungen nach ist der Assistent nicht in
der Lage, ausfhrbare Projekte ohne Doc/View zu erstellen.

Auf der zweiten Seite knnen Sie Ihre Anwendung mit einer
Datenbank verbinden. Im oberen Teil whlen Sie die Art der
Datenbankuntersttzung und ob Befehle zum Laden und Speichern von Dokumentdateien in das Men DATEI aufgenommen
werden sollen. (Die Dokumentklassen von Datenbank-Applikationen mssen hufig kurzfristig lediglich den Inhalt einer Datenbank darstellen, ohne diese zu speichern. Verwenden Sie in
diesem Fall die Option DATENBANKANSICHT OHNE DATEIUNTERSTTZUNG.)
Wenn Sie sich fr eine Datenbankanbindung entschieden haben, knnen Sie im unteren Teil des Dialogfelds ber den
Schalter DATENQUELLE eine Datenbank auswhlen.
Seit VC 6.0 haben Sie hier die Mglichkeit, die Datenbankuntersttzung nicht nur durch ODBC oder DAO, sondern auch
durch OLE DB aufzubauen. (Wobei OLE DB am fortschrittlichsten und fr ambitionierte Programmierer am empfehlenswertesten ist, siehe Kapitel zur Datenbankprogrammierung.)

Tabelle 3.1:
Die Seiten des
MFC-Anwendungsassistenten

54

Kapitel 3: Die Assistenten

Seite

Beschreibung

Die dritte Seite fhrt die OLE-Mglichkeiten und ActiveX-Features auf. Geben Sie hier an, ob Ihre Applikation OLE-Verbunddokumentfunktionalitt als Server, Container, Mini-Server
oder Container/Server untersttzen soll.
Auerdem knnen Sie Ihrem Projekt Untersttzung fr Automations-Server sowie fr ActiveX-Steuerelement-Container hinzufgen. Selektieren Sie die letzte Option, wenn Sie ActiveXSteuerelemente in den Dialogen Ihrer Applikation verwenden
mchten.
Wenn Sie die Untersttzung fr Verbunddokumente selektieren,
knnen Sie ebenfalls die Untersttzung fr Verbunddateien aktivieren. Nach Auswahl dieser Option werden die Objekte Ihrer
Applikation im Verbunddateiformat gespeichert, welches das
Laden nach Aufforderung und sukzessives Speichern ermglicht (aber grere Dateien bedingt).

Die nchste Dialogseite des Anwendungsassistenten (Abbildung


2.6) enthlt unterschiedliche Optionen. Die meisten Optionen
sind selbsterklrend oder verfgen ber eine ausreichende Online-Hilfe.
Setzen Sie die Option KONTEXTABHNGIGE HILFE, werden Ihrer
Applikation die Grundstruktur einer Hilfeprojektdatei sowie Hilfethemendateien hinzugefgt. Auerdem wird die Batch-Datei
Makehelp.bat erzeugt, die zur erneuten Generierung berarbeiteter Hilfedateien verwendet werden kann.
Selektieren Sie das Kontrollkstchen MAPI (MESSAGING API),
werden die MAPI-Bibliotheken an Ihre Applikation gebunden,
und dem Men DATEI wird der Eintrag SENDEN hinzugefgt. Auf
diese Weise gewhrleisten Sie eine minimale MAPI-Untersttzung fr die Kompatibilitt zu Windows-95-Applikationsanforderungen.
Das Aktivieren der Option WINDOWS-SOCKETS fhrt dazu, da
Ihrem Projekt WinSock-Bibliotheken und Header-Dateien hinzugefgt werden. Die WinSock-Funktionalitt mssen Sie jedoch selbst dem Projekt hinzufgen.
Ihr besonderes Interesse sollte dem Dialog WEITERE OPTIONEN
gelten, der nach einem Klick auf die gleichlautende Schaltflche
aufgerufen wird. In diesem Dialog bestimmen Sie einige zustzliche Optionen, die das uere sowie die Ausfhrung Ihrer Applikation betreffen.

Der Anwendungsassistent

Seite

Beschreibung
Der Dialog WEITERE OPTIONEN besteht aus zwei Registern.

Das erste Register mit der Bezeichnung ZEICHENFOLGEN FR


DOKUMENTVORLAGE (siehe Abbildung) ermglicht Ihnen die Angabe verschiedener Zeichenfolgen, die fr den Datei-ffnenDialog, die Dokumentvorlagen und den Fenstertitel (MDI) relevant sind. Die eingegebenen Zeichenfolgen werden in der
Stringtabelle der Ressource-Datei der Anwendung unter
IDR_MAINFRAME gespeichert.
Das zweite Register des Dialogs ist mit FENSTERSTILE bezeichnet
und wird zur Konfiguration der Rahmenfensterstile Ihrer Applikation verwendet.
5

Auf dieser Seite legen Sie fest,

Cob Sie ein normales oder ein Explorer-hnliches Fenster haben mchten,
Cob ausfhrliche Kommentare angelegt werden sollen,
Cob die MFC statisch oder als DLL eingebunden werden soll.
6

Auf der letzten Seite werden die zu generierenden Klassen angezeigt, und Sie haben die Mglichkeit, zu den einzelnen Klassen passende Basisklassen auszuwhlen und die Dateinamen zu
ndern.

55

56

Kapitel 3: Die Assistenten

3.2

Weitere Anwendungsassistenten und Projekttypen

Neben dem MFC-Anwendungsassistenten existieren noch eine Reihe


weiterer Anwendungsassistenten und Projekttypen, die Sie auf der Seite PROJEKTE des Dialogfelds NEU (Aufruf ber DATEI/NEU) auswhlen
knnen.
Mglicherweise werden nicht alle Projekttypen in Ihrer Visual-C++Version angezeigt. Einige Projekttypen sind lediglich in der Professional- und Enterprise-Edition des Produkts enthalten.
Add-in-Assistent fr DevStudio
Assistent zur Erstellung von Add-In-DLLs, die der Erweiterung und Automatisierung der Developer-Studio-IDE dienen (knnen sowohl auf
das Visual-Studio-Objektmodell wie auch auf die Ressourcen des Computers zugreifen).
Assistent fr erw. gespeicherte Prozeduren
Legt ein Projekt zur Erstellung von gespeicherten Funktionen (Stored
Procedures) fr einen Microsoft SQL-Server an.
Assistent fr ISAPI-Erweiterungen
Dieser Assistent untersttzt Sie bei der Erstellung von API-Erweiterungen fr Internet Server (beispielsweise den Microsoft Internet Information Server (WinNT) oder den Microsoft Personal Web Server (wird mit
Microsoft FrontPage ausgeliefert)). Als Erweiterungen knnen auch Filter implementiert werden, die in den Datentransfer vom und zum Server eingeschaltet werden.
ATL-COM-Anwendungs-Assistent
Mit diesem Assistenten knnen Sie ActiveX-Steuerelemente auf der
Grundlage der ATL (Active Template Library) erstellen.
Benutzerdefinierter Anwendungsassistent
Dieser Assistent ermglicht Ihnen die Erstellung eigener Anwendungsassistenten. Ein solcher Anwendungsassistent kann auf dem StandardAnwendungsassistenten fr MFC-Applikationen oder DLLs basieren.
Er kann auerdem auf einem bestehenden Projekt basieren oder benutzerdefinierte Schritte enthalten, die Sie definieren.

Weitere Anwendungsassistenten und Projekttypen

Wenn Sie festlegen, da Ihr benutzerdefinierter Anwendungsassistent


auf einem der Standard-Anwendungsassistenten basieren soll, bestimmen Sie im nchsten Schritt den gewnschten Anwendungsassistenten. Soll der Assistent auf einem bestehenden Projekt basieren, spezifizieren Sie anschlieend den Projektpfad.
Cluster-Ressourcentyp-Assistent
Erzeugt zwei Projekte fr Microsoft Cluster Server (MSCS)-Ressourcen. Die Cluster-Architektur verbindet mehrere verbundene Systeme
zu einem nach auen einheitlich erscheinenden Netzwerk. Ausflle in
einzelnen Untersystemen knnen von anderen Systemen abgefangen
werden.
Der Microsoft Cluster Server wird mit dem Windows NT-Server, Enterprise Edition, ausgeliefert.
Datenbank-Assistent
Die Option NEW DATABASE WIZARD ermglicht Ihnen die Erstellung einer neuen SQL-Server-Datenbank. Zu dieser Datenbank wird ein Projekt generiert. Beachten Sie bitte, da Sie ber einen Zugriff auf den
Microsoft-SQL-Server verfgen mssen, der entweder auf Ihrem Computer oder auf einem Netzwerkrechner vorhanden sein mu, um die
Datenbank erstellen lassen zu knnen.
Datenbankprojekt
Ein Datenbankprojekt verweist in die Tabellen einer Datenbank. Die
Tabellen mssen dem Projekt manuell hinzugefgt werden, nachdem
dieses erzeugt wurde.
Dienstprogramm-Projekt
Leeres Programmgerst fr Dateien, die nur kompiliert, aber nicht gelinkt werden sollen.
Makefile
Verwenden Sie diese Option, um ein Projekt zu generieren, das auf einer Make-Datei basiert. Geben Sie anschlieend den Namen der externen Make-Datei oder anderer ausfhrbarer Programme an, die zur Erzeugung Ihres Projekts ausgefhrt werden sollen.
MFC-ActiveX-Steuerelement-Assistent
Der MFC-ActiveX-Steuerelement-Assistent fhrt Sie zur Erstellung eines Projekts, das aus einem oder mehreren ActiveX-Steuerelementen
besteht, die auf der MFC-Steuerelement-Implementierung basieren.
Ein ActiveX-Steuerelement-Projekt erzeugt eine spezielle DLL-Datei,

57

58

Kapitel 3: Die Assistenten

die eine OCX-Datei bildet. Die beiden Dialogseiten des Anwendungsassistenten dienen der Angabe bestimmter Eigenschaften sowie der
Konfiguration einzelner Steuerelemente Ihres ActiveX-SteuerelementProjekts.
MFC-Anwendungsassistent (dll)
Assistent zur Erstellung von MFC-Programmgersten fr DLLs (Dynamische Linkbibliotheken).
MFC-Anwendungsassistent (exe)
Assistent zur Erstellung von MFC-Programmgersten fr Windows-Anwendungen.
Win32 Dynamic-Link Library
Projekt fr dynamische Bibliotheken.
Per Voreinstellung fr API-Projekte, die MFC kann aber nachtrglich
ber die Projektkonfiguration eingebunden werden.
Win32-Anwendung
Projekt fr Windows-Anwendungen.
Per Voreinstellung fr API-Projekte, die MFC kann aber nachtrglich
ber die Projektkonfiguration eingebunden werden.
Win32-Bibliothek (statische)
Projekt fr statische Bibliotheken.
Per Voreinstellung fr API-Projekte, die MFC kann aber nachtrglich
ber die Projektkonfiguration eingebunden werden.
Win32-Konsolenanwendung
Projekt fr textbildschirmbasierte Konsolenanwendungen (ohne MFC).

3.3

Der Klassen-Assistent

Aufruf ber Der Klassen-Assistent dient der komfortablen, semi-automatischen BeAnsicht/Klassen- arbeitung von Projekten mit Klassen, die von CCmdTarget abgeleitet sind
Assistent und ber eine clw-Datei verfgen (beispielsweise die vom MFC-Anwen-

dungsassistenten generierten Projekte).


Insbesondere folgende Manahmen werden untersttzt:
C Neue Klassen erstellen
C Antwortmethoden zur Botschaftsverarbeitung einrichten

Der Klassen-Assistent

C Virtuelle Methoden einrichten


C Dialogklassen erstellen
C Elementvariablen fr Steuerelemente aus Dialogen anlegen
C Ereignisse fr ActiveX-Steuerelemente definieren
C Automatisierung von Klassen
C Klassen aus Typbibliotheken erstellen
Der Klassen-Assistent erscheint als fnfseitiges Dialogfeld:
C NACHRICHTENZUORDNUNGSTABELLEN. Auf dieser Seite knnen Sie
sich darber informieren, welche Antwortmethoden in welchen
Klassen zu welchen Botschaften deklariert sind (soweit diese vom
Klassen-Assistenten verwaltet werden). Sie knnen Methoden zur
Botschaftsverarbeitung einrichten, bearbeiten oder lschen, Sie
knnen virtuelle Methoden berschreiben, und Sie knnen in den
Quelltext der aufgefhrten Methoden springen.
C MEMBER-VARIABLEN. Auf dieser Seite knnen Sie Elementvariablen zum Datenaustausch zwischen einer Anwendung und den
Steuerelementen eines Dialogs oder eines Datenbankformulars
einrichten.
C AUTOMATISIERUNG. Auf dieser Seite knnen Sie Eigenschaften und
Methoden automatisieren.
C ACTIVEX-EREIGNISSE. Auf dieser Seite knnen Sie Aktionen definieren, die Ereignisse in ActiveX-Steuerelementen auslsen (nur
fr die Entwicklung, nicht fr die Verwendung von ActiveX-Steuerelementen gedacht).
C KLASSEN-INFO. Auf dieser Seite knnen Sie den Nachrichtenfilter
einer Klasse so einstellen, da er feststellt, welche Nachrichten der
Klassen-Assistent bereitstellt, um die Behandlungsroutinen in Ihrer
Klasse zuzuordnen. Sie knnen auch ein Fremdobjekt anzeigen
oder setzen, das mit der Formularansichts- oder DatensatzansichtsKlasse Ihres Dialogs verbunden ist.
Die Informationen zur Bearbeitung des Projekts entnimmt der
Klassen-Assistent einer Datenbankdatei (Extension .clw), die von
den Anwendungsassistenten standardmig erstellt wird, die aber
auch nachtrglich angelegt oder aktualisiert werden kann.

59

60

Kapitel 3: Die Assistenten

3.3.1

Erstellen einer neuen Klasse

Mit einem Klick auf die Schaltflche KLASSE HINZUFGEN erstellen Sie
eine neue Klasse fr Ihre Applikation. Der Klassen-Assistent ermglicht Ihnen,
C eine Klasse unter Verwendung einer bestehenden Implementierung hinzuzufgen,
C eine Klasse anhand einer Typenbibliothek zu erstellen,
C eine vollstndig neue Klasse zu erstellen.
Klassen Mchten Sie eine Klasse aus einer existierenden Implementierung erimportieren zeugen, mssen Sie die Klassendaten in den Klassen-Assistenten im-

portieren. Gewhnlich ist die Klasse bereits ein Teil Ihres Projekts.
Diese Vorgehensweise ist sehr geeignet, wenn Sie eine neue Klasse in
Ihr Projekt importiert haben, indem Sie die Header- und Implementierungsdateien in das Projektverzeichnis kopierten und manuell dem
Projekt hinzufgten. Das Importieren der Klassendaten ist auch dann
sinnvoll, wenn Sie die Klasseninformationsdatei (CLW-Datei) Ihrer Applikation erneut erstellen mssen, weil diese beschdigt wurde. In dieser Datei verwahrt der Klassen-Assistent alle relevanten Klasseninformationen.
Klassen aus Ty- Das Erzeugen einer Klasse aus einer Typenbibliothek erfordert das Gepenbibliotheken nerieren einer neuen Klasse, die die in der Typenbibliothek beschriebe-

ne Schnittstelle umfat. Sie knnen dieses Feature beispielsweise verwenden, um eine Klasse zu erstellen, die ein ActiveX-Steuerelement
oder ein Automatisierungsobjekt reprsentiert.
Neue Klassen Wenn Sie eine Klasse von Grund auf neu anlegen lassen wollen, geben

Sie zuerst den Namen der Klasse ein und whlen dann eine Basisklasse
aus.
Reprsentiert die selektierte Basisklasse eine Dialogvorlage (z.B. einen
Dialog, eine Formularansicht oder Eigenschaftenseite), wird der Zugriff
auf das Feld DIALOGFELD-ID freigegeben. Hier whlen Sie einen Bezeichner fr eine Dialogvorlage aus der Liste der Bezeichner aus, die in
der Ressource-Datei Ihrer Applikation vermerkt sind.
Untersttzt die Basisklasse die Automatisierung, knnen Sie die entsprechenden Optionen im unteren Bereich des Dialogs selektieren.
Beachten Sie bitte, da einige Klassen Automatisierung, aber nicht das
Erstellen von Objekten untersttzen. Ein Zugriff auf die Option ERSTELLBAR NACH TYP-ID ist fr solche Klassen nicht mglich.

Der Klassen-Assistent

3.3.2

61

Nachrichtenzuordnungstabellen

MFC implementiert einen speziellen Mechanismus fr die Verwaltung


von Windows-Nachrichten. Nachdem die Nachrichtenschleife einer
Applikation die Nachrichten empfangen hat, werden diese von Klassenobjekten, die sich von der Applikationsklasse CCmdTarget ableiten, gem spezifischer Regeln bearbeitet. Empfngt ein Objekt eine
Nachricht, wird diese entweder verarbeitet oder weitergeleitet.
Ein Objekt verarbeitet lediglich solche Nachrichten, deren Typ in der
Nachrichtenzuordnungstabelle aufgefhrt und mit einer Bearbeitungsfunktion verbunden ist. Sie greifen ber den Klassen-Assistenten auf
Nachrichtenzuordnungstabellen fr MFC-Klassen zu.
Abbildung 3.2 zeigt die Nachrichtenzuordnungstabelle fr die Eigenschaftenseite eines ActiveX-Steuerelements. (Ich habe ein einfaches
ActiveX-Steuerelementprojekt fr die Abbildungen dieses Kapitels
verwendet, da ActiveX-Steuerelemente alle erforderlichen Klassen besitzen, die zur Demonstration der Features des Assistenten bentigt
werden.)
Abbildung 3.2:
Bearbeiten von
Nachrichtenzuordnungstabellen mit dem
Klassen-Assistenten

Die Selektion in dem Listenfeld KLASSENNAME gibt an, da Sie die Eintrge der Nachrichtenzuordnungstabelle fr die Klasse CMCTLPropPage einsehen und festlegen wollen. Im Listenfeld OBJEKT-IDS
werden die ausgewhlte Klasse und alle zugehrigen Objekte aufgefhrt, die Nachrichten generieren knnen (Menbefehle, Steuerelemente, etc.). In Abbildung 3.2 sehen Sie beispielsweise neben der

62

Kapitel 3: Die Assistenten

Klasse CMCTLPropPage noch die ID IDC_CBSHAPE, die sich auf


ein Kombinationsfeld bezieht, das in der Dialogvorlage fr CMCTLPropPage enthalten ist. (Wenn die Klasse eines Dialogs oder einer Eigenschaftenseite ausgewhlt ist, fhrt der Klassen-Assistent die Bezeichner aller Steuerelemente der Dialogvorlage auf, die mit der in
dem Listenfeld OBJEKT-IDS selektierten Klasse verknpft sind.)
Bearbeitungsfunktionen einrichten
Um sich ber die Bearbeitungsfunktionen zu einer Klasse, einem Objekt oder einer Botschaft zu informieren oder eine solche Funktion einzurichten oder zu bearbeiten, gehen Sie wie folgt vor:
1. Whlen Sie im Feld KLASSENNAME die Klasse aus, in der die Antwortmethode deklariert werden soll.
2. Whlen Sie im Feld OBJEKT-IDS das Objekt aus, dessen Bearbeitungsfunktionen Sie einsehen mchten oder fr das Sie eine Botschaftbearbeitungsfunktion einrichten wollen.
Die bereits eingerichteten Bearbeitungsfunktionen werden jetzt im
Feld MEMBER-FUNKTIONEN angezeigt.
Wenn Sie eine bereits eingerichtete Bearbeitungsfunktion bearbeiten
wollen,
3a. Whlen Sie die Bearbeitungsfunktion im Feld MEMBER-FUNKTIONEN aus, und klicken Sie auf den Schalter CODE BEARBEITEN.
Wenn Sie eine neue Bearbeitungsfunktion fr eine Botschaft einrichten wollen,
3b. Whlen Sie im Feld NACHRICHTEN eine Botschaft aus.
Fr IDs von Menbefehlen stehen Ihnen beispielsweise die Nachrichten COMMAND (zur Behandlung des eigentlichen Menbefehls) und UPDATE_COMMAND_UI (zur Aktualisierung des
Menbefehls im Men, beispielsweise durch Anzeigen eines Hkchens oder Deaktivierung) zur Verfgung. Fr Klassen stehen
Ihnen die virtuellen Methoden, die vordefinierten Bearbeitungsfunktionen (On...) und die Windows-Botschaften (WM_...) zur Verfgung (die Auswahl hngt von dem Typ der Klasse ab und kann
ber das Feld FILTER FR NACHRICHTEN auf der Seite KLASSENINFO verndert werden).
Nachrichten (oder Methoden), fr die bereits Implementierungen
vorliegen, werden im Feld NACHRICHTEN durch Fettschrift hervorgehoben.
4. Klicken Sie auf den Schalter FUNKTION HINZUFGEN.

Der Klassen-Assistent

nderungen im Quelltext
Wenn Sie eine Bearbeitungsfunktion einrichten, aktualisiert der Klassen-Assistent automatisch Ihren Quelltext. Fgen Sie beispielsweise die
in Abbildung 3.2 dargestellte Member-Funktion der Klasse CMCTLPropPage hinzu, wird die Deklaration der Nachrichtenzuordnungstabelle in der Header-Datei wie folgt modifiziert:
// Message maps
protected:
//{{AFX_MSG(CMCTLPropPage)
afx_msg void OnDblclkCbshape();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

Der Klassen-Assistent ermittelt die Position der Nachrichtenzuordnungstabelle in Ihrem Programmcode anhand der speziellen Kommentare, die die Tabelle umschlieen. Deklarationen von Nachrichtenzuordnungstabellen sind beispielsweise durch Kommentare gekennzeichnet,
die mit //{{AFX_MSG beginnen. Sie sollten Programmcode, der mit solchen Kommentaren versehen ist, nicht verndern. Das Auffinden dieser
spezifischen Programmabschnitte in Ihren Quelldateien ist sehr einfach.
Der Developer-Studio-Editor zeigt die Abschnitte in einer besonderen
Farbe an.
Die Deklaration der Nachrichtenzuordnungstabelle ist nicht der einzige
Abschnitt, der von dem Klassen-Assistent modifiziert wird. Die Definition der Nachrichtenzuordnungstabelle in der Implementierungsdatei
der Klasse CMCTLPropPage wird ebenfalls verndert.
///////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(CMCTLPropPage, COlePropertyPage)
//{{AFX_MSG_MAP(CMCTLPropPage)
ON_CBN_DBLCLK(IDC_CBSHAPE, OnDblclkCbshape)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

Beachten Sie bitte, da der Klassen-Assistent eine Grundstruktur fr


die Implementierung der neuen Funktion erstellt, die mit OnDblclkCbshape bezeichnet ist. Diese Implementierung wird der Datei einfach
angehngt. Sie knnen den entsprechenden Abschnitt an die gewnschte Position im Programmcode verschieben:
///////////////////////////////////////////////////////////////////
// CMCTLPropPage message handlers
void CMCTLPropPage::OnDblclkCbshape()
{
// TODO: Add your control notification handler code here
}

63

64

Kapitel 3: Die Assistenten

Virtuelle Elementfunktionen berschreiben


1. Whlen Sie im Feld KLASSENNAME die Klasse aus, in der die Elementfunktion berschrieben werden soll. Danach mssen Sie die
Klasse noch einmal im Feld OBJEKT-IDS auswhlen.
2. Whlen Sie im Feld NACHRICHTEN die zu berschreibende Elementfunktion aus.
3. Klicken Sie auf den Schalter FUNKTION HINZUFGEN.
Die eingerichtete Elementfunktion wird im Feld MEMBER-FUNKTIONEN
angezeigt. Virtuelle Elementfunktionen werden dabei durch ein vorangestelltes V gekennzeichnet.
Member-Funktionen lschen
1. Um eingerichtete Member-Funktionen zu lschen, markieren Sie
die Funktion im Feld MEMBER-FUNKTIONEN, und drcken Sie den
Schalter FUNKTION LSCHEN.
Haben Sie fr eine eingerichtete Member-Funktion bereits Code ausgesetzt, kann der Klassen-Assistent die Definition nicht mehr selbst
entfernen. In solchen Fllen werden Sie darauf hingewiesen, da Sie
die Definition der Member-Funktion selbst lschen mssen.
Member-Funktionen bearbeiten
Um in die Definition einer eingerichteten Member-Funktion zu springen und den passenden Code einzugeben, markieren Sie die Funktion
im Feld MEMBER-FUNKTIONEN, und drcken Sie den Schalter CODE BEARBEITEN.

3.3.3

Member-Variablen und Datenaustausch

In dem zweiten Register des Klassen-Assistenten-Dialogs knnen Sie


Member-Variablen definieren und modifizieren.
Wenn Sie einen Dialog implementieren, reicht es nicht, die Ressource
aufzusetzen, eine Klasse mit der Ressource zu verbinden und den Dialog in der Anwendung aufzurufen. Nachdem der Anwender den Dialog
beendet hat, mssen Sie die Eingaben des Anwenders in den Steuerelementen des Dialogs abfragen (und blicherweise auch darauf reagieren).
Die MFC verfgt ber einen speziellen internen Mechanismus, der Ihnen die Abfrage der Eingaben in den Steuerelementen wesentlich erleichtert DDX (Dialogdatenaustausch) und DDV (Dialogdatenberprfung).

Der Klassen-Assistent

65

Abbildung 3.3:
Bearbeiten von
Member-Variablen mit dem
Klassen-Assistenten

Um DDX nutzen zu knnen, brauchen Sie nur mit Hilfe des KlassenAssistenten fr jedes Steuerelement Ihres Dialogs eine Elementvariable
einzurichten. Die Implementierung sorgt dann dafr, da beim Aufrufen des Dialogs die Steuerelemente mit den Werten der zugehrigen
Elementvariablen initialisiert werden und da beim Abschicken des
Dialogs die Elementvariablen umgekehrt mit den Eingaben aus den
Steuerelementen aktualisiert werden.
Elementvariablen fr Dialogelemente einrichten:
1. Rufen Sie den Klassen-Assistenten auf (Befehl ANSICHT/KLASSENASSISTENT), und wechseln Sie zur Seite MEMBER-VARIABLEN.
2. Whlen Sie im Feld KLASSENNAME die Dialogklasse aus. Wenn Sie
noch keine Dialogklasse fr Ihre Dialogressource eingerichtet
haben, knnen Sie dies durch Klick auf den Schalter KLASSE HINZUFGEN/NEU nachholen.
3. Whlen Sie im Feld STEUERELEMENT-IDS ein Steuerelement aus.
4. Klicken Sie auf den Schalter VARIABLE HINZUFGEN. Im Dialog
MEMBER-VARIABLE HINZUFGEN legen Sie neben dem Namen auch
noch Kategorie und Variablentyp der bertragenen Daten fest.
Im Feld KATEGORIE entscheiden Sie, ob der Inhalt des Steuerelements (Wert) oder eine Referenz auf das Steuerelement
(Control) bertragen werden soll.

66

Kapitel 3: Die Assistenten

Im Feld VARIABLENTYP whlen Sie den genauen Datentyp aus


(blicherweise ist dieser bereits durch den Typ des Steuerelements festgelegt).
Wenn Sie eine neue Member-Variable definieren, aktualisiert der Klassen-Assistent den Quellcode Ihrer Applikation an verschiedenen Positionen. Das Hinzufgen einer int-Variablen m_nShape fhrt beispielsweise zu der folgenden nderung in der CMCTLPropPage-Header-Datei:
// Dialog Data
//{{AFX_DATA(CMCTLPropPage)
enum { IDD = IDD_PROPPAGE_MCTL };
int
m_nShape;
//}}AFX_DATA

Der Klassen-Assistent verndert auch die Implementierungsdatei der


Klasse. Dem Klassen-Konstruktor wurden Initialisierungen fr die neuen Variablen hinzugefgt:
CMCTLPropPage::CMCTLPropPage() :
COlePropertyPage(IDD, IDS_MCTL_PPG_CAPTION)
{
//{{AFX_DATA_INIT(CMCTLPropPage)
m_nShape = -1;
//}}AFX_DATA_INIT
}

Eine weitere Funktion, die von dem Klassen-Assistenten modifiziert


wurde, ist die DoDataExchange-Member-Funktion. In dieser Funktion
werden Informationen zwischen dem Steuerelementobjekt selbst und
der Variable ausgetauscht, die den Wert des Objekts reprsentiert. Fr
CMCTLPropPage wird die Funktion wie folgt modifiziert:
///////////////////////////////////////////////////////////////////
// CMCTLPropPage::DoDataExchange Moves data between page and properties
void CMCTLPropPage::DoDataExchange(CDataExchange* pDX)
{
//{{AFX_DATA_MAP(CMCTLPropPage)
DDP_CBIndex(pDX, IDC_CBSHAPE, m_nShape, _T("Shape") );
DDX_CBIndex(pDX, IDC_CBSHAPE, m_nShape);
//}}AFX_DATA_MAP
DDP_PostProcessing(pDX);
}

Zur Erleichterung des Datenaustausches zwischen dem Steuerelementobjekt und der Member-Variablen wird nicht nur eine DDX-Funktion
(Dialog Data Exchange), sondern ebenfalls eine DDP-Funktion (Eigenschaftenseite) aufgerufen. Diese Funktion transferiert Daten zwischen
der Member-Variablen und dem ActiveX-Steuerelementobjekt.
Sollten die Klassen bestimmte Datenstze in Datenbanken reprsentieren, nimmt der Klassen-Assistent mglicherweise Vernderungen an
weiteren Funktionen vor (z.B. an der DoFieldExchange-Member-Funktion der Klasse, die von CRecordSet abgeleitet wird).

Der Klassen-Assistent

3.3.4

67

Automatisierung

Das Register AUTOMATISIERUNG im Dialog des Klassen-Assistenten ermglicht Ihnen das Hinzufgen und Modifizieren von AutomatisierungsEigenschaften und -Methoden (zuvor OLE-Automatisierung). Eine Eigenschaft ist eine Member-Variable, auf die ber die Automatisierungsschnittstelle zugegriffen wird. Eine Methode ist eine Member-Funktion.
Klassen, die ActiveX-Steuerelemente reprsentieren, knnen zustzlich
zur Automatisierung Eigenschaften und Methoden besitzen.
Nicht alle Klassen in Ihrer Applikation untersttzen die Automatisierung. Untersttzung fr Automatisierung knnen Sie beispielsweise
vorsehen, indem Sie bei der Erstellung der Klasse im MFC-Anwendungsassistenten die Option AUTOMATISIERUNG aktivieren.
Automatisierungs-Methode hinzufgen
Abbildung 3.4:
Hinzufgen
einer AutomatisierungsMethode

1. Rufen Sie den Klassen-Assistenten auf (Befehl ANSICHT/KLASSENASSISTENT), und wechseln Sie zur Seite AUTOMATISIERUNG.
2. Whlen Sie im Feld KLASSENNAME die zu automatisierende Klasse
aus. Wenn Sie noch keine entsprechende Klasse fr die Automatisierung eingerichtet haben, knnen Sie dies durch Klick auf den
Schalter KLASSE HINZUFGEN/NEU nachholen.
3. Klicken Sie auf den Schalter METHODE HINZUFGEN. Im Dialog
METHODE HINZUFGEN machen Sie folgende Angaben:

68

Kapitel 3: Die Assistenten

Den externen Namen der Methode. Unter diesem Namen knnen Automatisierungs-Clients auf die Methode zugreifen. Reprsentiert die Klasse ein ActiveX-Steuerelement, knnen Sie
den Namen einer Standardmethode ebenfalls aus dem Kombinationsfeld unter EXTERNER NAME auswhlen.
Den internen Namen. Unter diesem Namen wird die Methode
in der C++-Klasse des Servers deklariert und definiert.
Einen Rckgabetyp.
Den Implementierungstyp.
Etwaige Parameter. Doppelklicken Sie dazu einfach in die leere Schablone, und geben Sie den Parameternamen ein. Den
Typ whlen Sie aus einer Liste aus.
Eigenschaften automatisieren
1. Rufen Sie den Klassen-Assistenten auf (Befehl ANSICHT/KLASSENASSISTENT), und wechseln Sie zur Seite AUTOMATISIERUNG.
2. Whlen Sie im Feld KLASSENNAME die zu automatisierende Klasse
aus. Wenn Sie noch keine entsprechende Klasse fr die Automatisierung eingerichtet haben, knnen Sie dies durch Klick auf den
Schalter KLASSE HINZUFGEN/NEU nachholen.
3. Klicken Sie auf den Schalter EIGENSCHAFT HINZUFGEN. Im Dialog
EIGENSCHAFT HINZUFGEN machen Sie folgende Angaben:
Den externen Namen der Eigenschaft. Unter diesem Namen
knnen Automatisierungs-Clients auf die Methode zugreifen.
Einen Typ. Den Datentyp der Eigenschaft whlen Sie aus der
Liste aus.
Den Implementierungstyp. Entscheiden Sie sich hier zwischen
Member-Variable und Get/Set-Methoden.
Falls Sie Member-Variable gewhlt haben:
Den Variablennamen. Geben Sie hier den Namen des zugehrigen Datenelements in der C++-Klasse ein.
Eine Benachrichtigungsfunktion. Diese Funktion wird aufgerufen, wenn sich der Wert der Member-Variablen gendert hat.
Etwaige zustzliche Parameter.

Der Klassen-Assistent

69

Falls Sie Get/Set-Methoden gewhlt haben:


Eine Get-Funktion. ber diese Methode wird der Wert der
Eigenschaft zurckgeliefert.
Fr ActiveX-Steuerelemente knnen Sie den Grad der Untersttzung fr die Datenverbindung bestimmen, die Sie Ihrem Steuerelement hinzufgen mchten. Datenverbindung ist ein Begriff, der fr
die Mglichkeit steht, ActiveX-Steuerelement-Eigenschaften an bestimmte Felder einer Datenbank zu binden. Bettigen Sie die
Schaltflche Datenverbindung, um mit Hilfe des gleichlautenden
Dialogs den Grad der Datenverbindung zu bestimmen, den die Eigenschaft untersttzen soll, und um eine Eigenschaft zu definieren, die anschlieend gebunden werden kann.

3.3.5

ActiveX-Ereignisse

ActiveX-Ereignisse werden von ActiveX-Steuerelementen generiert.


Ereignisse sind ein Medium fr die Kommunikation zwischen dem
Steuerelement und dessen Container.
Die ActiveX-Ereignisse einer ActiveX-Steuerelementklasse knnen in
dem Register ACTIVEX-EREIGNISSE des Klassen-Assistenten definiert
oder modifiziert werden.
Abbildung 3.5:
Erstellen eines
ActiveX-Ereignisses

70

Kapitel 3: Die Assistenten

1. Rufen Sie den Klassen-Assistenten auf (Befehl ANSICHT/KLASSENASSISTENT), und wechseln Sie zur Seite ACTIVEX-EREIGNISSE.
2. Whlen Sie im Feld KLASSENNAME die Klasse des ActiveX-Steuerelements aus. Wenn Sie noch keine entsprechende Klasse fr die
Automatisierung eingerichtet haben, knnen Sie dies durch Klick
auf den Schalter KLASSE HINZUFGEN/NEU nachholen.
3. Klicken Sie auf den Schalter EREIGNIS HINZUFGEN. Im Dialog
EREIGNIS HINZUFGEN machen Sie folgende Angaben:
Den externen Namen des Ereignisses. Sie knnen entweder
ein eigenes Ereignis definieren oder ein vordefiniertes Ereignis
auswhlen.
Der interne Name ist der Name der Member-Funktion, die das
Ereignis auslst. Der Name ist eine Kombination aus dem
Wort Fire und dem externen Namen. Fr ein Ereignis mit der
Bezeichnung Select gibt der Klassen-Assistent somit den Funktionsnamen FireSelect vor.
Den Implementierungstyp. Fr vordefinierte Ereignisse kann
eine vordefinierte Implementierung bestimmt werden oder
eine benutzerdefinierte Implementierung vorgesehen werden.
Die Parameter der auslsenden Funktion.
Nachdem ein neues Ereignis definiert wurde, modifiziert der KlassenAssistent die Header-Datei Ihrer Klasse, indem er das Ereignis in die
Ereignistabelle eintrgt. Das Ereignis wird der Klasse in Form seiner
auslsenden Funktion und seiner Inline-Implementierung hinzugefgt.
Fr das benutzerdefinierte Ereignis Select modifiziert der Klassen-Assistent die Ereignistabelle wie folgt:
// Event maps
//{{AFX_EVENT(CMCTLCtrl)
void FireSelect(BOOL IsSelected)
{FireEvent(eventidSelect,EVENT_PARAM(VTS_BOOL), IsSelected);}
//}}AFX_EVENT
DECLARE_EVENT_MAP()

Das Ereignis wird ausgefhrt, wenn Sie die auslsende Funktion aus
anderen Funktionen in Ihrem Programmcode aufrufen.

3.3.6

Klassen-Info

Das letzte Register des Klassen-Assistenten ist mit KLASSEN-INFO bezeichnet. Hier werden verschiedene Klasseneigenschaften aufgefhrt.
Des weiteren knnen in dem Register bestimmte erweiterte Optionen
modifiziert werden.

Die Klasseninformationsdatei

C Die erste der erweiterten Optionen, die mit FILTER FR NACHRICHTEN bezeichnet ist, ermglicht Ihnen zu bestimmen, welche Nachrichten der Klassen-Assistent in der Nachrichtenzuordnungstabelle
auffhren soll. Beachten Sie bitte, da sich das Verndern des
Nachrichtenfilters nicht auf den Programmcode Ihrer Applikation
auswirkt. Die hier vorgenommene Einstellung betrifft lediglich die
Anzeige der Nachrichten.
C Die Option FREMDKLASSE ist fr Datenbank-Applikationen relevant. Die Ansichtsklasse einer Datenbank-Applikation, die von
CRecordView oder CDaoRecordView abgeleitet wird, ist mit einer
Datensatzklasse verknpft, die sich wiederum von CRecordSet
oder CDaoRecordSet ableitet. In diesem Fall trgt die Fremdklasse
die Bezeichnung der Datensatzklasse. Die Fremdklasse ist ein Zeiger in die Ansichtsklasse Ihrer Applikation, die ein FremdklassenObjekt reprsentiert. Der Klassen-Assistent mu die Fremdklasse
identifizieren knnen, da er auf die Member-Variablen der Datensatzklasse verweisen und deren Member-Funktion OnFieldExchange aktualisieren knnen mu.

3.4

Die Klasseninformationsdatei

Der Klassen-Assistent kann nicht den gesamten Quellcode Ihrer Applikationen analysieren. Die Informationen, die nicht aus der Quelldatei
ermittelt werden knnen, werden in einer besonderen Datei, der Klasseninformationsdatei, gespeichert. Diese Datei trgt dieselbe Bezeichnung wie Ihr Projekt. Die Dateiendung lautet .CLW.
Die Informationen fr die .clw-Datei knnen nur dann aus dem Quelltext ausgelesen werden, wenn im Quelltext entsprechende Makros zur
Untersttzung des Klassen-Assistenten verwendet werden (Codeabschnitte auerhalb dieser Bereiche werden vom Klassen-Assistenten
nicht angetastet). Sofern Sie einen Anwendungs-Assistenten oder den
Klassen-Assistenten zur Bearbeitung Ihres Quelltextes nutzen, werden
diese Makros automatisch eingefgt. Die gleichen Markierungen verwendet der Klassen-Assistent, um Code in Ihr Projekt einzufgen.
Hierzu gehrt beispielsweise, da die Deklarationen fr Antwortfunktionen zu Botschaften zwischen die Makros //{{AFX_MSG(CFensterklasse) und //}}AFX_MSG geschrieben werden und als afx_msg deklariert
werden:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG

71

72

Kapitel 3: Die Assistenten

nderungen, die Sie mit Hilfe des Klassen-Assistenten vorgenommen


haben, werden automatisch in der .clw-Datei eingetragen.
Wenn Sie einen Quelltext von Hand bearbeitet haben und die Informationen fr den Klassen-Assistenten danach aktualisieren wollen, lschen Sie die .clw-Datei im Windows Explorer und lassen die Datei
dann vom Klassen-Assistenten neu erstellen, wobei Sie darauf achten
sollten, da alle Header- und Quelltextdateien des Projekts im Feld Dateien im Projekt aufgefhrt werden.

3.5

Zusammenfassung

Anwendungsassistenten befreien Sie von lstigen Routinearbeiten


von dem Anlegen eines Projekts mit Quelldateien bis zur Implementierung eines lauffhigen Grundgersts.
ber DATEI/NEU gelangen Sie zu einem Dialogfeld, in dem Sie zwischen verschiedenen Anwendungsassistenten und Projekttypen whlen
knnen.
Am leistungsfhigsten ist der MFC-Anwendungsassistent, mit dem Sie
Windows-MFC-Anwendungen mit oder ohne Doc/View als SDI, MDI
oder dialogbasierte Anwendung erstellen lassen knnen. Der Anwendungsassistent kann zudem fr eine Datenbankuntersttzung, ActiveXund OLE-Features, Fensterdekorationen, kontextabhngige Hilfe und
vieles mehr sorgen.
Der Klassen-Assistent ist ein weiteres wesentliches Werkzeug des Visual-C++-Entwicklungssystems. Mit Hilfe des Assistenten knnen Sie
Projekte, die mit dem MFC-Anwendungsassistenten generiert wurden,
weiter bearbeiten.
Der Klassen-Assistent wird in einem Dialog mit fnf Registern ausgefhrt.
C Das erste dieser Register, das mit NACHRICHTENZUORDNUNGSTABELLE bezeichnet ist, ermglicht Ihnen die Definition von Bearbeitungsfunktionen fr verschiedene Ereignisse.
C In dem Register MEMBER-VARIABLEN knnen Sie Member-Variablen fr den Datenaustausch mit Dialog-Steuerelementen oder Datenbankformularen einrichten.
C Das Register AUTOMATISIERUNG dient der Einrichtung von verschiedenen Automatisierungs-Methoden und -Eigenschaften fr
Klassen, die Automatisierung untersttzen. Fr ActiveX-Steuerelemente knnen Sie vordefinierte sowie benutzerdefinierte Methoden und Eigenschaften bestimmen.

Zusammenfassung

C Das Register ACTIVEX-EREIGNISSE dient der Definition von ActiveX-Ereignissen, die von einem ActiveX-Steuerelement generiert
werden knnen.
C In dem Register KLASSEN-INFO werden einige allgemeine Informationen zu bestimmten Klassen angezeigt.
C Neue Klassen knnen von Grund auf aus Typenbibliotheken und
aus bestehenden Header- und Implementierungsdateien generiert
werden.

73

Browser und Debugger

Kapitel
B

rowser und Debugger sind zwei Entwicklertools, die einem hnlichen Zweck dienen, aber unterschiedlichen Einsatzgebieten angehren.
Beide Tools dienen dazu, uns detailliert ber den Zustand eines Programms zu informieren.
Der Browser vermittelt dabei allerdings nur ein statisches Bild des Programms. Er fhrt uns zu Definitionen und Referenzen, zeichnet Klassenhierarchien und Funktionsaufrufe nach.
Der Debugger erlaubt uns, ein Programm whrend der Ausfhrung zu
kontrollieren. Mit seiner Hilfe knnen wir zur Laufzeit die Programmausfhrung gezielt anhalten und uns die augenblicklichen Werte von
Variablen, den Zustand des Stacks und andere aktuelle Informationen
anzeigen lassen.
Beide Tools sind auf spezielle Informationen angewiesen, die whrend
der Kompilierung erzeugt werden mssen.

4.1

Der Quellcode-Browser

Der Quellcode-Browser dient anders als Assistentenleiste und Klassen-Ansicht rein der Analyse des Quelltextes, kennt also keine Befehle zum Einfgen von Klassen oder Klassenmethoden. Dafr kann Ihnen der Quellcode-Browser Informationen zusammenstellen, die
Assistentenleiste und ClassView nicht kennen. So
C untersttzt der Quellcode-Browser auch lokale Variablen,
C kann der Quellcode-Browser die in einer Datei verwendeten Bezeichner auflisten,

76

Kapitel 4: Browser und Debugger

C steht der Quellcode-Browser hinter verschiedenen Befehlen, die


auch in den Kontextmens der Klassen-Ansicht verfgbar sind, beispielsweise die Darstellung von Klassenhierarchien.

4.1.1

Hinzufgen von Browser-Informationen zu einem


Projekt

Der Quellcode-Browser ist zur Ausfhrung seiner Befehle auf spezielle


Browser-Informationen angewiesen. Um dem Projekt Browser-Informationen hinzuzufgen, mssen Sie Ihre Projekteinstellungen ndern.
Alternativ dazu knnen Sie das Programm BSCMAKE.EXE aufrufen.
Projekteinstellungen ndern
Um Browser-Informationen zu erzeugen, aktivieren Sie im Dialogfeld
PROJEKTEINSTELLUNGEN (Aufruf ber PROJEKT/EINSTELLUNGEN) fr
den Projektknoten die Optionen
C BROWSE-INFO GENERIEREN auf der Seite C/C++, Kategorie ALLGEMEIN,
C BROWSER-INFORMATIONSDATEI ERSTELLEN auf der Seite BROWSEINFORMATION,
und lassen Sie das Projekt neu erstellen.
Sollten Sie versuchen, Browser-Features zu nutzen, wenn keine
Browser-Informationsdatei vorhanden ist, gibt das Developer Studio eine Warnung aus und bietet Ihnen an, das Projekt einschlielich der erforderlichen Browser-Informationen erneut zu erstellen.
Browser-Informationsdatei lschen
Die Browser-Informationen werden in einer uerst umfangreichen
Datei (Extension .bsc) abgelegt. Lschen Sie diese, wenn Sie die Browser-Informationen nicht mehr bentigen. Sie knnen die .bsc-Datei fr
den Browser nur dann lschen, wenn der Browser den Zugriff auf sie
freigegeben hat. Rufen Sie dazu den Menbefehl EXTRAS/QUELLCODEBROWSER-DATEI SCHLIESSEN auf.

4.1.2

Mit dem Quellcode-Browser arbeiten

1. Rufen Sie den Quellcode-Browser auf (Befehl QUELLCODE-BROWSER im Men EXTRAS). Es erscheint das Dialogfeld DURCHSUCHEN.
2. Geben Sie den Bezeichner ein, ber dessen Verwendung Sie sich
informieren wollen.

Der Debugger

77

Abbildung 4.1:
Das Fenster des
Browsers

Wenn Sie mchten, knnen Sie den Bezeichner (Klasse, Methode,


lokale oder globale Variable etc.) auch vor dem Aufruf des Quellcode-Browsers im Quelltext oder der Klassen-Ansicht markieren. Der
Name wird dann direkt in das Feld BEZEICHNER bertragen, und
Sie vermeiden Tippfehler.
3. Rufen Sie einen der Befehle im Listenfeld ABFRAGE AUSWHLEN
auf.

4.2

Der Debugger

Eines der leistungsfhigsten Features von Visual C++ ist der integrierte
Symbol-Debugger. Mit Hilfe dieses Werkzeugs knnen Sie Ihre Programme whrend der Ausfhrung berwachen. Sie knnen das Programm mittels Haltepunkten an definierten Stellen anhalten, es schrittweise ausfhren lassen, sich Informationen ber die Werte von
Variablen, den Zustand des Stacks, etc. anzeigen lassen.
Zudem untersttzt der Visual-C++-Compiler Just-In-Time-Testlufe
(das Testen von abgestrzten Programmen, auf die auerhalb der Entwicklungsumgebung zugegriffen wurde) und Remote-Testlufe. Der
Debugger ist ebenso wie andere Features (Quellcode-Browser oder
Quellcode-Editor) vollstndig in die Visual-Studio-Umgebung integriert.

4.2.1

Vorbereiten einer Anwendung auf den Testlauf

Damit der Debugger korrekt arbeiten kann, ist er auf entsprechende


Debug-Informationen in den .obj- und .exe-Dateien angewiesen. Damit
diese erstellt werden, sind folgende Projekteinstellungen ntig:

Erstellen/Debug
starten fhrt eine
Anwendung im
Debugger aus

78

Kapitel 4: Browser und Debugger

Auf der Seite C/C++, Kategorie ALLGEMEIN der Projekteinstellungen:


C PROGRAMMDATENBANK oder PROGRAMMDATENBANK FR BEARBEITEN UND FORTFAHREN im Feld DEBUG-INFO. Letztere Einstellung
untersttzt das Debuggen editierten Codes ohne Neukompilation
(siehe unten). (Kommandozeilenoption /ZI)
C OPTIMIERUNGEN (DEAKTIVIEREN (DEBUG)), um eine mglichst vollstndige bereinstimmung zwischen Ihrem Quelltext und dem debuggten Objektcode zu erreichen. (Kommandozeilenoption /Od)
Auf der Seite C/C++, Kategorie CODE GENERATION der Projekteinstellungen:
C Whlen Sie unter LAUFZEIT-BIBLIOTHEK eine passende Debug-Bibliothek aus, um eine Debug-Version der C-Laufzeitbibliothek in
Ihr Projekt einzubinden. (Kommandozeilenoptionen /MDd (DLL
debuggen), /MLd (Single-Thread debuggen) oder /MTd (Multithread debuggen))
Auf der Seite LINKER, Kategorie ALLGEMEIN der Projekteinstellungen:
C DEBUG-INFO GENERIEREN setzen. (Kommandozeilenoption /debug)
Auf der Seite LINKER, Kategorie ANPASSEN der Projekteinstellungen:
C PROGRAMMDATENBANK VERWENDEN setzen.
Auf der Seite LINKER, Kategorie DEBUG der Projekteinstellungen:
C Die Option DEBUG-INFO setzen.
Ist Ihre Applikation eine MFC-Anwendung, die mit dem Anwendungs-Assistenten erstellt wurde, brauchen Sie vermutlich keine
nderungen vorzunehmen. Der Anwendungs-Assistent generiert
gewhnlich eine Debug-Konfiguration zu Ihrem Projekt und deklariert diese als Standardkonfiguration.

4.2.2

Ausfhren einer Anwendung im Debugger

Nachdem Sie Ihre Anwendung mit den Debug-Einstellungen kompiliert


haben, knnen Sie die Anwendung im Debug-Modus ausfhren lassen,
indem Sie einen der Eintrge aus dem Untermen DEBUG STARTEN
auswhlen, das wiederum in dem Men ERSTELLEN enthalten ist:
C ERSTELLEN/DEBUG STARTEN/AUSFHREN ((F5)). Fhrt Programm
ganz bzw. bis zum nchsten Haltepunkt aus.

Der Debugger

C ERSTELLEN/DEBUG STARTEN/IN AUFRUF SPRINGEN ((F11)). Startet


das Programm und stoppt es zu Beginn der Eintrittsfunktion
(main(), WinMain()). Ansonsten fhrt dieser Befehl das Programm
schrittweise aus.
C ERSTELLEN/DEBUG STARTEN/AUSFHREN BIS CURSOR ((Strg) +
(F10)). Fhrt das Programm bis zur aktuellen Cursorposition aus.
C ERSTELLEN/DEBUG STARTEN/VERBINDEN MIT PROZESS. Verbindet
den Debugger nachtrglich mit einem bereits in der Ausfhrung
befindlichen Programm (wird ber ein Dialogfeld ausgewhlt).
DLLs debuggen
Fr DLLs ist das Feld Ausfhrbares Programm fr Debug-Sitzung
interessant. Verwenden Sie dieses Eingabefeld, um DLL-Projekte
zu debuggen. Geben Sie jedoch nicht den Namen der DLL, sondern
den Namen des Programms an, das die DLL ldt und testet. Um
beispielsweise ein ActiveX-Steuerelement zu debuggen (das ein besonderer DLL-Typ ist), verwenden Sie die Anwendung
tstcon32.exe.
Wenn Sie eine Debug-Sitzung starten, erscheinen abhngig von Ihren
Visual-Studio-Einstellungen verschiedene Debug-Fenster. In der Menleiste von Visual Studio wird das Men ERSTELLEN durch das Men DEBUG ersetzt.
Der nchste Schritt besteht darin, die Anwendung gezielt anzuhalten,
um sich dann ber den aktuellen Zustand des Programms informieren
zu knnen.

4.2.3

Haltepunkte und Einzelschrittausfhrung

Die beiden wesentlichen Features des Debuggers sind das Einfgen


von Haltepunkten in den Programmcode und die Einzelschrittausfhrung des Programms.
Haltepunkte setzen
Die einfachste Mglichkeit, einen Haltepunkt zu setzen, besteht darin,
die Schreibmarke an die gewnschte Position im Quellcode zu bewegen und dort die Taste (F9) zu drcken. Ein Haltepunkt ist durch einen
groen roten Punkt links von der Programmzeile gekennzeichnet (siehe Abbildung 4.2).

79

80

Kapitel 4: Browser und Debugger

Abbildung 4.2:
Haltepunkt
setzen

Beachten Sie, da Sie auch in dem Fenster Disassemblierung Haltepunkte setzen knnen.
Haltepunkte deaktivieren oder lschen
Um einen Haltepunkt zu lschen, setzen Sie die Schreibmarke auf die
Zeile mit dem Haltepunkt und drcken erneut die Taste (F9).
Wollen Sie den Haltepunkt gesetzt lassen (fr sptere Verwendung),
ihn aber im Moment beim Debuggen nicht bercksichtigen, knnen
Sie ihn im Haltepunktfenster deaktivieren. Rufen Sie dazu das Haltepunktfenster auf (Befehl BEARBEITEN/HALTEPUNKTE) und deaktivieren
Sie ihn, indem Sie auf das Hkchen neben dem Haltepunkt klicken.
Spezielle Haltepunkte
Im Dialogfeld HALTEPUNKTE (Aufruf ber BEARBEITEN/HALTEPUNKTE)
knnen Sie zwischen drei verschiedenen Haltepunkttypen whlen.
C Pfad-Haltepunkte unterbrechen die Programmausfhrung an einer
bestimmten Stelle im Programmcode. Dies sind die Haltepunkte,
die Sie mit Hilfe der Taste (F9) setzen. Sie knnen einem PfadHaltepunkt eine Bedingung hinzufgen. Das Programm wird in
diesem Fall nur dann unterbrochen, wenn die angegebene Bedingung erfllt ist.
C Daten-Haltepunkte unterbrechen die Programmausfhrung, wenn
sich der Wert des angegebenen Ausdrucks verndert. Daten-Haltepunkte implizieren eine Speicherberwachung und knnen den
Debug-Proze verlangsamen.

81

Der Debugger

C Der NACHRICHTEN-Haltepunkt unterbricht die Programmausfhrung, wenn die angegebene Nachricht von einer Ihrer WindowsProzeduren empfangen wurde. Fr API-Programme sind dies die
von Ihnen definierten Fensterfunktionen; in MFC-Programmen
knnen Sie die entsprechenden botschaftsverarbeitenden Methoden der MFC angeben.
Programmausfhrung
Die Programmausfhrung kann ebenfalls unterbrochen werden, indem Sie aus dem Men DEBUG den Eintrag ANHALTEN auswhlen.
Interessant ist aber nicht nur das Anhalten des Programms im Debugger, sondern auch die schrittweise Ausfhrung:
Debug-Befehl

Krzel

Beschreibung

In Aufruf springen

(F11)

Fhrt die jeweils nchste Programmzeile Ihrer Quelldatei oder


die nchste Anweisung in dem
Fenster DISASSEMBLIERUNG aus.
Ist in dieser Programmzeile ein
Funktionsaufruf enthalten, verzweigt die Einzelschrittausfhrung
in diese Funktion.

Aufruf als ein Schritt

(F10)

hnlich wie IN AUFRUF SPRINGEN.


Die Einzelschrittausfhrung verzweigt jedoch nicht in Funktionen.
Statt dessen werden Funktionen
vollstndig ausgefhrt.

Ausfhren bis
Rcksprung

()+(F11)

Fhrt die aktuelle Funktion aus.

Ausfhren bis Cursor

(Strg)+(F10) Fhrt das Programm bis zu der


Position in dem Quellcode- oder
Assembler-Fenster aus, an der
sich ein Haltepunkt oder die
Schreibmarke befindet.

Bisweilen ist es mglich, da das


Programm whrend der Ausfhrung einer Systemfunktion unterbrochen wird. Whlen Sie in solchen Situationen wiederholt
diesen Befehl, bis Sie sich wieder
in Ihrem Programmcode befinden.

Tabelle 4.1:
Befehle zur
schrittweisen
Ausfhrung

82

Kapitel 4: Browser und Debugger

4.2.4
Die DebugFenster werden
ber das Men
Ansicht aufgerufen

Die Debug-Fenster

Whrend eines Testlaufs fhrt Visual Studio Debug-Informationen in


verschiedenen Debug-Fenstern auf. Diese Fenster werden ber die entsprechenden Eintrge des Mens ANSICHT geffnet, sofern sie nicht
bereits angezeigt werden. Die Fenster knnen in der gewohnten Ansicht oder gedockt dargestellt werden. In der gedockten Ansicht werden sie ebenfalls in den Kontextmens der Symbolleisten aufgefhrt.
(Sie ffnen das Kontextmen einer Symbolleiste, indem Sie den Mauszeiger auf einen freien Bereich der Leiste bewegen und mit der rechten
Maustaste klicken.)
Das Fenster berwachung

Abbildung 4.3:
Das Fenster
berwachung

In diesem Fenster knnen die Werte ausgewhlter Variablen berwacht werden.


C Um eine neue Variable zur berwachung einzurichten, doppelklikken Sie einfach in die leere Schablone in der Spalte NAME, und geben Sie den Namen der zu berwachenden Variablen (oder einen
Ausdruck) ein. Alternativ knnen Sie einen Namen auch per
Drag&Drop aus Ihrem Quelltext in das Feld ziehen.
C In der Spalte WERT wird der aktuelle Inhalt der Variablen angezeigt
(fr Ausdrcke wird der Wert des berechneten Ausdrucks angezeigt).
Wenn Sie hier einen Wert ndern, wird die nderung an das Programm weitergereicht. Sie knnen auf diese Weise das Programm
schnell fr verschiedene Variablenwerte austesten.
C Um eine Variable aus der berwachung zu streichen, markieren
Sie den Eintrag der Variablen, und drcken Sie die (Entf)-Taste.
C Zur bersichtlicheren Verwaltung der zu berwachenden Ausdrkke stellt Ihnen das Fenster vier einzelne Seiten zur Verfgung.

Der Debugger

83

Um sich schnell ber den Inhalt einer aktuellen Variablen zu informieren, knnen Sie statt dieses Fensters auch die Debugger-Untersttzung des Texteditors nutzen und einfach den Mauszeiger fr
eine Weile auf den Bezeichner der Variablen rcken.
Das Fenster Aufrufliste
Abbildung 4.4:
Das Fenster
Aufrufliste

Dieses Fenster zeigt Ihnen an, welche Funktionen bis zum Erreichen
der aktuellen Ausfhrungsposition aufgerufen (und noch nicht beendet)
wurden. Sie knnen in diesem Fenster also die Aufrufabfolge der Funktionen (einschlielich der Parameterwerte) und den aktuellen Zustand
des Programm-Stacks kontrollieren.
Das Fenster Speicher
Abbildung 4.5:
Das Fenster
Speicher

Dieses Fenster liefert Ihnen verschiedene Ansichten Ihres Speichers. In


der Abbildung ist p beispielsweise ein Zeiger auf eine von CObject abgeleitete Klasse mit zwei Integer-Datenelementen x und y, die die Werte
3 (hexadezimal 0000 0003) und 15 (hexadezimal 0000 000F) haben.
C Um zwischen den verschiedenen Darstellungen des Speicherinhalts zu wechseln, klicken Sie mit der rechten Maustaste in das
Fenster, um das zugehrige Kontextmen aufzurufen, und whlen
Sie einen der folgenden Befehle: Byte-Format (In dieser Ansicht
wird zustzlich versucht, den Speicherinhalt als Text zu interpretieren.), Kurzes Hex-Format (Short), Langes Hex-Format (Long).

84

Kapitel 4: Browser und Debugger

C Um zu einer bestimmten Adresse zu springen, geben Sie die


Adresse in das gleichnamige Feld ein (beispielsweise im Hexadezimalformat (0x00840885) oder als Zeigervariable), oder ziehen Sie
eine Adresse (als direkte Adresse oder als Variablennamen) per
Drag&Drop aus dem Quelltext oder einem anderen Debug-Fenster
in das Speicher-Fenster.
Das Fenster Variablen
Abbildung 4.6:
Das Fenster
Variablen

Mit Hilfe dieses Fensters knnen Sie sich schnell und bequem ber die
Inhalte der aktuellen Variablen informieren.
Das Fenster verfgt ber drei verschiedene Seiten:
C Die Registerkarte AUTO zeigt Informationen ber die Variablen der
aktuellen Anweisung sowie der vorangegangenen Anweisung an.
C Die Registerkarte LOKAL zeigt die Namen und Werte aller lokalen
Variablen der aktuellen Funktion an. Wenn Sie durch das Programm gehen, werden je nach Kontext andere Variablen angezeigt.
C Die Registerkarte THIS zeigt Namen und Inhalt des Objekts an, auf
das der this-Zeiger gerichtet ist. Alle Basisklassen des Objekts werden automatisch eingeblendet.
Sie selbst haben keine Mglichkeit, Variablen zur berwachung in diesem Fenster einzurichten benutzen Sie dazu das Fenster BERWACHUNG.

Der Debugger

85

Das Fenster Register


Abbildung 4.7:
Das Fenster
Register

Dieses Fenster zeigt die Namen und aktuellen Werte der plattformspezifischen CPU-Register und Attribute sowie den Fliekomma-Stack an.
Das Fenster Disassemblierung
Abbildung 4.8:
Das Feld Disassemblierung

Dieses Fenster zeigt die Assembleranweisungen an, die der Compiler


fr den Quellcode generiert.
C Wenn Sie im Kontextmen des Fensters den Befehl QUELLCODEANMERKUNG gesetzt haben, wird ber den Assembleranweisungen
der zugehrige Quelltext angezeigt.
C Ein spezielles Feature des Fensters DISASSEMBLIERUNG ist in dem
Kontextmen aufgefhrt, das nach einem Klick auf die rechte
Maustaste geffnet wird. Die Option NCHSTE ANWEISUNG SETZEN
ermglicht Ihnen, den Befehlszeiger zu verndern. Dieser wird
nach einer Auswahl der Option auf die Adresse der Anweisung gesetzt, die sich unter der Schreibmarke befindet. Sie knnen dieses
Feature verwenden, um bestimmte Abschnitte Ihres Programmcodes zu berspringen. Sie sollten mit dieser Option jedoch sehr vorsichtig umgehen. Setzen Sie den Befehlszeiger mit NCHSTE ANWEISUNG SETZEN niemals auf die Anweisung einer anderen
Funktion, und achten Sie darauf, da der Stack die korrekten Wer-

86

Kapitel 4: Browser und Debugger

te enthlt. Sollten Sie diese Hinweise nicht bercksichtigen, sind


die Ergebnisse unberechenbar, so da die im Testlauf befindliche
Applikation mglicherweise abstrzt.

4.2.5

Schnellberwachung im Editorfenster

Bisweilen ist es erforderlich, den Wert bestimmter Symbole zu ermitteln, die nicht in den Fenstern VARIABLEN und BERWACHUNG aufgefhrt sind. Der Visual-C++-Debugger stellt zu diesem Zweck zwei Hilfsmittel zur Verfgung: die SCHNELLBERWACHUNG und DATENINFO.
DatenInfo
Abbildung 4.9:
DatenInfo im
Debug-Modus

DatenInfo ist hnlich dem bekannten QuickInfo, das Hinweise zu


Schaltflchen oder anderen Anwenderschnittstellen anzeigt, wenn der
Mauszeiger fr eine kurze Zeit darber angeordnet wird. Bewegen Sie
den Mauszeiger whrend des Debug-Vorgangs auf den Namen eines
Symbols, das ausgewertet werden kann, wird der Wert des Symbols in
einem kleinen gelben Kstchen angezeigt (siehe Abbildung 4.9).
Schnellberwachung
Gengen Ihnen die Informationen des DatenInfos nicht, knnen Sie
den Dialog SCHNELLBERWACHUNG aufrufen (siehe Abbildung 4.10).
Whlen Sie dazu aus dem Men DEBUG den Eintrag SCHNELLBERWACHUNG aus. Befindet sich die Schreibmarke auf einem Symbolnamen,
erscheint das Symbol automatisch in dem Dialog. Ist statt dessen ein
Ausdruck markiert, wird dieser in dem Dialog aufgefhrt.

87

Der Debugger

Abbildung 4.10:
Schnellberwachung

Die Funktion und der Aufbau des Dialogs SCHNELLBERWACHUNG


gleicht der Funktion und dem Aufbau des Fensters BERWACHUNG. Sie
verwenden dieses Fenster, um die Werte der Variablen eines einfachen
Datentyps zu verndern.

4.2.6

Bearbeiten und Fortfahren

Kompilierte Programme haben blicherweise den Nachteil, da sie Bequemer


recht unbequem zu debuggen sind. Wurde whrend einer Debug-Sit- debuggen
zung ein Fehler entdeckt, mute der Programmierer bislang die DebugSitzung beenden, den Fehler im Editor beseitigen, die Anwendung neu
kompilieren und dann erneut im Debugger austesten.
Seit VC 6.0 gibt es nun die Mglichkeit, ein Programm whrend des
Debuggens zu bearbeiten und dann mit der aktuellen Debug-Sitzung
fortzufahren.
Haben Sie whrend des Debuggens einen Fehler ausfindig gemacht:
1. ndern Sie den Quelltext
2. Rufen Sie den Befehl DEBUG/CODE-NDERUNGEN ZUWEISEN auf,
und warten Sie bis der Code automatisch neu kompiliert wurde.
(Wenn Sie die Debug-Sitzung nach einem Haltepunkt fortsetzen,
knnen Sie sich den Befehlsaufruf sparen.)
3. Fahren Sie mit Ihrer Debug-Sitzung fort.

88

Kapitel 4: Browser und Debugger

4.3

Weitere Debug-Techniken
und -Tools

Der integrierte Visual-C++-Debugger und die Debug-Features in den


MFC-Klassen stellen noch verschiedene weitere Debug-Techniken zur
Verfgung.

4.3.1

Meldungsfenster

Manchmal ist der Einsatz des integrierten Debuggers strend oder


bertrieben aufwendig. In solchen Fllen kann Sie ein gut plaziertes
Meldungsfenster bei der Suche nach einem schwer auffindbaren Fehler
untersttzen. Muten Sie beispielsweise feststellen, da eine Funktion
mit der Bezeichnung foo, der zwei Parameter bergeben werden, nicht
korrekt in Ihrer Anwendung arbeitet, knnen Sie sehr einfach ermitteln, ob die Funktion die gewnschten Parameter erhlt. Dazu fgen
Sie der Funktion einen AfxMessageBox-Aufruf wie folgt hinzu:
...
char temp[100];
wsprintf(temp, "Calling foo(x = %d, y = %d)", x, y);
AfxMessageBox(temp);
foo(x, y);

4.3.2

TRACE-Diagnosemakros

Wenn eine MFC-Applikation mit Debug-Bibliotheken kompiliert wird,


erzeugen einige MFC-Funktionen eine Debug-Ausgabe. Sie knnen
die Debug-Ausgabe auch in Ihrem eigenen Programmcode verankern,
indem Sie die Makros TRACE, TRACE0, TRACE1, TRACE2 oder TRACE3 verwenden. Die Debug-Ausgabe wird an ein vordefiniertes Objekt vom
Typ CDumpContext gesendet, das mit afxDump bezeichnet ist. Auerdem
erscheint die Ausgabe gewhnlich in dem Ausgabefenster von Visual
Studio (vorausgesetzt, die Anwendung wird im Debugger ausgefhrt).
Um Debug-Informationen einsehen zu knnen, mssen Sie das Register DEBUG in diesem Fenster ffnen.
Um beispielsweise die an die Funktion foo bergebenen Werte zu berprfen, knnten Sie den folgenden Programmcode schreiben:
...
TRACE2("Calling foo(x = %d, y = %d)", x, y);
foo(x, y);

Beachten Sie bitte, da diese Art der Debug-Ausgabe nur dann erfolgen kann, wenn Sie Ihre Applikation fr den Debug-Vorgang kompiliert haben. Ihre Applikation mu auerdem auch dann ber den Debugger gestartet worden sein, wenn Sie keine anderen Debug-Features
nutzen mchten.

Weitere Debug-Techniken und -Tools

Sie sollten die Makros TRACE0, TRACE1, TRACE2 und TRACE3 verwenden,
wenn Sie Speicherkapazitt bentigen, da diese weniger Speicher
als TRACE beanspruchen.
Die TRACE-Makros erfllen so lange keine Funktion, bis die Applikation
fr den Debug-Vorgang erstellt wurde.

4.3.3

Das ASSERT-Makro

Das Makro ASSERT unterbricht die Programmausfhrung, wenn eine bestimmte Bedingung falsch (false) ist. Dieses Makro kann in Debug-Versionen Ihrer Applikation verwendet werden, um beispielsweise zu prfen, ob eine Funktion die korrekten Parameter erhalten hat:
void foo(int x)
{
ASSERT (x >= 0 && x < 100);
...

Das ASSERT_VALID-Makro prft, ob ein Zeiger auf ein zulssiges, von


CObject abgeleitetes Objekt verweist. Verwenden Sie beispielsweise
eine Funktion mit der Bezeichnung GetDocument, die ein Zeiger auf ein
CMyDoc-Objekt zurckgibt, prfen Sie den Zeiger wie folgt:
CMyDoc *pDoc;
pDoc = GetDocument();
ASSERT_VALID(pDoc);
...

ASSERT-Makros unterbrechen die Programmausfhrung, nachdem eine

Meldung ausgegeben wurde, die die Nummer der Zeile angibt, in der
die Assertion nicht erfllt wurde.
In Programmen, die nicht fr den Debug-Vorgang erstellt wurden, haben Assertionsmakros keine Funktion.

4.3.4

Objekt-Dump

Die CObject-Klasse enthlt eine Member-Funktion mit der Bezeichnung


Dump, die den Inhalt eines Objekts an die Debug-Ausgabe bergibt (vorausgesetzt, die Anwendung wird im Debugger ausgefhrt). Sollten Sie
beabsichtigen, dieses Feature zu nutzen, implementieren Sie die DumpMember-Funktion fr Klassen, die Sie direkt oder indirekt von CObject
ableiten.
Enthlt Ihre Applikation beispielsweise eine von CDocument abgeleitete
Klasse mit der Bezeichnung CMyDoc, welche die beiden Member-Variablen m_x und m_y verwendet, knnte Ihre CMyDoc::Dump-Implementierung wie folgt aufgebaut sein:

89

90

Kapitel 4: Browser und Debugger

#ifdef _DEBUG
void CMyDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
dc << "m_x = " << m_x << '\n';
dc << "m_y = " << m_y << '\n';
}
#endif //_DEBUG

4.3.5

Ermitteln von Speicherverlust mit der Klasse


CMemoryState

Die Klasse CMemoryState ermittelt den Speicherverlust, der entsteht,


wenn die C++-Operatoren New oder Delete unsachgem eingesetzt
werden. Erstellen Sie ein CMemoryState-Objekt, und rufen Sie dessen
Member-Funktion Checkpoint auf, um ein Abbild des reservierten Speichers zu erstellen. Spter knnen Sie die Member-Funktion DumpAllObjectsSince aufrufen, um die Inhalte aller Objekte seit dem letzten Aufruf von Checkpoint zu lschen. Um beispielsweise jedes von foo
reservierte Objekt zu lschen, dessen Reservierung nicht vollstndig
von der Funktion rckgngig gemacht werden konnte, verwenden Sie
den folgenden Programmcode:
...
CMemoryState memState;
memState.Checkpoint();
foo(x, y);
memState.DumpAllObjectsSince();

Um die Debug-Ausgabe im Ausgabefenster angezeigt zu bekommen, mu die betreffende Anwendung im Debugger ausgefhrt
werden ((F5)).
Wenn Sie sich nicht den vollstndigen Dump der reservierten Objekte
anzeigen lassen mchten, knnen Sie die Member-Funktion DumpStatistics verwenden. DumpStatistics wird aufgerufen, nachdem die Differenz zwischen zwei Speicherzustnden mit Hilfe der Member-Funktion Difference ausgewertet wurde. Dieses Verfahren erfordert drei
CMemoryState-Objekte. Die ersten beiden Objekte erstellen die Abbilder
der beiden Speicherzustnde, whrend das dritte Objekt die Differenz
ermittelt. Betrachten Sie dazu auch das folgende Beispiel:
// Speicher.cpp Konsolen-Anwendung mit MFC-Einbindung
#include <afxwin.h>
#define new DEBUG_NEW
CMemoryState msOld, msNew, msDif;
class Koord : public CObject
{
public:
int x,y;
Koord(int X, int Y) {x = X; y = Y;}
};

Weitere Debug-Techniken und -Tools

Koord* createKoord(int x, int y)


{
// Achtung!!
// p_tmp ist lokal und wird mit Fkt. aufgelst
// dyn. erzeugtes Koord-Objekt bleibt in Speicher
Koord *p_tmp = new Koord(3,15);
return p_tmp;
}
void main()
{
msOld.Checkpoint();
Koord *p = createKoord(3,15);
msNew.Checkpoint();
msOld.DumpAllObjectsSince(); //gibt allokiertes Objekt aus
msNew.DumpAllObjectsSince(); //gibt keine Objekte aus
//Statistik ausgeben
msDif.Difference( msOld, msNew );
msDif.DumpStatistics();
// bis hierher alles ok
// Zeiger p wird umgesetzt!
// Koord-Objekt (3,15) aus Fkt-Aufruf bleibt in Speicher
p = new Koord(3,14);
delete p;
// lscht nur (3,14)-Objekt
}

CMemoryState-Objekte knnen Speicherverluste, die durch inkorrekte Aufrufe von malloc/free, GlobalAlloc/GlobalFree oder LocalAlloc/
LocalFree verursacht wurden, nicht ermitteln.

4.3.6

Remote-Testlauf

Remote-Testlufe ermglichen das Debuggen von Programmcode, der


auf einem anderen Rechner ausgefhrt wird. Der lokale PC und der
Remote-Rechner sind ber ein serielles Kabel oder ein lokales Netzwerk miteinander verbunden. Der lokale Rechner fhrt Visual Studio
und den integrierten Debugger aus, whrend die zu testende Applikation auf dem Remote-PC mit dem Visual-C++-Debug-Monitor ausgefhrt wird.
Damit ein Remote-Testlauf durchgefhrt werden kann, mu der Remote-Rechner den Visual-C++-Debug-Monitor msvcmon.exe ausfhren.
Damit dieses Programm korrekt ausgefhrt wird, mssen die folgenden DLLs auf dem Remote-Rechner installiert werden: msvcrt.dll,
dm.dll, msvcp60.dll und msdis110.dll. Kopieren Sie diese Dateien in
ein Verzeichnis, das als Systempfad vermerkt ist (z.B. in das WindowsSystemverzeichnis).

91

92

Abbildung 4.11:
RemoteDebuggen

Kapitel 4: Browser und Debugger

Remote-Rechner

Lokaler Rechner

DebugApplikation

Integrierter
Debugger

VC++-DebugMonitor

Developer
Studio

Netzwerktransport

Netzwerktransport

Abbildung 4.12:
Der Visual-C++Debug-Monitor

Starten Sie zunchst den Debug-Monitor auf dem Remote-Computer.


Der Debug-Monitor wird in einem Dialog dargestellt (siehe Abbildung
4.12), in dem Sie die erforderlichen Einstellungen vornehmen. Sie
knnen den Remote-Testlauf ber eine TCP/IP-Netzwerkverbindung
ausfhren. Drcken Sie die Schaltflche EINSTELLUNGEN, um die Details der Verbindung zu bestimmen, nachdem Sie den gewnschten
Verbindungstyp ausgewhlt haben.
Nachdem ein Remote-Testlauf vollstndig konfiguriert wurde, drcken
Sie bitte die Schaltflche VERBINDEN. Der Debug-Monitor wartet nun
auf eine eingehende Verbindung.

Weitere Debug-Techniken und -Tools

93

Abbildung 4.13:
Der Dialog
Remote-Verbindung

Sie mssen Visual Studio auch auf dem lokalen Rechner fr den Remote-Testlauf konfigurieren. Whlen Sie dazu den Eintrag REMOTEVERBINDUNG DES DEBUGGERS aus dem Men ERSTELLEN aus. Daraufhin wird der Dialog REMOTE-VERBINDUNG (siehe Abbildung 4.13) angezeigt, in dem Sie den Verbindungstyp angeben und die Verbindungsoptionen nach einem Klick auf die Schaltflche EINSTELLUNGEN setzen.
Wenn Sie fr den Debug-Vorgang eine TCP/IP-Verbindung einrichten, werden Sie aufgefordert, ein Pawort anzugeben. Stellen Sie
sicher, da dieses Pawort fr beide Rechner, den lokalen PC und
den Remote-Rechner, gleich ist.
Der wesentliche Vorteil des Remote-Debuggens besteht darin, da die
Applikation auf einem Computer ausgefhrt wird, der nicht von dem
Debugger beeinflut wird. Remote-Testlufe sind beispielsweise fr
Applikationen geeignet, die den gesamten Windows-Bildschirm bentigen und ber die Tastatur gesteuert werden wie Full-Screen-Spiele.

4.3.7

Just-in-Time-Testlufe

Just-in-Time-Debuggen beschreibt die Fhigkeit des Visual-C++-Debuggers, ein Programm zu debuggen, dessen Ausfhrung durch einen
Ausnahmefehler unterbrochen wurde. Just-in-Time-Testlufe sind
berwiegend fr den Debug-Vorgang solcher Applikationen geeignet,
die nicht aus dem integrierten Debugger heraus gestartet wurden.
Just-in-Time-Testlufe werden in dem Dialog OPTIONEN eingeschaltet,
den Sie aus dem Men EXTRAS auswhlen. Selektieren Sie dort das
Register DEBUG, und aktivieren Sie das Kontrollkstchen JUST-IN-TIMEDEBUGGING.

94

Kapitel 4: Browser und Debugger

4.4

Zusammenfassung

Der Quellcode-Browser ist ein sehr wichtiges Entwicklungswerkzeug


von Visual C++, mit dem Sie sich ber
C Definitionen und Referenzen von ausgewhlten Symbolen
C den Inhalt von Quelltextdateien
C Klassenhierarchien
C und Funktionsaufrufe
informieren knnen.
Um den Quellcode-Browser verwenden zu knnen, mssen Ihrem Projekt Browse-Informationen hinzugefgt werden. Sie knnen die dazu
notwendige Option in dem Dialog PROJEKT-EINSTELLUNGEN, Register
C/C++ und BROWSE-INFORMATION, vornehmen.
Das Fenster des Quellcode-Browsers wird ber den Eintrag QUELLCOim Men EXTRAS oder ber verschiedene Kontextmeneintrge aufgerufen.

DE-BROWSER

Der in Visual Studio integrierte Debugger wird ausgefhrt, wenn Sie


eine Applikation ber eine der Debug-Anweisungen im Men ERSTELLEN starten. Der Debugger verfgt ber verschiedene Ansichtsfenster,
ber die Sie den Zustand Ihrer Anwendung berwachen knnen. Dazu
zhlen Quellcode-Fenster sowie die Fenster VARIABLEN, BERWACHUNG, REGISTER, AUFRUFE, SPEICHER und DISASSEMBLIERUNG.
Sie bereiten eine Anwendung auf den Debug-Vorgang vor, indem Sie
sie mit den erforderlichen Flags kompilieren und binden. Dies geschieht fr MFC-Applikationen, die mit dem Anwendungsassistenten
erzeugt wurden, automatisch. Fr solche Applikationen erstellt der Anwendungsassistent eine Debug-Konfiguration und deklariert diese als
Standardkonfiguration.
Whrend des Debuggens einer Anwendung kann deren Ausfhrung
unterbrochen werden. Setzen Sie dazu Haltepunkte, und nutzen Sie
die verschiedenen Debug-Befehle zur schrittweisen Ausfhrung.
C++ kennt viele Debug-Techniken, die Sie zum Testen von MFC- und
anderen Applikationen verwenden knnen. Dazu gehren beispielsweise die TRACE- und ASSERT-Makros sowie die Funktion CObject::Dump.
Mit Objekten vom Typ CMemoryState knnen Sie feststellen, ob es bei
der Ausfhrung Ihrer Anwendung zu Speicherverlusten kommt.

Zusammenfassung

Eine besondere Debug-Technik ist das Remote-Debuggen. RemoteTestlufe ermglichen Ihnen, eine Anwendung auf einem entfernten
Rechner mit Hilfe des Debuggers auf dem lokalen Computer zu debuggen.
Visual C++ ermglicht Just-In-Time-Debuggen. Auf diese Weise knnen Sie Anwendungen testen, die auerhalb der Umgebung des integrierten Debuggers abgestrzt sind.

95

Optimierung

Kapitel
S

ollten Sie auch nach dem Debuggen noch nicht die Lust am Programmieren verloren haben, knnen Sie darangehen, Ihr Programm nach verschiedenen Kriterien zu optimieren. Visual C++ untersttzt Sie dabei mit drei verschiedenen Werkzeugen:
C dem Compiler

C dem Profiler
C dem Analyzer

5.1

Der Compiler

Die einfachste Form der Optimierung ist, die ganze Arbeit dem Compiler zu berlassen.
1. ffnen Sie Ihr Projekt und rufen Sie das Fenster fr die Projekteinstellungen auf (Befehl PROJEKT/EINSTELLUNGEN).
2. Whlen Sie auf der Seite C/C++ eine der Einstellungen im Feld
OPTIMIERUNGEN.
3. Deaktivieren Sie die Debug-Einstellungen, die den Umfang der
Zieldateien unntig vergrern.
Die Assistenten des Visual Studios legen neue Projekte standardmig mit zwei Konfigurationen an: Debug und Release. Die Release-Version ist fr die Endversion des Programms gedacht und
bewirkt, da das Projekt optimiert und ohne Debug-Informationen
compiliert wird.

98

Kapitel 5: Optimierung

5.2

Der Profiler

Aufruf ber Der Visual-C++-Profiler ist ein Hilfsmittel zur Analyse der Laufzeit-PerErstellen/Profil formance. Der Profiler kann zur Erstellung von Funktionsanalysen und

Zeilenanalysen eingesetzt werden. Funktionsanalysen ermitteln, wie


Funktionen in Ihrem Programm ausgefhrt werden. Zeilenanalysen
fhren eine hnliche Untersuchung fr einzelne Zeilen des Quellcodes
durch. Sie mssen Ihren Programmcode mit Debug-Informationen
kompilieren lassen, um eine Zeilenanalyse durchfhren zu knnen. Fr
Funktionsanalysen werden Debug-Informationen ignoriert.
Haben Sie die benutzerdefinierte Installation von Visual C++ ausgefhrt, ist der Profiler mglicherweise nicht auf Ihrem System vorhanden. In diesem Fall knnen Sie nicht auf die Features des Profilers zugreifen. Wiederholen Sie das Installationsprogramm, um
den Profiler einzurichten.

5.2.1

Vorbereiten einer Anwendung fr den Profiler

Um einen Profilerlauf durchfhren zu knnen, mssen Sie


C Im Dialog PROJEKT-EINSTELLUNGEN. (Aufruf PROJEKT/EINSTELLUNGEN) auf der Registerseite LINKER, Kategorie ALLGEMEIN, die Option PROFILER-LAUF ERMGLICHEN setzen. (Kommandozeilenoption/
PROFILE).
Um zuverlssige Ergebnisse zu erhalten, sollten Sie folgende Empfehlungen beherzigen:
Vermeiden Sie Werden innerhalb einer Funktion Eingaben vom Benutzer verlangt, sei
Eingaben durch es durch scanf, cin oder ein Dialogfeld, wird die fr die Eingabe erforden Benutzer derliche Zeit der Funktion hinzuaddiert. Der dadurch zustande kom-

mende Wert kann weit ber dem tatschlich von den Anweisungen bentigten Zeitverbrauch liegen und eine realistische Einschtzung des
Bereichs unmglich machen. Vermeiden Sie daher Eingaben durch
den Benutzer, indem Sie
C Eingabedaten im Programm vorgeben (zum Beispiel mit random),
C Eingabedaten aus einer Datei einlesen,
C Beim Programmablauf Verzweigungen mit Eingaben meiden,
C Anweisungen, in denen Eingaben vom Benutzer verlangt werden,
aus der Erfassung ausgrenzen (PREP-Optionen /EXCALL /INC).

99

Der Profiler

Ausgaben sind ebenfalls immer sehr zeitraubend und knnen die Ana- Vermeiden Sie
Ausgaben
lyse verflschen.
Funktionen, in denen nur wenig Zeit verbracht wird, liefern ungenaue
Werte und sind nur schlecht untereinander zu vergleichen. Stellen Sie
also sicher, da in den interessierenden Funktionen gengend Zeit verbracht wird.
Konfrontieren Sie Ihr Programm nicht mit zu trivialen Aufgaben.
(Wenn Sie beispielsweise Schleifen berechnen lassen, sorgen Sie fr
ausreichend viele Iterationen.)
Lassen Sie das Programm mehrmals hintereinander ablaufen, wobei
Sie ab dem zweiten Lauf den Profiltyp VEREINIGEN whlen, um die Ergebnisse der einzelnen Lufe aufaddieren zu lassen

5.2.2

Der Profiler-Vorgang

Wie arbeitet der Profiler? Der Profiler besteht aus drei untergeordneten
Programmen, die ber die Kommandozeile aufgerufen werden. Die
Programme sind mit PREP, PROFILE und PLIST bezeichnet. Eine
einfache Darstellung der Arbeitsweise dieser Hilfsmittel ist in Abbildung 5.1 dargestellt.
PREP wird whrend des Profiler-Vorgangs zweimal ausgefhrt. Das
Programm liest zunchst die ausfhrbare Datei der Anwendung ein
und erstellt eine PBI- sowie eine PBT-Datei. Die PBI-Datei bildet die
Eingabequelle des Hilfsmittels PROFILE. Dieses Programm startet und
analysiert die Applikation. Die Ergebnisse werden in eine PBO-Datei
geschrieben. Die PBO- und PBT-Dateien dienen der anschlieend ausgefhrten Anwendung PREP als Eingabequelle. PREP erzeugt eine
neue PBT-Datei. Schlielich wird PLIST zur Erstellung der Ergebnisse
verwendet.
Der Profiler wird gewhnlich ber Batch-Dateien gestartet, die PREP,
PROFILE und PLIST in der erforderlichen Reihenfolge aufrufen (beispielsweise LCover.bat und FCover.bat aus dem VisualC++-Unterverzeichnis BIN).
Die Ausgabe von PLIST ist eine schriftliche Zusammenfassung der Ergebnisse der Analyse.

5.2.3

Profiltypen

Der Profiler kann unterschiedliche Analysen durchfhren. Einige dieser


Analysen werden ber den Dialog PROFIL ausgewhlt (Aufruf ber ERSTELLEN/PROFIL), andere erfordern die Verwendung von Batch-Dateien, die sich gewhnlich in dem Verzeichnis \bin befinden.

Sorgen Sie fr
umfangreiches
statistisches
Material

100

Kapitel 5: Optimierung

Abbildung 5.1:
Arbeitsweise
des Profilers

Ausfhrbare Anwendung

PREP
Phase I

PBI-Dateien

PBT-Dateien

PROFILE

PBO-Dateien

PREP
Phase II

PBT-Dateien

PLIST

Abbildung 5.2:
Profiler starten

101

Der Profiler

Profiltyp

Beschreibung

Funktionszeit

Zeigt fr die berwachten Funktionen die Anzahl der


Aufrufe und die verbrauchte Zeit an (einmal mit und einmal ohne die Zeit, die in Unterfunktionen verbracht wurde). (Batch-Datei Ftime.bat)

Funktionen
abdecken

Zeigt an, welche Funktionen berhaupt aufgerufen werden. Sie verwenden diese Option, um beispielsweise zu
prfen, ob bestimmte Abschnitte Ihres Programmcodes
ausgefhrt wurden. (Batch-Datei FCover.bat)

Zeilen abdecken

Zeigt an, welche Zeilen ausgefhrt werden. (Batch-Datei


LCover.bat)

Vereinigen

Addiert zu dem Ergebnis der neuen Analyse das Ergebnis der letzten Analyse (zur statistischen Absicherung;
Voraussetzung ist, da die Analysen von der gleichen
Art sind).

Benutzerdefiniert

Zum Aufruf eigener Batch-Dateien (werden im Feld BEeingegeben). Zur Aufstellung eigener Batch-Dateien laden Sie am besten eine der vorgegebenen Batch-Dateien aus dem VisualC++Verzeichnis \bin, und berarbeiten diese, indem Sie andere Optionen fr die Aufrufe der Profiler-Befehlszeilenprogramme setzen (siehe unten).
NUTZEREINSTELLUNGEN

Nach der Einstellung des Profiltyps starten Sie den Profilerlauf durch
Drcken des OK-Schalters.
Das Ergebnis der Analyse wird nach einiger Zeit im Ausgabefenster auf
einer eigenen Seite angezeigt.
Das Programm PLIST generiert gewhnlich eine Ausgabe, die von
Ihnen im Ausgabefenster gelesen werden kann. Sie knnen jedoch
mit dem Schalter /T bestimmen, da die Ausgabe in einem Datenbankformat generiert werden soll, das von anderen Applikationen
importiert werden kann. Mit Hilfe des Analyse-Makros PROFILER.XLM fr Microsoft Excel, knnen Sie die Profiler-Ausgabe unter Excel bearbeiten.

5.2.4

Erweiterte Profiler-Einstellungen

Die Analyse Ihrer gesamten Applikation ist nicht immer sinnvoll. Gewhnlich ist eine Analyse bestimmter Abschnitte Ihres Programmcodes ausreichend. Auerdem wird die Programmausfhrung whrend
des Profiler-Vorgangs auf diese Weise beschleunigt.

Tabelle 5.1:
Profiltypen

102

Kapitel 5: Optimierung

Ihnen stehen drei Methoden zur Auswahl, um erweiterte Optionen zu


dem Profiler zu bestimmen.
C Sie knnen die Datei PROFILER.INI modifizieren.
C Sie knnen unter Visual Studio in dem Dialog PROFIL weitere Einstellungen vornehmen.
C Sie knnen eigene Batch-Dateien fr die Analyse schreiben.
Die Datei Profiler.ini
Die Datei PROFILER.INI fhrt Einstellungen zu dem Profiler in dem
Abschnitt [profiler] auf. Dort knnen Sie Bibliothek- (LIB) und Objektdateien (OBJ) angeben, die von dem Profiler-Vorgang ausgeschlossen
werden sollen. Ihre Datei profiler.ini knnte die folgenden Zeilen enthalten:
[profiler]
exclude:user32.lib
exclude:gdi32.lib

Die Datei PROFILER.INI befindet sich in dem VisualC++-Verzeichnis


\BIN.
Einstellungen im Dialog Profil
Im Dialog PROFIL haben Sie die Mglichkeit, ber das Feld WEITERE
EINSTELLUNGEN zustzliche Parameter anzugeben, die dem Programm
PREP whrend des ersten Aufrufs bergeben werden.
Einzelnes Modul Mchten Sie beispielsweise lediglich ein einzelnes Modul analysieren
berwachen (beispielsweise das Modul der Datei myapp.cpp), knnen Sie den fol-

genden Eintrag in dem Feld WEITERE EINSTELLUNGEN vornehmen:


/EXCALL /INC MyApp.cpp

Einzelne Zeilen Mchten Sie lediglich einen bestimmten Programmzeilenbereich in der


berwachen Datei myapp.cpp analysieren lassen, knnen Sie schreiben:
/EXCALL /INC MyApp.cpp(30-67)

Eine Aufzhlung der mglichen Argumente finden Sie in der Online-Hilfe unter dem Indexeintrag Prep.
Eigene Batch-Dateien
Schlielich knnen Sie eigene Batch-Dateien zur Analyse entwickeln.
Verwenden Sie die Batch-Dateien, die in dem VisualC++-Verzeichnis
\BIN installiert sind (FCOUNT.BAT, FCOVER.BAT, FTIME.BAT,
LCOUNT.BAT und LCOVER.BAT) als Vorlage fr die Entwicklung
eigener Profiler-Batch-Dateien.

Der Visual Studio Analyzer

5.3

Der Visual Studio Analyzer

Der Visual Studio Analyzer dient speziell zur Optimierung verteilter


Anwendungen. Mit der Hilfe des Analyzers knnen Sie
C den Aufbau einer verteilten Anwendung nachvollziehen
C aufzeigen, was in Ihrer verteilten Anwendung geschieht
C die Laufzeit detailliert aufschlsseln (beispielsweise auch um die
Auswirkung verschieden starker Auslastungen eines Servers zu simulieren)
Der Visual Studio Analyzer wird nur zusammen mit der Enterprise
Edition ausgeliefert.

5.4

Zusammenfassung

Der erste Schritt zur Optimierung einer Anwendung besteht darin, das
Projekt mit passenden Compiler-Einstellungen zur Optimierung neu
erstellen zu lassen (Release-Version).
Der zweite Schritt besteht im Einsatz des Visual-C++-Profilers, der
ber den Befehl ERSTELLEN/PROFIL aufgerufen wird. (Bevor Sie das
Programm im Profiler ausfhren knnen, mssen Sie die Linker-Option PROFILER-LAUF ERMGLICHEN setzen.)
Verwenden Sie den Profiler, um Zeilen- oder Funktionsanalysen durchzufhren. Die Zeilenanalyse ermittelt, welche und wie oft bestimmte
Zeilen aufgerufen wurden. Die Funktionsanalyse wird verwendet, um
Funktionszeiten und Funktionsaufrufe zu ermitteln. Um zuverlssigere
Daten zu erhalten, knnen Sie Profiler-Lufe mit Hilfe des Profiltyps
VEREINIGEN wiederholen und zusammenaddieren lassen.
Zustzliche Profiler-Einstellungen knnen in dem Eingabefeld WEITERE
EINSTELLUNGEN oder in benutzerdefinierten Batch-Dateien vorgenommen werden. Sie knnen die Analyse beispielsweise auf bestimmte
Funktionen oder Quellcode-Zeilen begrenzen.
Mit Hilfe des Visual Studio Analyzers knnen verteilte Anwendungen
analysiert werden.

103

Wiederverwenden von
Programmcode mit der
Komponentensammlung

Kapitel
E

ines der Leitworte der objektorientierten Programmierung lautet


Wiederverwenden von Programmcode. Das Visual-C++-Entwicklungssystem realisiert diese Devise, indem es ein Depot fr wiederverwendbare Code-Komponenten, die sogenannte Komponentensammlung, zur Verfgung stellt.
In der Komponentensammlung sind Elemente enthalten, die auf den
Einsatz in Ihrer Applikation warten. So knnen Sie Ihren Anwendungen beispielsweise Zwischenablage- und Palettenfunktionen, einen Begrungsbildschirm, einen Pawort-Dialog, und viele andere Features
hinzufgen.

6.1

Die Komponentensammlung

Die Visual-C++-Komponentensammlung ist ein Sammelbehlter fr


unterschiedliche Standard- und benutzerdefinierte Komponenten. Was
aber ist eine Komponente? Eine Komponente kann eine Klasse einschlielich der Header-, Implementierungs- und Ressourcen-Dateien
sein. Komponenten knnen ebenfalls von Microsoft oder Drittanbietern zur Verfgung gestellt werden.
Die Komponentensammlung bietet die Mglichkeit, Komponenten zu
speichern und zu verwalten.

106

Kapitel 6: Wiederverwendung von Programmcode

6.1.1

Einfgen einer Komponente in ein Projekt

Die Komponentensammlung wird ber den Befehl KOMPONENTEN UND


STEUERELEMENTE des Eintrags DEM PROJEKT HINZUFGEN im Men
PROJEKT aufgerufen. Sie erscheint in Form des Dialogs SAMMLUNG
DER KOMPONENTEN UND STEUERELEMENTE (siehe Abbildung 6.1).
Die Komponenten, die installiert werden knnen, sind in verschiedenen Ordnern gespeichert. Zwei dieser Ordner werden whrend der Installation von Visual C++ erzeugt: der Ordner DEVELOPER STUDIO
COMPONENTS sowie der Ordner REGISTERED ACTIVEX CONTROLS. Weitere Ordner knnen erstellt werden, um benutzerdefinierte Komponenten aufzunehmen.
Abbildung 6.1:
Die Komponenten- und Steuerelementsammlung

Um bestimmte Komponenten Ihrem Projekt hinzuzufgen,


1. ffnen Sie den Ordner, der die Komponente enthlt,
2. selektieren die Komponente und
3. klicken auf die Schaltflche EINFGEN.
Viele Standardkomponenten zeigen Konfigurationsdialoge an, wenn
Sie diese zum Einfgen auswhlen. Einige Komponenten berprfen
sogar den Quellcode Ihrer Anwendung, um zu ermitteln, ob die selektierte Komponente mit der Anwendung kompatibel ist.

Die Komponentensammlung

6.1.2

Erstellen eigener Komponenten

Whrend Sie mit Visual C++ arbeiten, entwickeln Sie einige Komponenten, die fr die Wiederverwendung geeignet sind. Vielleicht mchten Sie einen Begrungsdialog, eine von CDocItem abgeleitete Klasse
eines Dokument-Objekts oder einen benutzerdefinierten Info-Dialog
mit dem Firmenlogo Ihres Unternehmens erstellen. Jede der soeben
genannten Komponenten ist wiederverwendbar.
Um eine Komponente der Komponentensammlung hinzuzufgen,
1. ffnen Sie die Klassen-Ansicht und klicken mit der rechten Maustaste auf die Klasse, die in eine wiederverwendbare Komponente
konvertiert werden soll.
2. Whlen Sie aus dem anschlieend dargestellten Kontextmen den
Eintrag ZUR KOMPONENTENSAMMLUNG HINZUFGEN aus.
Wenn Sie der Komponentensammlung eine Klasse hinzufgen, wird
eine OGX-Datei erstellt, die in den selektierten Ordner kopiert wird.
Microsoft empfiehlt, benutzerdefinierte Komponenten nicht in den bereits vorhandenen Ordnern DEVELOPER STUDIO COMPONENTS
und REGISTERED ACTIVEX CONTROLS abzulegen.
Die Funktion Zur Komponentensammlung hinzufgen wird optimal ausgefhrt, wenn die Klassen in individuellen Dateien gespeichert werden. Damit ist gemeint, da nicht mehrere Klassen in derselben Quell- oder Header-Datei deklariert oder definiert sind.
Wenn der Komponentensammlung die Klassen eines Projekts ber die
Funktion ZUR KOMPONENTENSAMMLUNG HINZUFGEN hinzugefgt werden, erstellt Visual C++ automatisch einen neuen Ordner, der die Bezeichnung des Quellprojekts trgt. Sie knnen die Ordner manipulieren, Komponenten zwischen den Ordnern verschieben und der
Sammlung neue Ordner hinzufgen oder bestehende Ordner und
Komponenten lschen respektive umbenennen. Dies geschieht in dem
Dialog SAMMLUNG DER KOMPONENTEN UND STEUERELEMENTE.
Mit Hilfe dieses Dialogs knnen Sie auerdem Komponenteneigenschaften ermitteln und setzen. Ein Klick mit der rechten Maustaste auf
eine benutzerdefinierten Komponente ffnet deren Kontextmen.
Whlen Sie dort den Eintrag EIGENSCHAFTEN aus, um den EIGENSCHAFTEN-Dialog dieser Komponente zu ffnen

107

108

Kapitel 6: Wiederverwendung von Programmcode

6.2

Zusammenfassung

Die Komponentensammlung ist ein Depot fr Standard- und benutzerdefinierte Komponenten sowie ActiveX-Steuerelemente.
Um Ihrer Applikation eine Komponente oder ein Steuerelement hinzuzufgen, whlen Sie das gewnschte Objekt in dem Dialog SAMMLUNG
DER KOMPONENTEN UND STEUERELEMENTE aus und klicken auf die
Schaltflche EINFGEN.
Sie knnen Ihre eigenen Klassen der Sammlung als Komponenten hinzufgen. Klicken Sie dazu in der Klassen-Ansicht mit der rechten
Maustaste auf die gewnschte Klasse, und whlen Sie aus dem anschlieend dargestellten Kontextmen den Eintrag ZUR KOMPONENTENSAMMLUNG HINZUFGEN aus.
Die Konfiguration der Komponentensammlung ermglicht Ihnen,
neue Ordner zu erzeugen und Komponenten darin zu speichern. Benutzerdefinierte Komponenten werden in OGX-Dateien gespeichert.
Da diese dem Verbunddokumentformat entsprechen, knnen Sie deren Eigenschaften einsehen und verndern.
Das Visual-C++-Entwicklungssystem stellt Ihnen einige Standardkomponenten zur Verfgung. So knnen Sie Ihren Anwendungen beispielsweise Zwischenablagefunktionen, eine Dialogfeldleiste, Paletten,
Pop-up-Mens, einen Begrungsbildschirm und einen Tips-undTricks-Dialog sowie viele andere Features hinzufgen.

WindowsGrundlagen
und API

Teil II
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.

Betriebssystembersicht
Das API-Anwendungsgerst
Fenster, Dialogfelder und Steuerelemente
Ressourcen
Zeichnen und Gertekontexte
Threads und Prozesse
DLLs Dynamische Bibliotheken
Speicherverwaltung
Dateiverwaltung
Die Windows-Zwischenablage
17. Die Registrierung
18. Ausnahmebehandlung

Betriebssystembersicht

Kapitel
D

ie 32-Bit-Edition von Visual C++ kann zur Entwicklung von Programmen fr zwei Win32-Plattformen verwendet werden:
Windows NT (auch mit mehreren Prozessoren) und Windows 95/98.
Die 32-Bit-Erweiterung fr Windows 3.1, Win32s, wird nicht mehr untersttzt. Microsoft hat diese Option bereits aus Visual C++ Version
4.2 entfernt.
Windows NT ist Microsofts High-End-Server-Betriebssystem. Es ist ein
echtes 32-Bit-Multitasking-Betriebssystem mit einer integrierten Grafikumgebung und erweiterter Server-Funktionalitt. Die Entwicklung
von Windows NT war auf maximale Portierbarkeit, Stabilitt und Sicherheit ausgerichtet. Das Betriebssystem ist vollstndig kompatibel zu
stabiler MS-DOS- und Windows-3.1-Software. Es bildet jedoch kein
Substitut fr Ihr altes MS-DOS-System. Mchten Sie beispielsweise ein
komplexes Spiel starten, mssen Sie Ihren Rechner mglicherweise erneut unter DOS booten.
Windows 95/98 ist das Betriebssystem, das beide Welten in sich vereint. Im Gegensatz zu Windows NT bildet die Abwrtskompatibilitt
von Windows 95/98 eines der wesentlichen Kriterien. Trotz dieses
Umstands und der Tatsache, da fr Windows 95/98 sehr viel Programmcode aus Windows 3.1 bernommen wurde, weist das neue Betriebssystem nur wenige Unzulnglichkeiten auf.
Obwohl bedeutende Unterschiede zwischen diesen Plattformen bestehen, verwenden sie die gleichen wesentlichen Features. Die berwiegende Anzahl einfacher Anwendungen ist sowohl zu Windows NT als
auch zu Windows 95/98 kompatibel. Compiler- oder BetriebssystemFeatures werden daher in diesem Buch unabhngig von dem verwendeten Betriebssystem beschrieben. Bedeutende Plattformunterschiede
werden natrlich erwhnt.

112

Kapitel 7: Betriebssystembersicht

7.1

Fenster und Nachrichten

Windows wird hufig als ein nachrichtengesteuertes Betriebssystem


bezeichnet. Nachrichten dienen der Kommunikation zwischen dem
Betriebssystem und den laufenden Anwendungen, aber auch der Kommunikation zwischen den Anwendungen.
Von DOS zu Unter DOS kann im Prinzip immer nur ein Programm gleichzeitig ausWindows gefhrt werden. Dieses Programm verfgt dann uneingeschrnkt ber

alle Ressourcen des Systems.


Unter Windows laufen meist mehrere Anwendungen gleichzeitig. Aufgabe des Windows-Betriebssystems ist es daher, dafr zu sorgen, da
die Ressourcen ordnungsgem verteilt werden. Dies betrifft nicht nur
Ressourcen wie Speicher und Handles, sondern auch die Aus- und Eingabegerte.

7.1.1

Ereignisbehandlung ber die Nachrichtenwarteschlange

Abbildung 7.1:
Ereignisbehandlung
Mausbewegung

Windows

Anwendung

Eintrag in
System-Queue

Anwendung wird in
CPU geladen

WM_MOUSEMOVE
fordert Botschaft
Eintrag in
Application-Queue

Message Loop
fordert Meldung an

WM_MOUSEMOVE
Message Loop
verarbeitet Meldung

WM_MOUSEMOVE
Windows wird
angewiesen,
Fensterfunktion
aufzurufen

Aufruf
Fensterfunktion
(reagiert Aufschlag
Mausbewegung)

113

Fenster und Nachrichten

Betrachten wir zum Beispiel den einfachen Fall, da der Anwender mit
der Maus in das Hauptfenster einer Anwendung klickt. Windows fngt
dieses Ereignis auf, bersetzt es in eine Nachricht.
Eine solche Nachricht besteht aus mehreren Teilen, unter anderem:

Nachrichten

C einem Fenster-Handle, der das Fenster identifiziert, an das die


Nachricht gerichtet ist
C einem Nachrichtencode (beispielsweise WM_LBUTTONDOWN fr das Niederdrcken der linken Maustaste.)
C und zwei 32-Bit-Parameter (wParam und lParam) fr zustzliche Informationen (beispielsweise den Koordinaten des Mausklicks).
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;

// Datentyp fr Windows-Nachrichten

Diese Nachricht schickt Windows an die Nachrichtenwarteschlange


der Anwendung (Application-Queue). Jede Anwendung (genauer gesagt, sogar jeder Thread) bekommt von Windows eine solche Nachrichtenwarteschlange zugeteilt.
Die Anwendung mu folglich eine Schleife implementieren, die stndig Die Message
die Nachrichtenwarteschlange nach eingetroffenen Nachrichten ab- Loop
fragt. Dies ist die sogenannte Message Loop:
// MessageLoop
while (GetMessage (&Message, NULL, 0, 0) )
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}

Sie ist allerdings nicht die Endstation der Botschaftsverarbeitung, sondern lediglich eine Zwischenstation. Ihr Vorteil ist die chronologische
Bearbeitung der einkommenden Botschaften (First In, First Out). Dies
ist insbesondere fr die Bearbeitung von Benutzereingaben wichtig
(wenn der Anwender beim Aufsetzen eines Textes in einen bestimmten Absatz klickt und dort ein neues Wort einfgt, mchte er auch,
da zuerst der Mausklick und dann die Tastatureingaben bearbeitet
werden und nicht umgekehrt). Botschaften, die die Anwendung ber
vom Anwender ausgelste Ereignisse informieren, laufen daher stets
ber die MessageLoop.

114

Kapitel 7: Betriebssystembersicht

Zudem beschleunigt die Einschaltung einer Warteschlange die Ausfhrung von Windows, das auf diese Weise am schnellsten auf Ereignisse reagieren und die weitere Verarbeitung an die Anwendungen verteilen kann.
In der Message Loop werden die Nachrichten eingelesen und an die
Fenster der Anwendung verteilt. (Ziel einer Nachricht ist ja ein Fenster).
Wie werden die Nachrichten an die Fenster geschickt? Um Nachrichten empfangen zu knnen, definiert jedes Fenster eine Fensterfunktion. Nach der Verarbeitung in der Message Loop wird die Nachricht
wieder an Windows bergeben, das die entsprechende Fensterfunktion
aufruft und dieser die Nachricht, in verschiedene Parameter aufgeschlsselt, bergibt.
Die Fenster- Die Fensterfunktion empfngt die Nachricht und sorgt fr eine adquafunktion te Verarbeitung. Zu diesem Zwecke definiert jede Fensterfunktion eine
mehr oder weniger umfangreiche switch-Anweisung. In dieser switch-

Anweisung wird festgestellt, welche Botschaft empfangen wurde, und


eine entsprechende Funktion zur Beantwortung der Botschaft aufgerufen.
// Fensterfunktion WndProc
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage,
WPARAM wParam, LPARAM lParam)
{
// beantworte Botschaften mit entsprechenden Aktionen
switch(uiMessage)
{
case WM_DESTROY: PostQuitMessage(0);
return(0);
default: return(DefWindowProc(hWnd,uiMessage,
wParam,lParam));
}
}

Nachrichtenbertragung ohne MessageLoop


Eine Vielzahl von Nachrichten haben nur indirekt etwas mit Benutzeraktionen zu tun und werden intern von Windows verschickt (beispielsweise, wenn Windows ein Fenster darber informiert, da es gerade
verschoben, neu dimensioniert oder geschlossen wird). In diesen Fllen
umgeht Windows meist die Nachrichtenwarteschleifen der einzelnen
Anwendungen und schickt die Nachricht statt dessen direkt an die Fensterfunktion des betroffenen Fensters.

Fenster und Nachrichten

Nachrichten selbst abschicken


Anwendungen knnen nicht nur Botschaften empfangen, sie knnen
auch selbst Botschaften verschicken an sich selbst oder an andere
Anwendungen. Auf diese Weise kann eine Anwendung beispielsweise:
C eines ihrer Fenster durch Neuzeichnen aktualisieren lassen,
C die Funktionsweise von Windows-Steuerelementen verndern,
C mit anderen Anwendungen Informationen austauschen.
Um eine Botschaft abzuschicken, stehen einer Anwendung ebenso wie
Windows zwei Mglichkeiten offen: entweder ber die MessageLoop
oder direkt an eine Fensterfunktion.
1. Zum Abschicken von Botschaften ber die MessageLoop verwendet man die Funktionen der PostMessage-Familie. Diese Funktionen
tragen die zu verschickende Botschaft in die gewnschte Message
Queue und kehren dann direkt zurck (im Erfolgsfall mit einem
Wert ungleich NULL). Nach Rckkehr der PostMessage-Funktion
kann man also nicht davon ausgehen, da die Botschaft in der
empfangenden Anwendung bereits bearbeitet wurde!
BOOL PostMessage( HWND hWnd, UINT message,
WPARAM wParam = 0, LPARAM lParam = 0 );

2. Botschaft direkt verschicken. Um Botschaften direkt an bestimmte


Fenster zu schicken, verwendet man die Funktionen der SendMessage-Familie. Diese Funktionen senden die zu bermittelnde Botschaft direkt an die Fensterfunktion eines Fensters. Im Gegensatz
zu den Funktionen der PostMessage-Familie kehrt SendMessage
allerdings danach nicht zurck, sondern wartet darauf, da die
Fensterfunktion die Botschaft verarbeitet hat. Die SendMessageFunktionen sind daher vor allem fr die schnelle und synchronisierte Verarbeitung von Botschaften bestens geeignet!
LRESULT SendMessage( HWND hWnd, UINT message,
WPARAM wParam = 0, LPARAM lParam = 0);

7.1.2

Fenster und Fensterklassen

Was sich dem Anwender als Fenster mit Rahmen, Titel, verschiedenen
Dekorationen und einem Arbeitsbereich darstellt, das er mit der Maus
aktivieren und verschieben kann, ist fr den Programmierer nur ein
spezieller Typ eines Fensters.
Aus Sicht des Programmierers ist ein Fenster ein Teil der grafischen
Schnittstelle seiner Applikation zum Anwender, die sich dadurch auszeichnet, da sie Nachrichten verarbeiten kann. Ein Fenster verfgt daher ber einen Handle, der von Windows zur eindeutigen Identifizie-

115

116

Kapitel 7: Betriebssystembersicht

rung des Fensters vergeben wird, und eine Fensterfunktion, in der die
an das Fenster gerichteten Nachrichten verarbeitet werden.
Hauptfenster, Clientfenster, Dialogfelder, Steuerelemente wie Schalter, Editierfelder, etc. sind aus Windows-Sicht Fenster.
Wie wird ein Fenster mit einer Fensterfunktion verbunden?
Aus Sicht von Windows ist ein Fenster ein Objekt. Windows ist allerdings nicht objektorientiert implementiert. Wre dies der Fall, wrde
man annehmen, da ein Fenster eine Instanz einer Fensterklasse ist. In
dieser Fensterklasse wre dann die Fensterfunktion als Elementfunktion definiert.
Nun, Windows ist zwar nicht objektorientiert implementiert, aber das
verwendete Prinzip ist ganz hnlich.
Fensterklassen Jedes Fenster wird auf der Grundlage einer Fensterklasse erzeugt. Allerdings ist diese Klasse in Wirklichkeit eine Struktur (WNDCLASSEX). In

dieser Fensterklasse werden Informationen ber Erscheinungsbild und


Verhalten fr die Fenster festgelegt, die spter auf der Grundlage dieser Fensterklasse erzeugt werden. Unter anderem gehrt hierzu auch
ein Zeiger auf die Fensterfunktion.
Mehrere Fenster knnen auf der Grundlage ein und derselben Fensterklasse erzeugt werden. Beispielsweise gehen alle Schalter-Steuerelemente auf eine gemeinsame Fensterklasse zurck. Voraussetzung ist
allerdings, da die Fensterklasse zuvor unter Windows registriert wurde. Im Falle einiger Standard-Fensterklassen (wie zum Beispiel auch
der Fensterklasse fr die Schalter-Steuerelemente) braucht sich der
Programmierer darum allerdings nicht zu kmmern, da diese Fensterklassen bereits als fester Teil des Betriebssystems registriert sind.
Windows bietet sehr viele Standard-Fensterklassen an. Diese globalen
Systemklassen implementieren die Funktionalitt einiger allgemeiner
Steuerelemente. Jede Anwendung kann diese Klassen fr die eigenen
Fenster verwenden. So ist es beispielsweise mglich, da eine Anwendung Eingabefelder implementiert, indem sie die Fensterklasse Edit verwendet.
Eigene Fenster- Anwendungen knnen auerdem ihre eigenen Fensterklassen ber
klassen die Funktion RegisterClassEx definieren. Diese Funktion ermglicht
registrieren dem Programmierer, ein Fensterverhalten zu implementieren, das die

vom Betriebssystem untersttzten globalen Klassen nicht bieten. Eine


Anwendung kann beispielsweise die Funktionalitt des eigenen Hauptfensters implementieren und das Symbol und Men des Hauptfensters
registrieren lassen.

117

Fenster und Nachrichten

Windows ermglicht auch das Erstellen von Subklassen und Superklassen aus bestehenden Klassen.
C Eine Subklasse ist eine Klasse, deren Fensterprozedur durch die einer anderen Klasse ersetzt wurde.
C Superklassen sind neue Klassen, die auf einer bestehenden Klasse
basieren und deren Fensterprozedur bernehmen. Um aus einer
Fensterklasse eine Superklasse erstellen zu knnen, ermittelt die
Anwendung einige Klasseninformationen mit Hilfe der Funktion
GetClassInfo. Anschlieend wird die ermittelte WNDCLASS-Struktur
modifiziert und in dem Aufruf von RegisterClass verwendet. Die
Anwendung ermittelt ber GetClassInfo ebenfalls die Adresse der
originalen Fensterprozedur. Nachrichten, die die neue Fensterprozedur nicht bearbeitet, werden an diese Funktion weitergeleitet
(siehe Beispielprogramm aus Kapitel 1).

7.1.3

Nachrichtentypen

Windows kennt derzeit an die 400 verschiedene Nachrichten. Glcklicherweise mu der Programmierer nicht selbst fr die korrekte Bearbeitung all dieser Nachrichten sorgen. Worauf es letztendlich ankommt, ist die fr ein Programm wirklich interessanten Nachrichten
abzufangen und mit dem Aufruf passender Antwortfunktionen zu verbinden. Alle anderen Nachrichten knnen einer Standardverarbeitung
zugefhrt werden (durch Aufruf der API-Funktion DefWindowProc).
Nachrichtentyp

Beschreibung

Windows-Nachrichten Das Gros der Nachrichten. Hierzu gehrt die Gruppe


der WindowsManager-Nachrichten die alle mit WM_
beginnen (mit der Ausnahme von WM_COMMAND). Die
Gruppe ist in weitere Kategorien unterteilt. Diese Kategorien enthalten DDE- (Dynamic Data Exchange),
Zwischenablage-, Maus-, Tastatur-, Nicht-Client-Bereich- (Nachrichten, die sich auf die Titelzeile, den
Rand und den Menbereich eines Fensters beziehen.
Diese werden von dem Betriebssystem verwaltet und
nicht von der Anwendung.), MDI- (MultipleDocument
Interface) und viele weitere Nachrichtentypen. Die
Definition der Kategorien erfolgt nach keiner streng
vorgegebenen Norm. Sie soll dem Programmierer lediglich helfen, eine bersicht ber die groe Anzahl
verschiedener Manager-Nachrichten zu erhalten. Die
WM_-Nachrichten sind nicht begrenzt. Werden dem
Betriebssystem neue Features hinzugefgt, kann
auch die Anzahl der Nachrichten steigen.

Tabelle 7.1:
Nachrichtentypen

118

Kapitel 7: Betriebssystembersicht

Nachrichtentyp

Beschreibung
Andere Nachrichtengruppen beziehen sich auf spezifische Fenstertypen wie Textfeld-Steuerelemente,
Schaltflchen, Listenfelder, Kombinationsfelder, Bildlaufleisten, Listenansichten und andere Elemente.

Benachrichtigungen

Dies sind Nachrichten, die von Steuerelementen oder


Kindfenstern an ihre Elternfenster geschickt werden.

CommandNachrichten

WM_COMMAND-Nachrichten, die von Elementen der Benutzeroberflche (Menbefehl, Schalter der Symbolleiste, Tastaturkrzel) ausgelst werden.
(In MFC-Anwendungen werden diese Botschaften blicherweise nicht von Fensterobjekten, sondern von
Dokumenten, Dokumentvorlagen oder dem Anwendungsobjekt abgefangen.)

Eigene Nachrichten
Anwendungen knnen auch eigene Nachrichten definieren. Dies geschieht unter Zuhilfenahme der Funktion RegisterWindowMessage.
Das Verwenden eigener Nachrichtentypen ermglicht bestimmten Bereichen einer Anwendung miteinander zu kommunizieren. Separate
Anwendungen knnen ebenfalls auf diese Weise Informationen austauschen.
Den Nachrichten auf der Spur
Abbildung 7.2:
Spy++

119

Fenster und Nachrichten

Wer sich einmal darber informieren mchte, welche Nachrichten so


bei einer seiner Anwendungen oder speziell einem Fenster eingehen,
der kann dazu das mit Visual C++ ausgelieferte Diagnose-Tool Spy++
verwenden.
Verwenden Sie SPY++ beispielsweise, um den Info-Dialog von Word Spy++
fr Windows zu berwachen.
1. Rufen Sie Spy++ auf (Befehl EXTRAS/SPY++).
2. ffnen Sie den Info-Dialog von Word und arrangieren Sie Word
und Spy++ nebeneinander auf Ihrem Desktop.
3. Richten Sie Spy++ fr die berwachung des Info-Dialogs ein.
Rufen Sie den Befehl SPY/FENSTER SUCHEN auf.
Nehmen Sie mit der Maus das Zielscheibensymbol auf und klikken Sie mit diesem Symbol in das zu berwachende Fenster.
Setzen Sie danach im Dialogfeld FENSTER SUCHEN die Option
NACHRICHTEN, und klicken Sie auf OK.
4. Bewegen Sie die Maus ber die Schaltflche OK und bettigen Sie
diese.
Im Spy++-Fenster werden die darauf folgenden Nachrichtenstrme angezeigt (siehe Tabelle 7.1).
5. Beenden Sie die Nachrichtenberwachung (Befehl NACHRICHTEN/
PROTOKOLLIERUNG BEENDEN).
Symbolbezeichner

Beschreibung

WM_LBUTTONDOWN

Die linke Maustaste wurde gedrckt.

WM_PAINT

Die Schaltflche OK wird whrend ihrer Bettigung erneut gezeichnet.

WM_LBUTTONUP

Die linke Maustaste wurde losgelassen.

WM_PAINT

Die Schaltflche OK wird erneut gezeichnet, nachdem Sie losgelassen wurde.

WM_WINDOWPOSCHANGING

Die Position des Fensters wird gendert.

WM_WINDOWPOSCHANGED

Die Position des Fensters wurde gendert.

WM_NCACTIVATE

Die Titelzeile des Fensters wurde aktiviert.

WM_ACTIVATE

Der Client-Bereich des Fensters wurde aktiviert.

WM_WINDOWPOSCHANGING

Die Position des Fensters wird gendert.

WM_KILLFOCUS

Das Fenster verliert den Fokus.

Tabelle 7.2:
Nachrichten, die
nach einem Klick
auf OK an den
Info-Dialog von
Word fr Windows gesendet
werden

120

Kapitel 7: Betriebssystembersicht

Symbolbezeichner

Beschreibung

WM_DESTROY

Das Fenster wird zerstrt.

WM_NCDESTROY

Die Titelzeile des Fensters wird zerstrt.

7.2

Nachrichten und Multitasking

In Windows 3.1 hatte die Nachrichtenschleife eine fr die Interaktion


der Anwendung mit dem Betriebssystem wichtige Aufgabe: Sie ermglichte der Anwendung die Abgabe der Steuerung des Prozessors. Da
Windows 3.1 kein premptives Multitasking-Betriebssystem ist, besitzt
es keine Mglichkeit, einer nicht kooperierenden Anwendung die
Steuerung des Prozessors abzunehmen. Ein stabiles System ist unter
Windows 3.1 daher von dem kooperativen Verhalten einer Anwendung abhngig.
Windows-95/98- und Windows-NT sind dagegen nicht auf die Kooperation der Anwendungen angewiesen beide Betriebssysteme sind in
der Lage, laufenden Anwendungen jederzeit die Kontrolle ber die
CPU zu entziehen.
Systemabstrze unter Windows 95/98
Diese Besonderheit der 32-Bit-Betriebssysteme ist unter anderem
die Grundlage dafr, da ein abstrzender Proze nicht das gesamte Betriebssystem mitzieht. Unter Win95/98 knnen abstrzende
Prozesse aber auch weiterhin das System lahmlegen. Dies liegt daran, da Windows 95/98 groe Teile alten Win16-Codes verwendet,
der immer nur von einer Anwendung gleichzeitig ausgefhrt werden kann (i.G: zu 32-Bit-Code, der reentrant ist). Strzt eine Anwendung whrend der Ausfhrung von 16-Bit-Betriebssystemcode
ab, gibt sie diesen nicht mehr frei, und der Code kann nicht mehr
von anderen Anwendungen ausgefhrt werden.

7.2.1

Multithreading und Multitasking

Multithreading
Unter Win16 bezeichnete man in Ausfhrung befindlichen Code als
Task. Da man unter Windows 3.x ein Programm mehrfach aufrufen
kann, sind die Bezeichnungen Programm und Task nicht identisch.
Statt dessen spricht man von Instanzen eines Programms und jeder
solchen Instanz wrde dann eine Task entsprechen.

Nachrichten und Multitasking

In Win32 spricht man dagegen von Prozessen und Threads. Jede Instanz eines Programms entspricht nun einem Proze, und jeder Proze
verfgt automatisch ber einen Thread, der den eigentlichen auszufhrenden Handlungsfaden bezeichnet. Unter Win32 werden Botschaften
an Threads gesendet, und Threads sind es, die sich die Kontrolle ber
die CPU teilen.
Bis dahin gibt es noch keinen wesentlichen Unterschied zwischen
Threads und Tasks, aber Threads haben den Vorzug, da sie selbst
neue Threads erzeugen knnen (wobei erzeugter und erzeugender
Thread dem gleichen Proze angehren). Da alle erzeugten Threads
am Multitasking (siehe unten) teilnehmen, hat eine Anwendung damit
die Mglichkeit, zeitaufwendige Routinen (beispielsweise das Ausdrukken eines Textes) als Thread abzuspalten, so da die Anwendung, genauer gesagt ihr Hauptthread, whrend des Druckens weiter ausgefhrt werden kann.
Multitasking und Nachrichtenwarteschlangen
Lassen Sie mich zunchst das Nachrichtensystem und die Task-Architektur der 16-Bit-Version von Windows beschreiben. Diese verwendet
lediglich eine Nachrichtenwarteschlange. Die von verschiedenen Betriebssystemereignissen generierten Nachrichten wie z.B. Tastaturoder Maus-Interrupts werden von Windows in diese Warteschlange
gestellt. Windows gibt der zugehrigen Anwendung die Kontrolle ber
die CPU, damit diese die Nachricht mit Hilfe der Funktionen GetMessage oder PeekMessage auslesen kann.
Kann eine Anwendung die Nachricht nicht auslesen, blockiert die Anwendung das ganze System. Nachrichten werden jedoch weiterhin in
der Warteschlange abgelegt. Da die Warteschlange lediglich eine begrenzte Kapazitt besitzt, entsteht nach einem Absturz mglicherweise
ein berlauf. Immer dann, wenn eine Nachricht nicht in der Warteschlange abgelegt werden kann, erzeugt Windows einen Fehlerton.
Das Ergebnis ist ein abgestrztes System, das bei der geringsten Mausbewegung unangenehme Signaltne erzeugt.
Unter Win32-Systemen (Windows 95/98 und Windows NT) weist das
Betriebssystem die CPU nacheinander den laufenden Threads zu. Da
das Betriebssystem den Threads auch die Kontrolle ber die CPU entziehen und weiterreichen kann, knnte es im Falle einer Nachrichtenschleife schnell geschehen, da einer oder mehrere Threads versuchen, gleichzeitig auf die Nachrichtenwarteschlange zuzugreifen. Da
ein Umschalten zwischen Threads nicht wie bisher von der nchsten
erhltlichen Nachricht in der Warteschlange abhngig ist, besteht kei-

121

122

Kapitel 7: Betriebssystembersicht

ne Garantie dafr, da ein Thread lediglich die Nachrichten erhlt, die


an ihn adressiert sind. Aus diesem Grund wurde die Warteschlange der
16-Bit-Version von Windows in einzelne Nachrichtenwarteschlangen
fr jeden Thread unterteilt.

7.2.2

Threads und Nachrichten

Unter Win32 werden Fenster und Nachrichtenschleifen nicht mehr


kompletten Anwendungen, sondern den einzelnen Threads zugeordnet.
Worker-Threads Bedeutet dies, da ein Thread ein Fenster besitzen und eine Nachrich-

tenschleife enthalten mu? Glcklicherweise nicht. Andernfalls wrde


der Einsatz von Threads in gewhnlichen Programmen sehr hinderlich
sein. Natrlich knnen Threads erzeugt werden, die kein Fenster besitzen und ber keine Nachrichtenschleife verfgen.
Stellen Sie sich beispielsweise eine hochentwickelte mathematische
Anwendung vor, in der eine komplexe Berechnung fr jedes Element
eines zweidimensionalen Arrays (einer Matrix) durchgefhrt werden
mu. Die einfachste Mglichkeit, diese Absicht zu realisieren, besteht
darin, eine Schleife zu implementieren, in der die Berechnung wiederholt durchgefhrt wird. Unter der 16-Bit-Version von Windows war
diese Vorgehensweise nicht zulssig. Whrend der Ausfhrung der
Schleife htte keine andere Anwendung auf den Prozessor zugreifen
knnen, so da der Rechner in dieser Zeit blockiert gewesen wre. In
Win32-Systemen ist es mglich, einen separaten Thread einzurichten,
in dem die Berechnung durchgefhrt wird, whrend der Haupt-Thread
der Anwendung weiterhin die erhaltenen Nachrichten bearbeitet. Der
einzige daraus resultierende Nachteil ist ein Performance-Verlust
nichts Unerwartetes whrend einer komplexen, rechenintensiven Berechnung. Der Thread, der die Berechnung vornimmt, verfgt ber
keine Fenster, Nachrichtenwarteschlangen oder Nachrichtenschleifen.
Er fhrt lediglich eine Aufgabe aus: die Berechnung.
MFC hat einen Namen fr diese Threads. Sie werden als WorkerThreads bezeichnet, im Gegensatz zu den weiterentwickelten User-Interface-Threads, die der Bearbeitung von Nachrichtenwarteschlangen
dienen.

Windows-Funktionsaufrufe

7.3

123

Windows-Funktionsaufrufe

Obwohl die Nachrichtenschleife eine der wesentlichen Eigenschaften


einer Windows-Anwendung reprsentiert, ist sie nicht der einzige Mechanismus, ber den eine Anwendung mit Windows interagiert. Windows offeriert eine Vielzahl verschiedener Systemaufrufe zur Ausfhrung unterschiedlicher Aufgaben. Dazu zhlen beispielsweise
Prozesteuerung, Fenster-Management, Dateiverwaltung, Speicherverwaltung, Grafikdienste und Kommunikation.
Die wesentlichen Windows-Funktionsaufrufe knnen in drei Kategorien unterteilt werden.
C Kernel-Dienste enthalten Systemaufrufe zur Kontrolle von Prozessen und Threads, zum Ressource-Management sowie zur Dateiund Speicherverwaltung.
C User-Dienste umfassen Systemaufrufe zur Verwaltung der Benutzerschnittstellenelemente, wie z.B. Fenster, Steuerelemente, Dialoge oder Nachrichten.
C GDI-Dienste (Graphics Device Interface) stellen eine gerteunabhngige Grafikausgabefunktionalitt zur Verfgung.
Die Funktionen dieser Dienste sind in den Bibliotheken des Betriebssystems implementiert und knnen ber die Funktionen der WindowsAPI (Application Programming Interface) aufgerufen werden.
Darber hinaus gibt es eine Reihe weiterer APIs fr unterschiedliche
Aufgaben. Beispiele hierfr sind MAPI (Messaging API), TAPI (Telephony API) oder ODBC (Open Database Connectivity). Der Umfang,
in dem diese APIs in das System integriert wurden, variiert. Das Komponentenobjektmodell (COM, die Grundlage fr ActiveX und OLE) ist
beispielsweise ein Teil der Windows-Funktionalitt, obwohl es in Form
mehrerer System-DLLs implementiert wurde. Andere APIs, wie z.B.
Winsock, bilden sogenannte Add-Ons.

7.3.1

Kernel-Dienste

Kernel-Dienste lassen sich der Kategorie Dateiverwaltung, Speicherverwaltung, Proze- und Thread-Kontrolle sowie Ressourcenverwaltung zuordnen. Trotz ihrer geringen Anzahl beschreiben diese Kategorien die berwiegend verwendeten Kernel-Modulfunktionen.
Die bevorzugte Methode der Dateiverwaltung unterscheidet sich von Dateiverwaltung
der, die gewhnlich in C/C++-Programmen eingesetzt wird. Anstatt
ber die C++-Klasse iostream respektive ber die Standard-C-Biblio-

124

Kapitel 7: Betriebssystembersicht

thekfunktionen fr die Stream- oder Low-Level-Ein- und Ausgabe auf


Dateien zuzugreifen, sollten Anwendungen das Win32-Dateiobjektkonzept und die entsprechenden Funktionen bernehmen. Dateiobjekte
ermglichen den Zugriff auf Dateien, ohne die C/C++-Bibliothek zu
nutzen. Beispiele hierfr sind berlappte Ein-/Ausgabe- und SpeicherMap-Dateien, die fr die Intertask-Kommunikation bentigt werden.
Speicher- Fr die Speicherverwaltung der meisten Anwendungen sind die C-malverwaltung loc-Funktion oder der C++-new-Operator vollkommen ausreichend. In

einer Win32-Anwendung werden diese Aufrufe automatisch in die entsprechenden Win32-Systemaufrufe zur Speicherverwaltung umgewandelt. Fr Anwendungen mit umfangreichen Anforderungen an die
Speicherverwaltung bestehen hochentwickelte Funktionen zur Verwaltung des virtuellen Speichers. Diese Funktionen knnen beispielsweise
verwendet werden, um Adreraum zu manipulieren, fr den mehrere
hundert Megabyte Speicher reserviert wurden.
Threadsynchro- Eine der wichtigsten Aspekte des Proze- und Thread-Managements
nisierung betrifft die Synchronisierung. Dieses Problem ist neu in der Windows-

Umgebung, da die 16-Bit-Version des Betriebssystem noch nicht damit


konfrontiert wurde. Unter der kooperativen Multitasking-Umgebung
von Windows 3.1, geben die Anwendungen die Steuerung des Prozessors lediglich zu vordefinierten Zeitpunkten whrend der Programmausfhrung ab. Die Ausfhrung mehrerer Threads geschieht synchron.
Im Gegensatz dazu erhalten Prozesse und Threads in der premptiven
Multitasking-Umgebung keine Informationen ber den Status der Ausfhrung anderer Threads. Um zu gewhrleisten, da mehrere Threads
in einer korrekten Reihenfolge ausgefhrt werden, und um Situationen
zu vermeiden, in denen zwei oder mehrere Threads lange Zeit auf andere Threads warten mssen, wird ein Synchronisationsmechanismus
verwendet. In der Win32-Umgebung bilden verschiedene Synchronisationsobjekte diesen Mechanismus, der von den Threads genutzt werden kann, um andere Threads ber ihren Status zu informieren, sensible Programmcode-Bereiche vor einer erneuten Ausfhrung zu
schtzen oder Informationen ber andere Threads respektive den Status anderer Objekte zu ermitteln.
Kernel-Objekte Unter Win32 werden viele Kernel-Ressourcen (die nicht mit Anwen-

derschnittstellen-Ressourcen verwechselt werden sollten) durch KernelObjekte reprsentiert. Beispiele hierfr sind Dateien, Threads, Prozesse und Synchronisierungsobjekte. Gewhnlich verweisen Zugriffsnummern auf diese Objekte. Einige Funktionen dienen der Manipulation aller Objekte, whrend andere Funktionen lediglich Objekte eines bestimmten Typs bearbeiten. Unter Windows NT besitzen Objekte Eigenschaften, die sich auf die Sicherheit beziehen. Ein Thread kann

Windows-Funktionsaufrufe

125

beispielsweise ein Dateiobjekt so lange nicht bearbeiten, bis er die entsprechende Genehmigung dazu erhlt, die sich auf die Sicherheitseigenschaften des Dateiobjekts beziehen.
Das Kernel-Modul stellt auerdem Funktionen zur Verfgung, die der Ressourcen
Verwaltung von Anwenderschnittstellen-Ressourcen dienen. Diese
Ressourcen nehmen Symbole, Mauszeiger, Dialogvorlagen, Zeichenfolgentabellen, Versionsinformationen, Tastaturkrzeltabellen, Bitmaps und benutzerdefinierte Ressourcen auf. Kernel-Systemaufrufe reservieren Speicher fr Ressourcen, laden Ressourcen aus einer Datei
(gewhnlich die ausfhrbare Datei der Anwendung) und entfernen Ressourcen aus dem Speicher.
Auch die Funktionalitt fr 32-Bit-Konsolenanwendungen wird von Konsolendem Kernel-Modul zur Verfgung gestellt. Solche Programme erschei- anwendungen
nen als einfache, herkmmliche DOS-Programme. Sie sind jedoch
vollwertige 32-Bit-Anwendungen, die ber die Kommandozeile ausgefhrt werden und die grafische Schnittstelle von Windows nicht nutzen.
Auch diese Anwendungen verfgen ber einen Zugriff auf sehr viele
Win32-Systemaufrufe. Eine Konsolenanwendung kann beispielsweise
die Funktionen zum virtuellen Speicher verwenden oder ein Multithread-Programm sein.
Windows NT
Einige Bereiche der Kernel-Modulfunktionalitt betreffen ausschlielich
Windows NT. Das NT-Kernel-Modul enthlt beispielsweise verschiedene Funktionen, mit deren Hilfe die Sicherheitsattribute der Kernel-Objekte ermittelt und gesetzt werden knnen.
Ein weiterer spezifischer NT-Bereich ist die Banddatensicherungsfunktionalitt. Einige Aufrufe lschen und formatieren ein Band, andere lesen oder schreiben Daten darauf.

7.3.2

User-Dienste

Wie der Name bereits impliziert, enthlt dieser Dienst Systemaufrufe,


die Elemente der Benutzerschnittstelle verwalten. Dazu zhlen Funktionen, die Fenster, Dialoge, Mens, Text- und Grafik-Cursor, Steuerelemente, die Zwischenablage und einige weitere Bereiche verwalten.
Erst durch die User-Dienstfunktionen werden die High-Level-Komponenten der Benutzerschnittstelle mglich. Das Kernel-Modul bietet
Speicherreservierung, Thread-Management und andere Dienste an,
die Windows bentigt, um ausgefhrt werden zu knnen. Das GDI-Modul verfgt ber grundlegende Grafikfunktionen. Erst das User-Modul
integriert diese beiden Bereiche und enthlt beispielsweise das Konzept eines Fensters.

126

Kapitel 7: Betriebssystembersicht

Fenster Fenster-Management-Aufrufe umfassen Funktionen zur Verwaltung

der Gre, Position, des Aufbaus und der Fensterprozedur, sowie


Funktionen zur Freigabe und zum Sperren eines Fensters. Auerdem
ermitteln diese Funktionen Informationen ber Fenster und verwalten
Steuerelemente, wie z.B. Schaltflchen, Bildlaufleisten oder Textfelder. Das Anwender-Modul enthlt ebenfalls Funktionen zur Verwaltung von untergeordneten MDI-Fenstern (Multiple Document Interface).
Mens Aufrufe in dem User-Modul, die sich auf Mens beziehen, stellen eine

Funktionalitt zur Verfgung, um Mens, Menleisten und Pop-up-Mens zu erstellen, darzustellen und zu manipulieren.
Mauszeiger Anwendungen knnen ber User-Funktionen die Form des grafischen

Mauszeigers und der Schreibmarke verndern.


Zwischenablage Die Verwaltung der Windows-Zwischenablage geschieht ebenfalls ber

User-Funktionen. Die Zwischenablage ist im wesentlichen ein einfacher Mechanismus, ber den Anwendungen Daten austauschen. Eine
Anwendung kann Daten in einem der verschiedenen Zwischenablageformate in der Zwischenablage plazieren. Andere Anwendungen knnen den Inhalt der Zwischenablage ermitteln und die darin enthaltenen
Daten verwenden, sofern diese in einem Format vorliegen, das die Anwendung interpretieren kann. Viele Anwendungen bieten Funktionen
zur Bearbeitung des Inhalts der Zwischenablage in dem Men BEARBEITEN an (AUSSCHNEIDEN, KOPIEREN, EINFGEN).
Nachrichten Auch die Funktionen zur Verwaltung von Nachrichten und Nachrich-

tenwarteschlangen sind in dem User-Modul enthalten. Anwendungen


knnen die entsprechenden Aufrufe verwenden, um den Inhalt einer
Nachrichtenwarteschlange zu berprfen, Nachrichten entgegenzunehmen. Nachrichten zu versenden und neue Nachrichten zu erstellen.

7.3.3

GDI-Dienste

Die Funktionen des GDI (Graphics Device Interface) werden gewhnlich dazu verwendet, einfache gerteunabhngige Grafikoperationen
auf bestimmten Gertekontexten auszufhren.
Gertekontexte Ein Gertekontext ist eine Schnittstelle zu einem spezifischen Grafikge-

rt. Der Gertekontext ermittlelt Informationen ber das Gert und


gibt die Grafiken darauf aus. Die Informationen, die ber den Gertekontext ermittelt werden knnen, beschreiben das Gert detailliert. Die
Technologie des Gerts (z.B. Vektor oder Raster), sein Typ, Name,
die Auflsung sowie Farben und Schriftarten werden mit Hilfe der entsprechenden Gertekontext-Aufrufe erfat.

Windows-Funktionsaufrufe

Die Grafikausgabe erfolgt durch die bergabe des GertekontextHandles an die entsprechende GDI-Ausgabefunktion. ber den Gertekontext wird ein allgemeiner gerteunabhngiger Grafikaufruf in
mehrere Anweisungen konvertiert, die schlielich die Grafik auf dem
Gert ausgeben. Ruft eine Anwendung beispielsweise die GDI-Funktion Ellipse auf, ermittelt der Gertekontext den Treiber, der den Aufruf
ausfhrt. Der Gertetreiber wiederum kann den Aufruf an einen Hardware-Beschleuniger weitergeben, sofern das Video-System diesen untersttzt.
GDI-Gertekontexte knnen verschiedene Gerte beschreiben. Einige
der berwiegend verwendeten Gertekontexte sind der Darstellungsgertekontext (fr die Ausgabe auf den Bildschirm des Computers), der
Speichergertekontext (fr die Ausgabe in eine Bitmap, die in dem
Speicher abgelegt wird) und der Druckergertekontext (fr die Ausgabe, die eventuell in den Steuercode des Druckers umgewandelt und an
diesen gesendet wird).
Ein besonderer Gertekontext ist der Meta-Datei-Gertekontext, der
Anwendungen ermglicht, eine kontinuierliche Aufzeichnung von
GDI-Ausgabeaufrufen durchzufhren. Diese Aufzeichnung ist gerteunabhngig und kann spter somit auf jedem Gert ausgegeben werden. Meta-Dateien erfllen eine besondere Funktion in der gerteunabhngigen Darstellung von eingebetteten OLE-Objekten. Sie
ermglichen das Portieren von OLE-Objekten und erlauben ContainerAnwendungen, diese Objekte sogar dann darstellen oder ausdrucken
zu lassen, wenn die Anwendung selbst nicht ausgefhrt wird.
Das Zeichnen in einen Gertekontext geschieht gewhnlich ber logische Koordinaten. Diese Koordinaten beschreiben Objekte mit realen
gerteunabhngigen Maen. Einem Rechteck kann beispielsweise eine
Breite von zwei Zentimetern und eine Hhe von einem Zentimeter zugewiesen werden. Die GDI konvertiert logische Koordinaten in physische Koordinaten.
Das Konvertieren der Koordinaten ist fr die Betriebssysteme Koordinaten
Windows 95/98 und Windows NT unterschiedlich. Wie sein 16-BitVorgnger ist auch Windows 95/98 auf 16-Bit-Koordinaten begrenzt.
Diese Begrenzung obliegt dem Umstand, da Windows 95/98 aus
sehr viel Windows-3.1-Programmcode besteht. Windows NT hingegen
arbeitet mit 32-Bit-Koordinaten. Daher ist dieses Betriebssystem fr
komplexe Grafikanwendungen geeignet, wie z.B. CAD-Programme.
Sowohl Windows NT als auch Windows 95/98 untersttzen eine einfache Konvertierung von logischen zu physischen Koordinaten. Dazu
werden die Werte der originalen Koordinaten ermittelt. Diese werden
auf die logischen und physischen Werte umgerechnet. Die ursprngli-

127

128

Kapitel 7: Betriebssystembersicht

chen Koordinaten geben eine horizontale und vertikale Verschiebung


an. Die Umrechnung ermittelt die Ausrichtung und Skalierung, der Objekte nach der Konvertierung.
Windows NT bietet auerdem Funktionen zur Transformation. Diese
Funktionen knnen jede lineare Transformation ausfhren, um logische Koordinaten in physische Koordinaten umzuwandeln. Zustzlich
zur Transformation und Skalierung kann die Ausgabe gedreht oder zugeschnitten werden.
Zeichen- Die wohl vorwiegend verwendeten GDI-Funktionen sind die zum
funktionen Zeichnen verschiedener Objekte, wie z.B. Rechtecke, Ellipsen, Poly-

gone oder Textelemente. (Das sind nur einige Beispiele.)


Andere Zeichenfunktionen sind die Funktionen zur Bit-Verschiebung,
die zum schnellen Kopieren von Bitmaps benutzt werden. (Fr Anwendungen, wie z.B. Spiele, die sehr hohe Geschwindigkeiten bentigen,
sollten die Funktionen zum Manipulieren von Bitmaps in der DirectXSDK verwendet werden.)
Gertekontext- Andere Funktionen verwalten die Gertekontexte. Kontexte fr verFunktionen schiedene Gerte knnen mit diesen Funktionen erstellt und zerstrt

werden. Auerdem kann der Status der Gerte gespeichert und wieder
geladen werden. Mit Hilfe dieser Funktionen ermitteln Sie ebenfalls Informationen ber die Gerte.
Koordinaten- Des weiteren bestehen Funktionen, die Koordinatenumwandlungen
funktionen bearbeiten. Funktionen fr alle Win32-Plattformen werden verwendet,

um den Ursprung und die Ausdehnung eines Fensters (die logischen


Koordinaten) und den Viewport (die Koordinaten des Zielgerts) zu setzen oder zu ermitteln. Spezifische NT-Funktionen manipulieren die
Transformationsmatrixen.
Paletten GDI-Funktionen knnen ebenfalls zur Bearbeitung von Paletten ver-

wendet werden. Diese werden vorwiegend von Anwendungen verwendet, die eine besondere Farbqualitt fr Gerte umsetzen mssen, die
lediglich ber eine begrenzte Anzahl der gleichzeitig darstellbaren Farben verfgen 256 Farben beispielsweise. Durch das Bearbeiten der
Farbpalette knnen diese Anwendungen (ein bezeichnendes Beispiel
ist ein Programm zur Ansicht von Grafikdateien, wie GIF- oder PCXDateien) eine Farbzusammenstellung einrichten, die zu der bestmglichen Darstellung des anzuzeigenden Bilds fhrt. Auf diese Weise wird
die Abhngigkeit von Dither-Techniken reduziert, wodurch die Bildqualitt verbessert wird. Sie haben auerdem die Mglichkeit, die
Farbpalette derart zu bearbeiten, da eine Palettenanimation entsteht.
Diese Technik verndert die Farbpalette, um den Eindruck einer Bewegung auf dem Bildschirm zu erzeugen.

Windows-Funktionsaufrufe

Ein weiteres GDI-Feature ist das Erstellen und Verwalten von GDI-Ob- GDI-Objekte
jekten. Pinsel, Stifte, Schriftarten, Bitmaps oder Paletten knnen in
Gertekontexten erstellt und selektiert werden, um die Form der zu
zeichnenden Figuren zu bestimmen.
Das GDI-Modul stellt auerdem Funktionen zum Verwalten von Schriftarten
Schriftarten zur Verfgung (einschlielich der TrueType-Schriftarten).
Andere Funktionen verwalten zwei Arten von Meta-Dateien (die her- Metadateien
kmmlichen Windows-Meta-Dateien sowie die neuen erweiterten
Meta-Dateien). Meta-Dateien knnen erstellt, gespeichert, wieder geladen und auf jedem Gert ausgegeben werden.
Ein weiteres Leistungsmerkmal des GDI-Moduls ist die Verwaltung von Clipping
Bereichen sowie das Clipping-Management. Clipping ist in der Windows-Umgebung sehr wichtig, da es einer Anwendung ermglicht,
eine Oberflche (z.B. ein untergeordnetes Fenster) ohne Rcksicht auf
deren Begrenzung darzustellen. Auerdem bercksichtigt das Clipping,
da bestimmte Bereiche der Oberflche von anderen Objekten auf
dem Bildschirm berdeckt werden knnen.

7.3.4

Andere APIs

Windows besteht natrlich aus weit mehr Funktionen als denen, die in
den drei zuvor beschriebenen Modulen enthalten sind. Darber hinaus
gibt es viele andere Module und viele andere APIs, die alle einen besonderen Bereich oder eine spezifische Funktionalitt implementieren.
Nachfolgend finden Sie einige der berwiegend verwendeten APIs aufgefhrt. Einige dieser APIs werden spter in diesem Buch detailliert erlutert.
C Allgemeine Steuerelementfunktionen werden zur Bearbeitung der
neuen allgemeinen Windows-95/98-Steuerelemente benutzt. Diese Funktionen sind natrlich ausschlielich unter Windows 95/98,
Windows NT 3.51 und hher erhltlich.
C Standarddialoge enthalten Systemdialoge zum ffnen einer Datei,
zum Selektieren einer Farbe aus einer Farbpalette, zur Auswahl einer Schrift aus den installierten System-Fonts und zum Bestimmen
eines Suchen- respektive Suchen- und Ersetzen-Vorgangs. Diese
Dialoge knnen entweder so verwendet werden, wie sie Ihnen zur
Verfgung stehen, oder ber neue Dialogvorlagen und Fensterprozeduren modifiziert werden.
C MAPI (Messaging Applications Programming Interface) gewhrt
den Anwendungen Zugriff auf die Nachrichtenfunktionen ber bestimmte Nachrichtensysteme, wie z.B. Microsoft Mail. Windows

129

130

Kapitel 7: Betriebssystembersicht

arbeitet mit drei verschiedenen MAPI-Varianten: Die einfache


MAPI wird von lteren Anwendungen genutzt, die auf Nachrichten
basieren. Dazu zhlen Anwendungen, die kein Nachrichtensystem
erfordern, dieses jedoch verwenden knnen, wenn es vorhanden
ist. Microsoft Word lt sich dieser Kategorie zuordnen. Neue Anwendungen, die mit Nachrichten arbeiten (die somit ein bestehendes Nachrichtensystem verwenden), sollten CMC (Common Messaging Calls Interface) nutzen. Komplex auf Nachrichten
basierende Workgroup-Anwendungen arbeiten gewhnlich mit allen MAPI-Diensten (Erweiterte MAPI).
C MCI (Multimedia Control Interface) ist die Multimedia-Schnittstelle. ber die MCI-Funktionen erhalten Anwendungen Zugriff auf
die Video-, Audio- und MIDI-Funktionalitt von Windows. Die
berwiegende Anzahl der Multimedia-Anwendungen verwendet die
MCI-Funktionen fr die Medienwiedergabe. Einige Anwendungen
nutzen mglicherweise komplexere MCI-Funktionen fr die Bearbeitung von Medien-Dateien.
C Die COM-API ist eine umfangreiche Sammlung von Systemaufrufen, die die gesamte OLE-Funktionalitt implementieren. Dazu
zhlen OLE-Container und Server-Funktionalitt fr die InplaceBearbeitung, das Aktivieren von Objekten, Drag & Drop, Automatisierung und ActiveX-Steuerelemente (frher benutzerdefinierte
OLE-Steuerelemente).
C TAPI ist die Telefonie-API. Anwendungen verwenden die TAPI,
um gerteunabhngig auf Telefonie-basierende Ressourcen zuzugreifen (Modems, FAX-Modems, Anrufbeantworter).
Verschiedene Bereiche sind der Netzwerk-Funktionalitt zugewiesen.
Dazu zhlen WinSock, die Windows-Socket-Bibliothek, WinInet, die
Windows-Internet-API, RAS (Remote Access Service) und die RPC-Bibliothek (Remote Procedure Call).

7.3.5

Fehlerrckgaben

Viele Windows-Funktionen verwenden einen allgemeinen Mechanismus fr die Fehlerrckgabe. Tritt ein Fehler auf, setzen diese Funktionen einen spezifischen Thread-Fehlerwert, der mit einem Aufruf der
Funktion GetLastError ermittelt werden kann. Die 32-Bit-Werte, die
von dieser Funktion zurckgegeben werden, sind in der Header-Datei
WINERROR.H oder in spezifischen Bibliothek-Headerdateien definiert.

Windows-Funktionsaufrufe

Die Funktionen Ihrer Anwendung knnen diesen Fehlerwert ebenfalls


setzen, indem Sie SetLastError aufrufen. Spezifische Anwendungsfehler sind dadurch gekennzeichnet, da das 29. Bit des Fehlerwerts gesetzt ist. Fehlercodes mit diesem gesetzten Bit sind von dem Betriebssystem fr die anwendungsspezifische Verwendung reserviert.

7.3.6

Verwenden von Standard-C/C++-BibliotheksFunktionen

Win32-Anwendungen knnen mit einigen Einschrnkungen ebenfalls


die Standardfunktionen der C/C++-Bibliothek nutzen.
Eine Windows-Anwendung verfgt gewhnlich nicht ber einen Zugriff
auf die traditionellen stdin-, stdout- oder stderr-Strme, und auch
nicht ber die entsprechenden DOS-Dateizugriffsnummern (0, 1 und
2) oder C++-Ein- und Ausgabe-Objekte (cin und cout). Lediglich Konsolenanwendungen knnen diese Standard-Dateizugriffsnummern verwenden. (Windows-Anwendungen verfgen jedoch ber einen eigenen
Ein- und Ausgabestandard.)
Wie ich bereits erwhnte, sollten Windows-Anwendungen die Win32Dateiverwaltungsfunktionen fr die Dateiverwaltung verwenden. Das
bedeutet nicht, da die Standardfunktionen des C-Stroms und der
Low-Level-Ein- und Ausgabe oder die C++-Ein- und Ausgabe-Bibliothek nicht mehr verfgbar wren. Diese Bibliotheken verfgen lediglich
nicht ber die Mglichkeiten der Win32-API. Die Funktionen der C/
C++-Bibliothek bercksichtigen beispielsweise nicht die Sicherheitsattribute eines Dateiobjekts und knnen auch nicht fr die asynchronen,
berlappten Ein- und Ausgabe-Operationen verwendet werden.
Anwendungen sollten auch auf die Verwendung der C-Bibliothek verzichten, die MS-DOS-Funktionen zur Steuerung der Prozesse enthlt,
und statt dessen CreateProcess benutzen.
Die meisten anderen C/C++-Bibliotheken knnen ohne Einschrnkungen verwendet werden. Wenngleich die Win32-API eine grere
Anzahl verschiedener Funktionen zur Speicherverwaltung anbietet, bentigen die meisten Anwendungen keine Dienste, die komplexer als
die von malloc oder dem C++-Operator new angebotenen Dienste sind.
Die C/C++-Routinen zur Bearbeitung von Puffern, Zeichenfolgen,
Zeichen- und Byte-Klassifizierungen, Datenkonvertierung und mathematischen Funktionen, um nur einige zu nennen, knnen ebenfalls uneingeschrnkt genutzt werden.

131

132

Kapitel 7: Betriebssystembersicht

Win32-Anwendungen sollten nicht versuchen, auf den MS-DOS-Interrupt 21 oder auf IBM-PC-BIOS-Funktionen zuzugreifen. Die APIs, die
zu diesem Zweck unter der 16-Bit-Version von Windows angeboten
wurden, bestehen nicht mehr. Anwendungen, die einen Low-Level-Zugriff auf die System-Hardware bentigen, sollten mit dem entsprechenden DDK (Device Driver Development Kit) entwickelt werden.

7.4

Plattformunterschiede

Die Win32-API wurde entwickelt, um als plattformunabhngige API zu


dienen. Dennoch bestehen einige Plattformunterschiede, die sich auf
Einschrnkungen des zugrundeliegenden Betriebssystems beziehen. Einige dieser Restriktionen wurden zuvor in diesem Kapitel beschrieben.
Die folgenden Abschnitte fhren eine bersicht und Zusammenfassung der Windows-95/98- und Windows-NT-Features auf.
Visual C++ kann nicht nur Anwendungen fr diese beiden Plattformen
erzeugen, sondern auch darauf installiert werden. Nachfolgend finden
Sie einige Hinweise zur Programmentwicklung mit Hilfe dieser Betriebssysteme.

7.4.1

Windows NT

Eine beinahe vollstndige Implementierung der Win32-API ist in


Windows NT enthalten. Seit Version 3.51 bietet Windows NT dieselben neuen benutzerdefinierten Steuerelemente wie Windows 95/98
an.
Windows NT untersttzt Unicode, erweiterte Sicherheits-Features und
unterschiedliche System-Level whrend einer Bandsicherung. Die Server-Plattform Windows NT verfgt ber eine komplexere Server-Umgebung als Windows 95/98. Dank einer echten 32-Bit-Implementierung ist Windows NT die stabilere Plattform. Dieses Betriebssystem ist
daher als Entwicklungsumgebung sehr geeignet.
Windows NT wurde bisher nachgesagt, Speicher und CPU-Leistung zu
sehr zu beanspruchen. Version 4.0 ist hinsichtlich dieses Rufs eine angenehme berraschung pltzlich ist NT schneller als Windows 95/
98. Obwohl das Betriebssystem weiterhin sehr viel Speicher bentigt,
erscheint sogar die Speicherverwaltung effizienter als bisher. Ein gut
ausgestattetes Entwicklungssystem sollte unter Windows NT ber mindestens 32 Mbyte RAM, 1 Gbyte Festplattenkapazitt und einen Pentium-Prozessor verfgen.

Zusammenfassung

7.4.2

Windows 95/98

Obwohl Windows 95/98 einige Features von Windows NT vermissen


lt, ist es diesem bezglich der Kompatibilitt zu lterer Software und
Hardware berlegen. Die berwiegende Anzahl der Features, die nicht
unter Windows 95/98 realisiert wurden, fehlt den Anwendern nicht.
Doch welche Funktionen fehlen Windows 95/98? Die erweiterten Sicherheits-Features, die Untersttzung von Unicode und unterschiedlichen System-Levels whrend der Bandsicherung wurden bereits genannt.
Fr Grafikprogrammierer, die von der NT-Umgebung kommen, bestehen einige Nachteile. Zwei dieser Nachteile sind die fehlende GDI-Untersttzung fr Transformationsfunktionen und die Begrenzung des
Koordinatenraums auf 16-Bit-Koordinaten.
Windows 95/98 hingegen ist eine flexible und stabile Multithread-Umgebung, die sich in vielerlei Hinsicht mit Windows NT vergleichen lt.
Windows 95/98 stellt eine umfangreiche Untermenge der Win32-API
zur Verfgung. Mit Ausnahme der spezifischen NT-Features, die bereits erwhnt wurden, sind die meisten API-Funktionen erhltlich.
Die Speicherverwaltung von Windows 95/98 ist ein wenig besser als
die von Windows NT. Einige Anwender konnten das Betriebssystem
auf einem alten 386-System mit 4 Mbyte RAM installieren.
Windows 95/98 bildet eine ausgezeichnete Entwicklungsplattform.
Seine Stabilitt ist auergewhnlich, auch wenn diese nicht mit der
von Windows NT verglichen werden kann. Alle 32-Bit-Entwicklungswerkzeuge, einschlielich der Konsolenanwendungen, werden korrekt
auf dieser Plattform ausgefhrt.

7.5

Zusammenfassung

Visual-C++-Anwendungen knnen in der Win32-Umgebung eingesetzt werden. Dazu zhlen die verschiedenen spezifischen Plattformversionen von Windows NT und Windows 95/98. Die 32-Bit-Erweiterung fr Windows 3.1, Win32s, wird nicht mehr untersttzt.
Der Kern jeder Windows-Anwendung ist die Nachrichtenschleife. Das
Betriebssystem informiert Anwendungen mit Hilfe von Nachrichten
ber unterschiedliche Ereignisse. Anwendungen wiederum bearbeiten
diese Nachrichten nach einem Aufruf der entsprechenden Fensterfunktion. Ein Fenster ist ein rechteckiger Bereich des Bildschirms, aber
auch ein abstraktes, eigenstndiges Objekt, das Nachrichten empfangen und bearbeiten kann.

133

134

Kapitel 7: Betriebssystembersicht

Prozesse oder Anwendungen besitzen Threads. Diese wiederum besitzen Fenster. Threads sind parallele Ausfhrungspfade innerhalb einer
Anwendung.
Anwendungen interagieren mit Windows, indem Sie eine der vielen
Betriebssystemfunktionen aufrufen, die entweder in Windows selbst
oder in verschiedenen Add-Ons implementiert sind. Die Systemfunktionen lassen sich in drei Kategorien unterteilen. Das Kernel-Modul
verwaltet den Speicher, Dateien und Prozesse. Das User-Modul verwaltet die Elemente der benutzerdefinierten Schnittstelle (besonders
Fenster) und Nachrichten. Das GDI-Modul stellt Grafikdienste zur Verfgung.
Weitere Module implementieren bestimmte Funktionalitten, wie z.B.
COM, MAPI, Netzwerk, allgemeine Steuerelemente und Standarddialoge sowie Multimedia.
Visual-C++-Anwendungen knnen mit einigen Einschrnkungen Standardfunktionen der C/C++-Bibliothek verwenden.
Die drei primren Win32-Plattformen unterscheiden sich in der Implementierung der Win32-API. Eine beinahe vollstndige Implementierung bietet Windows NT. Windows 95/98 verfgt ber eine groe Untermenge der API-Funktionen. Einige spezifische NT-Elemente und
erweiterte Komponenten fehlen dem Betriebssystem jedoch.

Das APIAnwendungsgerst

Kapitel

inige Anwender, die ber die Windows-Programmierung sprechen, sind der Meinung, da mit einem Betriebssystem etwas
nicht stimmen kann, das sehr viele Programmzeilen bentigt, um ein
einfaches Programm zur Ausgabe der Nachricht Hello, World! ausfhren zu lassen. Doch ist diese Aussage wirklich wahr oder nur ein
weiteres Gercht ber das Unternehmen Microsoft und das Betriebssystem Windows?

8.1

Das wahre Hello-WorldProgramm

Betrachten Sie bitte einmal den Dialog in Abbildung 8.1. Wie viele Zeilen C-Programmcode und Ressource-Code glauben Sie sind notwendig, um eine Anwendung zu erstellen, die lediglich diesen Dialog anzeigt? Keine? Um wie viele Zeilen ist dieses Programm lnger als das
originale Hello-World-Programm, das zu Beginn des ersten Kapitels
der C-Bibel von Kernighan-Ritchie erscheint?
Abbildung 8.1:
Hello World
unter Windows

Sie haben richtig geraten. Die Anzahl der Programmzeilen betrgt in


beiden Fllen fnf Zeilen (wobei die Leerzeilen zwischen dem eigentlichen Programmcode nicht gezhlt werden). Die Windows-Version des
Hello-World-Programms ist in Listing 8.1 aufgefhrt.

136

Listing 8.1:
Der Quellcode
des Hello-WorldProgramms
hello.c

Kapitel 8: Das API-Anwendungsgerst

#include <windows.h>
int WINAPI WinMain(HINSTANCE d1, HINSTANCE d2, LPSTR d3, int d4)
{
MessageBox(NULL, "Hello, World!", "", MB_OK);
}

Das Kompilieren dieses Programms ist nicht schwieriger als die Kompilierung des originalen Hello-World-Programms ber die Kommandozeile. (Nehmen Sie dieses Beispielprogramm als Anla, den VisualC++-Compiler ber die Kommandozeile zu verwenden.) Damit der
Compiler von der Kommandozeile aus gestartet werden kann, mu zunchst die Batch-Datei VCVARS32.BAT ausgefhrt werden. Visual
C++ erstellt diese Datei whrend der Installation in dem \BIN-Verzeichnis von VC. (Abhngig von Ihrem System und dessen Konfiguration, mssen Sie den Umgebungsspeicher fr DOS-Fenster mglicherweise vergrern.)
Schlielich geben Sie
CL HELLO.C USER32.LIB
ein. Das Programm Hello.exe kann nun ausgefhrt werden. Geben
Sie dazu HELLO in die Kommandozeile ein. Sowohl Windows 95/98
als auch Windows NT knnen Anwendungen auf diese Weise starten.
Das Verhalten dieser Anwendung ist berraschend komplex. Im Gegensatz zu seinem einfachen C-Pendant zeigt das Programm nicht
nur die Nachricht an. Es interagiert mit dem Anwender. Nachdem die
Nachricht ausgegeben wurde, wird die Anwendung weiterhin auf dem
Bildschirm angezeigt und kann mit der Maus verschoben werden. Sie
knnen die Schaltflche OK bettigen, um das Programm zu beenden.
Alternativ dazu knnen Sie die Maustaste ber der Schaltflche drkken und halten. Beobachten Sie, wie sich die Schaltflche verndert,
wenn Sie den Mauszeiger darber bewegen. Das Fenster verfgt ebenfalls ber ein Men, das mit der Tastenkombination (Alt) + (____) geffnet werden kann. Unter Windows 95/98 ffnen Sie dieses Men,
indem Sie den Mauszeiger auf die Titelzeile bewegen und mit der rechten Maustaste klicken. Der Eintrag VERSCHIEBEN in diesem Men wird
verwendet, um die Position des Fensters zu verndern. Mit einem
Druck auf die Taste (Esc) kann die Anwendung ebenfalls geschlossen
werden.
Wie Sie sehen, verfgt die Anwendung trotz der wenigen Code-Zeilen
ber sehr viele Funktionen. Doch woher kommt diese Komplexitt?
Die Antwort lautet: Nachrichtenschleife und Fensterfunktion. Leider ist
ein fnfzeiliges Programm fr die Erluterung des Verhaltens von Windows-Anwendungen nicht geeignet. Wir werden zu diesem Zweck eine
umfangreichere Anwendung verwenden.

Eine einfache Nachrichtenschleife: Senden und Hinterlegen von Nachrichten

8.2

137

Eine einfache Nachrichtenschleife: Senden und Hinterlegen von Nachrichten

Das Problem unseres ersten Hello-World-Programms ist dessen


Schlichtheit. Der Aufruf von MessageBox fhrt zu einer komplexen, fr
uns nicht erkennbaren Funktionalitt. Damit wir diese Funktionalitt
verstehen knnen, mssen wir sie sichtbar machen. Wir erstellen daher ein Fenster, das wir selbst verwalten. Die Funktion MessageBox wird
nicht diese Aufgabe fr uns bernehmen.
Die neue Version des Programms HELLO.C ist in Abbildung 8.2 dargestellt. Diesmal erscheint der Text Hello, World! auf einer Schaltflche, die den gesamten Client-Bereich einnimmt. (Der Text wird auerdem in der Titelzeile des Fensters aufgefhrt.) Die Anwendung ist sehr
einfach aufgebaut, so da wir die wesentlichen Elemente errtern knnen, ohne auf irrelevante Details eingehen zu mssen.
Abbildung 8.2:
Hello, World,
mit einer einfachen Nachrichtenschleife

Ein gewhnliches Windows-Programm registriert zunchst eine Fensterklasse whrend der Initialisierung, bevor es das Hauptfenster aus
der zuvor registrierten Klasse erzeugt. Wir verzichten vorerst auf die
Registrierung einer neuen Klasse und die damit verbundenen Umstnde (wie z.B. das Schreiben einer Fensterfunktion). Statt dessen verwenden wir eine der bestehenden Fensterklassen, die mit BUTTON bezeichnet ist. Die Funktionalitt dieser Klasse entspricht nicht dem
Verhalten der vorherigen Version von HELLO.C. Das ist auch nicht
meine Absicht. Mein Ziel besteht darin, Ihnen die Funktion einer einfachen Nachrichtenschleife zu demonstrieren.
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE d2,
LPSTR d3, int d4)
{
MSG msg;
HWND hwnd;
hwnd = CreateWindow("BUTTON", "Hello, World!",
WS_VISIBLE | BS_CENTER, 100,100,100,80,
NULL, NULL, hInstance, NULL);
while (GetMessage(&msg, NULL, 0, 0))

Listing 8.2:
Hello, World mit
einer einfachen
Nachrichtenschleife

138

Kapitel 8: Das API-Anwendungsgerst

{
if (msg.message == WM_LBUTTONUP)
{
DestroyWindow(hwnd);
PostQuitMessage(0);
}
DispatchMessage(&msg);
}
return msg.wParam;
}

Dieses Beispiel beschreibt eine Nachrichtenschleife. Nachdem das


Fenster des Programms erstellt wurde, wird eine while-Schleife ausgefhrt, die wiederholt die Windows-Funktion GetMessage aufruft. Erhlt
die Anwendung eine Nachricht, gibt GetMessage einen Wert zurck.
Dieser Wert ist nur dann FALSE, wenn die erhaltene Nachricht WM_QUIT
war. (Diese und andere symbolische Konstanten sind in den HeaderDateien definiert, wie z.B. WINDOWS.H.) Das Programm reagiert
auf die spezielle Nachricht WM_LBUTTONUP. Trifft diese Nachricht ein,
wird das Fenster mit einem Aufruf von DestroyWindow zerstrt. Ein Aufruf der Funktion PostQuitMessage gewhrleistet, da die Funktion GetMessage auf den Empfang der WM_QUIT-Nachricht wartet, woraufhin die
Schleife verlassen wird. Andere Nachrichten als WM_LBUTTONUP werden
mit Hilfe der Funktion DispatchMessage weitergeleitet.
Wohin aber werden die Nachrichten mit der DispatchMessage-Funktion
weitergeleitet? Die Nachrichten werden an die Standard-Fensterfunktion der Klasse BUTTON weitergeleitet. Diese Fensterfunktion bleibt uns
verborgen, da Sie ein Teil des Betriebssystems ist.
Der Aufruf der Funktion DestroyWindow in dem Abschnitt, der die Nachricht WM_LBUTTONUP bearbeitet, erstellt eine weitere Nachricht mit der Bezeichnung WM_DESTROY. Eine bessere Vorgehensweise als das Zerstren
der Anwendung mit einem Aufruf der PostQuitMessage-Funktion im
WM_LBUTTONUP-Handler besteht darin, den Aufruf dieser Funktion in einen
anderen Bedingungsblock einzubinden, der sich auf die WM_DESTROYNachricht bezieht. Dies ist jedoch nicht mglich, da WM_DESTROY-Nachrichten gewhnlich nicht hinterlegt, sondern direkt an die Anwendung
gesendet werden.
Wenn eine Nachricht hinterlegt wird, ermittelt die Anwendung diese
ber einen Aufruf der Funktion GetMessage oder PeekMessage. (PeekMessage wird verwendet, wenn die Anwendung einige Aufgaben ausfhren
mu und keine Nachrichten zur Bearbeitung vorliegen.) Das Senden einer Nachricht an eine Anwendung impliziert einen direkten und unmittelbaren Aufruf der Fensterfunktion, wobei alle Nachrichtenschleifen
umgangen werden. Die Nachricht WM_DESTROY, die nach einem Aufruf
von DestroyWindow erzeugt wird, kann daher nicht von der Nachrichtenschleife empfangen werden. Sie wird der Fensterfunktion der Fensterklasse BUTTON direkt bergeben.

Fensterfunktionen

139

Auch dieses Beispiel hat uns nicht geholfen, den Aufbau einer Fensterfunktion zu verstehen. Sie werden daher eine weitere, komplexere
Version des Hello-World-Programms kennenlernen.

8.3

Fensterfunktionen

In diesem Abschnitt werden wir fr unsere Anwendung ein eigene Fensterklasse registrieren. In der Fensterklasse definieren wir einen Zeiger
auf eine Fensterfunktion. Alle Fenster, die auf der Grundlage der Fensterklasse erzeugt werden, sind dann mit dieser Fensterfunktion verbunden.

8.3.1

Mausbehandlung

In dieser Version von Hello.c nutzen wir die Fensterfunktion, um die


Nachricht WM_LBUTTONDOWN abzufangen. Als Antwort auf diese Nachricht
zeichnen wir den Hello-World-Gru in das Fenster.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
HDC hDC;
RECT clientRect;
switch(uMsg)
{
case WM_LBUTTONDOWN:
hDC = GetDC(hwnd);
if (hDC != NULL)
{
GetClientRect(hwnd, &clientRect);
DPtoLP(hDC, (LPPOINT)&clientRect, 2);
DrawText(hDC, "Hello, World!", -1, &clientRect,
DT_CENTER|DT_VCENTER|DT_SINGLELINE);
ReleaseDC(hwnd,hDC);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR d3, int nCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndClass;

Listing 8.3:
Quellcode von
Hello World mit
einer neuen Fensterklasse

140

Kapitel 8: Das API-Anwendungsgerst

if (hPrevInstance == NULL)
{
memset(&wndClass, 0, sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = "HELLO";
if (!RegisterClass(&wndClass)) return FALSE;
}
hwnd = CreateWindow("HELLO", "HELLO",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
return msg.wParam;
}

Um dieses Programm kompilieren zu knnen, mssen Sie die Bibliothek gdi32.lib in der Kommandozeile angeben:
CL HELLO.C USER32.LIB GDI32.LIB
Abbildung 8.3:
Hello World mit
eigener Fensterklasse

Dieses Programm demonstriert Einsatz einer Fensterklasse und Untersttzung der Maus durch das Programm. Klickt der Anwender mit der
Maus in das Fenster, erscheint der Hello-World-Text. Das Programm
verfgt ber ein Systemmen und kann verschoben, vergrert und
verkleinert werden, und es reagiert auf den Meneintrag SCHLIESSEN
oder die Tastenkombination (Alt) + (F4).

Fensterfunktionen

141

Doch wie arbeitet das Programm?


Zunchst beginnt die Ausfhrung mit der Funktion WinMain. Die An- Fensterklasse
wendung prft, ob Kopien des Programms ausgefhrt werden. In die- registrieren
sem Fall mu die Fensterklasse nicht erneut registriert werden. Andernfalls wird die Fensterklasse registriert, und ihre Eigenschaften
werden in der Struktur WndClass definiert. In diese Struktur wird ebenfalls die Adresse der Fensterfunktion WndProc bestimmt.
Anschlieend wird ein Fenster mit einem Systemaufruf der Funktion Fenster ezeugen
CreateWindow erstellt. Nachdem das Fenster dargestellt wurde, wird die
Nachrichtenschleife ausgefhrt. Diese wird verlassen, wenn GetMessage
die Nachricht WM_QUITT erhlt und daraufhin den Wert FALSE zurckgibt.
WndProc zeigt die Struktur der Fensterfunktion. Eine gewhnliche Fen- Die Fenstersterfunktion ist eine umfangreiche switch-Anweisung. Abhngig von funktion

den erhaltenen Nachrichten, werden unterschiedliche Funktionen aufgerufen, die die erforderlichen Aktionen ausfhren. Der Programmcode in Listing 8.3 bearbeitet zwei Nachrichten: WM_LBUTTONDOWN und
WM_DESTROY.
Als Antwort auf die WM_LBUTTONDOWN-Nachricht holt sich die Fensterfunktion einen Handle zum Gertekontext des Fensters und gibt den Hello-World-Text zentriert im Fenster aus.
WM_DESTROY-Nachrichten werden versendet, wenn der Anwender das
Zerstren eines Anwendungsfensters verursacht. Unser Programm
reagiert darauf mit einem Aufruf der Funktion PostQuitMessage. Auf
diese Weise wird gewhrleistet, da die GetMessage-Funktion in WinMain
die Nachricht WM_QUIT erhlt. Die Hauptnachrichtenschleife wird daraufhin verlassen.

Was geschieht mit Nachrichten, die nicht von unserer Fensterfunktion


bearbeitet werden? Solche Nachrichten werden an die Standard-Fensterfunktion DefWindowProc weitergeleitet. Diese Funktion steuert ber
ihre Standardbehandlungsroutine das Verhalten des Anwendungsfensters und der Nicht-Client-Bereichskomponenten (wie z.B. die Titelzeile).
Das Dialog-Pendant zu DefDlgProc heit DefWindowProc. Die Funktion
bearbeitet spezifische Dialog-Nachrichten und verwaltet die Steuerelemente des Dialogs, wenn dieser den Fokus erhlt oder verliert.

142

Kapitel 8: Das API-Anwendungsgerst

8.3.2

Die Besonderheit von WM_PAINT

Das letzte Beispiel war schon eine ausgereifte Windows-Anwendung.


Allerdings mute man zur Anzeige des Textes erst die linke Maustaste
drcken. Auch verschwand der Text wieder, wenn Windows das Fenster neu aufbauen mute (beispielsweise, wenn der Anwender das Fenster minimiert und dann wiederherstellt).
Windows kann Fenster mitsamt Inhalt verschieben, aber nicht wieder
von Null aufbauen. Statt dessen schickt Windows immer dann, wenn
ein Neuaufbau des Fensterinhalts erforderlich wird, eine WM_PAINTNachricht an das Fenster. Aufgabe des Fensters ist es, diese Nachricht
abzufangen und den Fensterinhalt zu rekonstruieren.
Listing 8.4: #include <windows.h>
Hello World und void DrawHello(HWND hwnd)
WM_PAINT {
HDC hDC;
PAINTSTRUCT paintStruct;
RECT clientRect;
hDC = BeginPaint(hwnd, &paintStruct);
if (hDC != NULL)
{
GetClientRect(hwnd, &clientRect);
DPtoLP(hDC, (LPPOINT)&clientRect, 2);
DrawText(hDC, "Hello, World!", -1, &clientRect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
EndPaint(hwnd, &paintStruct);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_PAINT:
DrawHello(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR d3, int nCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndClass;
if (hPrevInstance == NULL)
{
memset(&wndClass, 0, sizeof(wndClass));

Mehrere Nachrichtenschleifen und Fensterfunktionen

143

wndClass.style = CS_HREDRAW | CS_VREDRAW;


wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = "HELLO";
if (!RegisterClass(&wndClass)) return FALSE;
}
hwnd = CreateWindow("HELLO", "HELLO",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
return msg.wParam;
}

Um dieses Programm kompilieren zu knnen, mssen Sie die Bibliothek gdi32.lib in der Kommandozeile angeben (CL HELLO.C
USER32.LIB GDI32.LIB).
Beachten Sie, da in der Behandlung der WM_PAINT-Nachricht der Gertekontext nicht ber GetDC/ReleaseDC, sondern BeginPaint und EndPaint
ermittelt und freigegeben wird.
Die Auslagerung des Codes zur Bearbeitung der WM_PAINT-Nachricht
in eine eigene Funktion ist nicht ntig, kann aber das Programm
bersichtlicher machen.

8.4

Mehrere
Nachrichtenschleifen und
Fensterfunktionen

Bisher haben wir in unseren HELLO.C-Beispielen lediglich eine Nachrichtenschleife verwendet. (In dem ersten Beispiel befand sich die Nachrichtenschleife in der MessageBox-Funktion.) Kann mehr als eine Nachrichtenschleife in einer Anwendung verwendet werden? Und wieso
sollten derartige Anwendungen erstellt werden, wenn dies mglich ist?
Die Antwort auf die erste Frage lautet: ja. Anwendungen knnen mehrere Nachrichtenschleifen einsetzen. Stellen Sie sich die folgende Situation vor: Eine Anwendung, die ber eine eigene Nachrichtenschleife verfgt, ruft eine MessageBox-Funktion auf. Dieser Aufruf fhrt dazu,
da die in der MessageBox-Funktion implizierte Nachrichtenschleife eine
gewisse Zeit, nmlich whrend die Nachricht angezeigt wird, die Bearbeitung der Nachrichten bernimmt.

Anwendungen
knnen mehrere
Nachrichtenschleifen einsetzen

144

Kapitel 8: Das API-Anwendungsgerst

Dieses Szenarium gibt die Antwort auf die zweite Frage. Sie implementieren eine zweite (oder dritte, vierte usw.) Nachrichtenschleife, wenn
Nachrichten zu einem bestimmten Zeitpunkt whrend der Programmausfhrung auf eine andere Weise als bisher bearbeitet werden mssen.
Freihand- Stellen Sie sich beispielsweise das Zeichnen mit der Maus vor. Eine
zeichnen Anwendung kann eine Freihand-Zeichenfunktion zur Verfgung stel-

len, indem Sie auf Mausereignisse reagiert und die Position der Maus
ermittelt, wenn die linke Maustaste im Client-Bereich bettigt wird.
Whrend der Ermittlung der Koordinaten wird die Anwendung mit Hilfe separater Nachrichten ber jede Mausbewegung informiert. Die Anwendung zeichnet somit eine Freihandlinie, indem Sie der Zeichnung
ein neues Segment hinzufgt, wenn der Anwender die Maus bewegt.
Das Zeichnen ist beendet, wenn der Anwender die linke Maustaste loslt.
Die fnfte und letzte Version des Hello-World-Programms verwendet
mehrere Nachrichtenschleifen. Sie mu ber die Kommandozeile mit
der Anweisung
CL HELLO.C USER32.LIB GDI32.LIB
kompiliert werden. Sie ermglicht Ihnen, den Text Hello, World! mit
der Maus zu zeichnen.
Abbildung 8.4:
Grafische Version von Hello
World

Mehrere Nachrichtenschleifen und Fensterfunktionen

145

Der in Listing 8.4 aufgefhrte Quellcode der Anwendung enthlt zwei


while-Schleifen, die die GetMessage-Funktion aufrufen. Die Hauptnachrichtenschleife in WinMain unterscheidet sich nicht von der des letzten
Beispiels. Der neue Programmcode befindet sich in der Funktion DrawHello.
#include <windows.h>
void AddSegmentAtMessagePos(HDC hDC, HWND hwnd, BOOL bDraw)
{
DWORD dwPos;
POINTS points;
POINT point;
dwPos = GetMessagePos();
points = MAKEPOINTS(dwPos);
point.x = points.x;
point.y = points.y;
ScreenToClient(hwnd, &point);
DPtoLP(hDC, &point, 1);
if (bDraw) LineTo(hDC, point.x, point.y);
else MoveToEx(hDC, point.x, point.y, NULL);
}
void DrawHello(HWND hwnd)
{
HDC hDC;
MSG msg;
if (GetCapture() != NULL) return;
hDC = GetDC(hwnd);
if (hDC != NULL)
{
SetCapture(hwnd);
AddSegmentAtMessagePos(hDC, hwnd, FALSE);
while(GetMessage(&msg, NULL, 0, 0))
{
if (GetCapture() != hwnd) break;
switch (msg.message)
{
case WM_MOUSEMOVE:
AddSegmentAtMessagePos(hDC, hwnd, TRUE);
break;
case WM_LBUTTONUP:
goto ExitLoop;
default:
DispatchMessage(&msg);
}
}
ExitLoop:
ReleaseCapture();
ReleaseDC(hwnd, hDC);
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_LBUTTONDOWN:
DrawHello(hwnd);

Listing 8.5:
Quellcode der
grafischen Version von Hello
World

146

Kapitel 8: Das API-Anwendungsgerst

break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR d3, int nCmdShow)
{
MSG msg;
HWND hwnd;
WNDCLASS wndClass;
if (hPrevInstance == NULL)
{
memset(&wndClass, 0, sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndClass.lpszClassName = "HELLO";
if (!RegisterClass(&wndClass)) return FALSE;
}
hwnd = CreateWindow("HELLO", "HELLO",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
return msg.wParam;
}

Das vorherige Beispiel gibt Hello, World! ber eine Zeichenfolge aus.
Das aktuelle Beispiel ist sehr viel komplexer. Es prft zunchst, ob eine
andere Anwendung die Maus verwendet und ermittelt den Handle des
Gertekontextes fr das Hauptfenster. Anschlieend wird die Maus mit
Hilfe der Funktion SetCapture okkupiert. Windows beginnt daraufhin,
der Anwendung WM_MOUSEMOVE-Nachrichten zu senden.
Die Funktion DrawHello ruft die Hilfsfunktion AddSegmentAtMessagePos
auf, die die aktuelle Zeichenposition auf die in der letzten Nachricht
vermerkte Position setzt, wenn als dritter Parameter der Boolesche
Wert FALSE bergeben wurde. Dazu wird die GetMessagePos-Funktion
aufgerufen, die die Position des Mauszeigers whrend der Erstellung
der letzten Nachricht zurckgibt. AddSegmentAtMessagePos verwendet auerdem Transformationsfunktionen, um die Bildschirmkoordinaten der
Maus in die logischen Koordinaten des Fensters umzuwandeln.
Nach dem Aufruf der Funktion AddSegmentAtMessagePos fhrt die DrawHello-Funktion die neue Nachrichtenschleife aus. Whrend die Maus
okkupiert wird, erwarten wir ein besonderes Verhalten von unserer

Zusammenfassung

Anwendung. Sie soll die Mausbewegungen berwachen und der Zeichnung zustzliche Segmente hinzufgen. Dazu wird erneut die Funktion
AddSegmentAtMessagePos aufgerufen. Der dritte bergebene Parameter
wird auf TRUE gesetzt, wenn die Anwendung eine WM_MOUSEMOVE-Nachricht empfngt.
Die Nachrichtenschleife wird verlassen, wenn die Maustaste losgelassen wird oder der Anwendung die Maus entzogen wird. In diesem Fall
wird die Routine DrawHello beendet, und die erste Nachrichtenschleife
setzt die Bearbeitung der nachfolgenden Nachrichten fort.
War die Implementierung der beiden Nachrichtenschleifen wirklich
notwendig? Htten wir die WM_MOUSEMOVE-Nachrichten nicht ebenfalls in
der Fensterfunktion bearbeiten knnen? Sicherlich wre diese Vorgehensweise mglich gewesen, doch ein strukturierter Programmcode,
wie der des letzten Beispiels, gestalten Programme bersichtlicher.

8.5

Zusammenfassung

Jede Windows-Anwendung verwendet eine Nachrichtenschleife. Nachrichtenschleifen rufen wiederholt eine der Funktionen GetMessage oder
PeekMessage auf und empfangen auf diese Weise Nachrichten, die anschlieend ber DispatchMessage an die Fensterfunktionen weitergeleitet werden.
Fensterfunktionen werden in dem Augenblick fr Fensterklassen definiert, in dem die Fensterklasse mit der Funktion RegisterClass registriert wird. Eine gewhnliche Fensterfunktion enthlt eine switch-Anweisung mit einem Bedingungsblock fr alle Nachrichten, die von der
Anwendung bearbeitet werden sollen. Andere Nachrichten werden an
die Standard-Fensterfunktion DefWindowProc oder DefDlgProc weitergeleitet.
Nachrichten knnen an eine Anwendung gesendet oder fr diese hinterlegt werden. Hinterlegte Nachrichten werden in der Nachrichtenwarteschlange gespeichert und dort von GetMessage oder PeekMessage
ausgelesen. Das Senden einer Nachricht ruft unmittelbar die Fensterfunktion auf und umgeht auf diese Weise die Nachrichtenwarteschlange und Nachrichtenschleifen.
Eine Anwendung kann ber mehrere Nachrichtenschleifen verfgen.
Es ist jedoch nicht erforderlich, mehr als eine Schleife zu verwenden.
Diese Vorgehensweise dient lediglich einem gut strukturierten, bersichtlichen Programmcode.

147

Fenster, Dialogfelder
und Steuerelemente

Kapitel
E

in Windows-Fenster wird als rechteckiger Bereich auf dem Bildschirm definiert. Diese Definition informiert nicht ber das Potential der Funktionalitt, die sich hinter der abstrakten Vorstellung von
einem Fenster verbirgt. Ein Fenster ist die primre Einheit, ber die ein
Anwender und eine Windows-Anwendung interagieren.
Ein Fenster ist nicht nur ein Bereich, in dem Anwendungen Ihre Ausgabe darstellen. Es ist das Ziel der Ereignisse und Nachrichten innerhalb der Windows-Umgebung. Obwohl das Windows-Fensterkonzept
bereits einige Jahre vor den ersten objektorientierten Programmiersprachen definiert wurde, ist seine Terminologie zeitgem. Die Eigenschaften eines Fensters bestimmen dessen Aufbau, whrend die Methoden definieren, wie es auf die Eingabe des Anwenders oder auf
andere Systemereignisse reagieren soll.
Ein Fenster wird durch einen Handle identifiziert. Dieser Handle (gewhnlich eine Variable vom Typ HWND) bezeichnet eindeutig jedes Fenster im System. Dazu zhlen die Anwendungsfenster, Dialogfelder, der
Desktop, bestimmte Symbole und Schaltflchen. Benutzerschnittstellen-Ereignisse werden mit dem entsprechenden Handle in WindowsNachrichten abgelegt und anschlieend an die das Fenster besitzende
Anwendung (respektive an den Thread, um przise zu sein) gesendet
oder fr diese hinterlegt.
Windows bietet sehr viele Funktionen zum Erstellen und Verwalten von
Fenstern.

150

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

9.1

Die Fensterhierarchie

Windows ordnet Fenster in einer hierarchischen Struktur an. Jedem


Fenster ist ein Fenster bergeordnet (das Parent- oder Elternfenster).
Mehrere Fenster knnen sich auf einer Gliederungsstufe befinden. Die
Grundlage aller Fenster bildet der Desktop, der nach dem WindowsStart generiert wird. Das bergeordnete Fenster von Top-Level-Fenstern ist somit das Desktop-Fenster. Das bergeordnete Fenster eines
untergeordneten Fensters (Child-Fenster oder Dokumentfenster) ist
entweder ein Top-Level-Fenster oder ein anderes Child-Fenster, das
sich auf einer hheren Hierarchiestufe befindet. Abbildung 9.1 stellt
diese Hierarchie an einem gewhnlichen Windows-Bildschirm dar.
Abbildung 9.1:
Die Hierarchie
der Fenster

Desktopfenster

bergeordnet
bergeordnet

gleichgeordnet
Anwendungsfenster
(berlappend)
Besitzer
bergeordnet

Dialog Box (popup)


bergeordnet
Button

Button

Clientfenster
(untergeordnet)

Die Windows-NT-Hierarchie ist ein wenig komplexer, da dieses Betriebssystem mit mehreren Desktops gleichzeitig arbeiten kann.
Windows NT verwendet gewhnlich drei Desktops, fr den Anmeldebildschirm, fr die Anwender-Anwendungen sowie fr Bildschirmschoner.
Die sichtbare Fensterhierarchie gibt gewhnlich die logische Hierarchie wieder. Diese ordnet die Fenster derselben Gliederungsebene in
deren Z-Reihenfolge an. Die Z-Reihenfolge ist die Reihenfolge, in der
Fenster einer Gliederungsebene geffnet wurden. Diese Anordnung

Die Fensterhierarchie

kann fr Top-Level-Fenster verndert werden. Top-Level-Fenster mit


dem erweiterten Fensterstil WM_EX_TOPMOST werden ber allen anderen
Top-Level-Fenstern angeordnet.
Ein Top-Level-Fenster kann ein anderes Top-Level-Fenster besitzen.
Ein Fenster, das einem anderen Fenster gehrt, wird immer ber diesem angeordnet und dann geschlossen, wenn sein Besitzer auf Symbolgre verkleinert wird. Ein bezeichnendes Beispiel fr ein Top-Level-Fenster, das ein anderes Fenster besitzt, ist eine Anwendung, die
einen Dialog darstellt. Das Dialogfeld ist kein untergeordnetes Fenster
(es ist nicht an den Client-Bereich des Hauptfensters gebunden), aber
es ist in dem Besitz des Anwendungsfensters.
bergeordnete Fenster

Aktive bergeordnete Fenster knnen


nicht von anderen Fenstern berlappt
werden (auer diese haben den erweiterten Fensterstil WM_EX_TOPMOST).
Hauptfenster von Anwendungen und
Dialogfenster sind bergeordnete Fenster.

Untergeordnete Fenster

Untergeordnete Fenster knnen nur im


Client-Bereich ihres bergeordneten
Fensters angezeigt werden.
Untergeordnete Fenster knnen nicht
ohne ihr bergeordnetes Fenster existieren.
Clientfenster sind untergeordnete Fenster; Hauptfenster sind dem Desktop untergeordnet.

Zugeordnete Fenster

Besitzt ein Fenster andere Fenster, werden diese zusammen mit ihrem Besitzer
geschlossen.

Dialoge sind zugeordnete Fenster.


Die Fensterhierarchie durchsuchen
Verschiedene Funktionen ermglichen die Suche nach einem bestimmten Fenster in der Fensterhierarchie. Nachfolgend finden Sie
eine bersicht ber einige der berwiegend verwendeten Funktionen:

151

152

Tabelle 9.1:
Suchfunktionen
fr Fenster

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

Funktion

Beschreibung

GetDesktopWindow

Ermittelt den Handle des aktuellen Desktop-Fensters.

EnumWindows

Fhrt alle Top-Level-Fenster auf. Eine benutzerdefinierte Funktion wird einmal fr jedes Top-Level-Fenster aufgerufen. Die Adresse der Funktion wird der
Funktion EnumWindows bergeben. Top-Level-Fenster, die nach dem Aufruf der Funktion erstellt wurden, werden nicht aufgefhrt. Ein neues Fenster wird
auch dann nicht aufgefhrt, wenn es whrend der Erstellung der Auflistung erzeugt wurde.

EnumChildWindows

Fhrt alle untergeordneten Fenster des angegebenen


Fensters auf, deren Handle der Funktion EnumChildWindows bergeben wird. Das Auflisten der Fenster
geschieht mit einer benutzerdefinierten Funktion, deren Adresse ebenfalls whrend des Aufrufs der Funktion EnumChildWindows angegeben wird. Die Funktion fhrt auch untergeordnete Fenster auf, die sich
von dem angegebenen Child-Fenster ableiten.
Untergeordnete Fenster, die vor ihrer Erfassung zerstrt oder nach der Auflistung erstellt wurden, werden nicht in die Liste aufgenommen.

EnumThreadWindows

Ordnet alle Fenster in einer Liste an, die der angegebene Thread besitzt. Dazu wird eine benutzerdefinierte Funktion fr jedes Fenster ausgefhrt, das der genannten Bedingung entspricht. Der Handle des
Threads und die Adresse der benutzerdefinierten
Funktion werden EnumThreadWindows als Parameter
bergeben. Die Auflistung umfat Top-Level-Fenster,
untergeordnete Fenster und deren Ableitungen.
Fenster, die nach der Auflistung erstellt wurden, werden nicht erfat.

FindWindow

Sucht das Top-Level-Fenster, dessen Fensterklassenname oder Fenstertitel der Funktion bergeben wird.

GetParent

Ermittelt das bergeordnete Fenster des angegebenen Fensters.

GetWindow

Diese Funktion bietet eine flexible Mglichkeit zur


Manipulation der Fensterhierarchie. Abhngig davon, welcher Wert mit dem zweiten Parameter uCmd
bergeben wurde, kann diese Funktion verwendet
werden, um den Handle eines bergeordneten, besitzenden, untergeordneten oder gleichgestellten Fensters zu ermitteln.

Fensterverwaltung

9.2

Fensterverwaltung

Gewhnlich kann eine Anwendung ein Fenster in zwei Schritten erstellen. Zuerst wird die Fensterklasse registriert, und anschlieend das Fenster selbst. Dazu wird die Funktion CreateWindow aufgerufen. Die Fensterklasse bestimmt das Verhalten des neuen Fenstertyps und enthlt
die Adresse der neuen Fensterfunktion. Mit CreateWindow steuert die
Anwendung einige Eigenschaften des neuen Fensters, wie z.B. dessen
Gre, Position und Aufbau.

9.2.1

Die Funktion RegisterClass und die Struktur


WND-CLASS

Eine neue Fensterklasse wird mit dem folgenden Aufruf registriert:


ATOM RegisterClass(CONST WNDCLASS *lpwc);

Der einzige Parameter dieser Funktion, lpwc, verweist auf eine Struktur
vom Typ WNDCLASS, die den neuen Fenstertyp beschreibt. Der Rckgabewert ist vom Typ atom, ein 16-Bit-Wert, der eine Zeichenfolge in einer Windows-Tabelle bezeichnet.
Die WNDCLASS-Struktur ist wie folgt definiert:
typedef struct _WNDCLASS {
UINT
style;
WNDPROC lpfnWndProc;
int
cbClsExtra;
int
cbWndExtra;
HANDLE hInstance;
HICON
hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS;

Die Bedeutung einiger Parameter ist unmiverstndlich:


hIcon

Nimmt den Handle des Symbols auf, das


zur Darstellung des auf Symbolgre verkleinerten Fensters dieser Klasse verwendet wird.

hCursor

Ist der Handle des Standard-Mauszeigers, der dargestellt werden soll, wenn
die Maus auf das Fenster bewegt wird.

hbrBackground

Nimmt den Handle des GDI-Pinsels auf,


der zum Zeichnen des Fensterhintergrunds benutzt wird.

153

154

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

lpszMenuName

Die Zeichenfolge, auf die lpszMenuName


verweist, bezeichnet die Men-Ressource
(ber den Namen oder ber das Makro
MAKEINTRESOURCE mit einem Integer-Bezeichner), die das Standardmen dieser
Klasse bildet.

lpszClassName

Nimmt die Bezeichnung der Klasse auf.

CbClsExtra,cbWndExtra

Die Parameter cbClsExtra und cbWndExtra reservieren zustzlichen Speicher fr


die Fensterklasse oder fr einzelne Fenster. Anwendungen knnen diesen zustzlichen Speicher nutzen, um spezifische
Anwendungsinformationen
zu
speichern, die sich auf die Fensterklasse
oder ein einzelnes Fenster beziehen.

Die ersten beiden Parameter werden bewut zuletzt erlutert. Die Eigenschaften, die ein Fenster als individuelle komplexe Einheit erscheinen lassen, werden ber die Fensterklasse und Fensterfunktion gesteuert.
WNDPROC lpfnWndProc
Der Parameter lpfnWndProc bestimmt die Adresse der Fensterfunktion
(siehe Kapitel 7). Diese Funktion bearbeitet jede an das Fenster gerichtete Nachricht. Sie kann die Nachrichten selbst bearbeiten oder die
Standard-Fensterfunktion DefWindowProc aufrufen. Die Funktion kann
ber jedes Ereignis benachrichtigt werden: das Verndern der Gre,
das Verschieben des Fensters, Mausereignisse, Tastaturereignisse, Anweisungen, Aufforderung zum erneuten Zeichnen, Timer- und andere
Hardware-Ereignisse usw.
Klassenstile (UINT style)
Bestimmte globale Kennzeichen der Fensterklasse werden mit Hilfe
des Klassenstilparameters style gesteuert. Dieser Parameter kann
mehrere Werte aufnehmen, die mit dem logischen ODER-Operator (|)
verknpft werden.

155

Fensterverwaltung

Stil

Beschreibung

CS_BYTEALIGNCLIENT

Bestimmt beispielsweise, da der Client-Bereich eines Fensters immer an der Byte-Begrenzung der auf
dem Bildschirm dargestellten Bitmap positioniert
wird, um die Grafik-Performance zu erhhen (vor allem dann, wenn Sie leistungsfhige Anwendungen
fr Grafik-Hardware der unteren Leistungsklasse
schreiben).

CS_DBLCLKS

Gibt an, da Windows Doppelklick-Mausnachrichten


generieren soll, wenn der Anwender innerhalb des
Fensters einen Doppelklick ausfhrt.

CS_HREDRAW

Gewhrleistet, da das Fenster vollstndig neu gezeichnet wird, nachdem dessen horizontale Gre
verndert wurde.

CS_HREDRAW

Gewhrleistet, da das Fenster vollstndig neu gezeichnet wird, nachdem dessen vertikale Gre verndert wurde.

CS_SAVEBITS

Fhrt dazu, da Windows den Speicher reserviert,


der von Unix- und X-Programmierern gewhnlich als
Sicherungsspeicher bezeichnet wird. Dieser Speicherbereich nimmt eine Kopie der Fenster-Bitmap
auf, so da dieses automatisch erneut gezeichnet
werden kann, nachdem bestimmte Bereiche berdeckt wurden. (Der Parameter sollte nicht unberlegt
eingesetzt werden, da der erforderliche Speicherbereich sehr gro ist und daher zu Performance-Einbuen fhren kann.)

Mit der 16-Bit-Version von Windows war es mglich, die globale


Klasse einer Anwendung ber den Stil CS_GLOBALCLASS zu registrieren. Auf diese globale Klasse konnten alle anderen Anwendungen
und DLLs zugreifen. Win32 untersttzt diese Mglichkeit nicht
mehr. Damit eine Anwendung eine globale Klasse verwenden
kann, mu diese von einer DLL registriert werden, die jede Anwendung ldt. Eine derartige DLL kann ber die Registrierung definiert werden.

9.2.2

Erstellen eines Fensters mit CreateWindow

Mchten Sie ein Fenster erstellen, mssen Sie zunchst eine neue Fensterklasse registrieren. Anschlieend erzeugt die Anwendung mit Hilfe
der Funktion CreateWindow ein Fenster:

Tabelle 9.2:
Verschiedene
Klassenstile

156

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HANDLE hInstance,
LPVOID lpParam
);

Die Fensterklasse (lpClassName)


Der erste Parameter lpClassName definiert den Namen der Klasse, von
der das Fenster das eigene Verhalten ableitet. Die Klasse mu entweder mit RegisterClass registriert werden, oder eine der vordefinierten
Steuerelementklassen sein. Dazu zhlen die Klassen BUTTON, COMBOBOX,
EDIT, LISTBOX, SCROLLBAR und STATIC. Auerdem bestehen einige Fensterklassen, die berwiegend von Windows intern genutzt werden und
auf die lediglich ber Integer-Bezeichner zugegriffen werden kann. Solche Klassen stehen fr Mens, das Desktop-Fenster und Symboltitel
zur Verfgung, um nur einige zu nennen.
Fenster (dwStyle)
Der Parameter dwStyle bestimmt den Stil des Fensters. Dieser Parameter sollte nicht mit dem Klassenstil verwechselt werden, der RegisterClass ber die Struktur WNDCLASS whrend der Registrierung der neuen
Fensterklasse bergeben wird.
C Der Klassenstil bestimmt einige fixe Eigenschaften der Fenster, die
sich auf die Fensterklasse beziehen.
C Der Fensterstil hingegen wird CreateWindow bergeben, um die variablen Eigenschaften des Fensters zu definieren. dwStyle kann beispielsweise verwendet werden, um zu bestimmen, wie das Fenster
nach dem ersten Aufruf dargestellt werden soll (minimiert, maximiert, sichtbar oder versteckt).
Wie der Klassenstil, ist auch der Fensterstil eine Kombination einiger
Werte (die mit dem bitweisen ODER-Operator verknpft werden). Zustzlich zu den allgemeinen Stilwerten, die fr alle Fenster gleich sind, bestehen einige spezifische Werte fr die vordefinierten Fensterklassen.
Der Stil BX_PUSHBUTTON kann beispielsweise fr Fenster der Klasse BUTTON verwendet werden, die WM_COMMAND-Nachrichten an die bergeordneten Fenster senden, wenn die Schaltflche bettigt wird.

Fensterverwaltung

Auswahl verschiedener dwStyle-Werte


WS_OVERLAPPED

Spezifizieren ein Top-Level-Fenster. Ein WS_OVERLAPPED-Fenster wird immer mit einem Titel dargestellt. berlappte Fenster werden gewhnlich als
Hauptfenster einer Anwendung verwendet.
Spezifizieren ein Top-Level-Fenster. Ein WS_POPUPFenster braucht keine Titelzeile. Pop-up-Fenster
werden gewhnlich als Dialogfelder eingesetzt.

WS_POPUP

Wenn ein Top-Level-Fenster erstellt wird, richtet


die aufrufende Anwendung das bergeordnete
(oder besitzende) Fenster ber den Parameter
hwndParent ein. Das bergeordnete Fenster eines
Top-Level-Fensters ist das Desktop-Fenster.
WS_CHILD

Untergeordnete Fenster werden mit dem Stil


WS_CHILD erstellt. Der wesentliche Unterschied zwischen einem untergeordneten und einem Top-Level-Fenster besteht darin, da ein Child-Fenster lediglich in dem Clientbereich des bergeordneten
Fensters dargestellt werden kann.

Kombinationen

Windows definiert einige Stilkombinationen, die


zum Erstellen gewhnlicher Fenster sehr ntzlich
sind. Der Stil WS_OVERLAPPEDWINDOW kombiniert den
Stil WS_OVERLAPPED mit WS_CAPTION, WS_SYSMENU,
WS_THICKFRAME, WS_MINIMIZEBOX und WS_MAXIMIZEBOX,
um ein charakteristisches Top-Level-Fenster zu erzeugen. WS_POPUPWINDOW kombiniert zur Darstellung
eines gewhnlichen Dialogfelds WS_POPUP mit
WS_BORDER und WS_SYSMENU.

9.2.3

Erweiterte Stile und die Funktion CreateWindowEx

Die Funktion CreateWindowEx spezifiziert im Vergleich zur Funktion


CreateWindow eine Kombination erweiterter Fensterstile. Erweiterte
Fensterstile ermglichen eine detaillierte Steuerung des Fensteraufbaus
und der Funktionsweise des Fensters.
Mit Hilfe des Stils WS_EX_TOPMOST kann eine Anwendung beispielsweise
ein Fenster ber allen anderen Fenstern darstellen lassen. Ein Fenster,
dem der Stil WS_EX_TRANSPARENT zugewiesen ist, verdeckt niemals andere
Fenster und erhlt lediglich dann eine WM_PAINT-Nachricht, wenn
alle unter diesem Fenster angeordneten Fenster aktualisiert wurden.

157

158

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

Andere erweiterte Fensterstile beziehen sich auf Windows 95/98 sowie auf die unterschiedlichen Versionen von Windows NT ab Version
3.51. So kann Windows NT 3.51 mit der Windows-95/98-Oberflche
installiert werden. Der Stil WS_EX_TOOLWINDOW wird beispielsweise zur Erstellung eines Symbolleistenfensters verwendet. Ein Symbolleistenfenster verfgt ber eine schmalere Titelzeile. Die Eigenschaften eines
derartigen Fensters sind auf dessen Einsatz als frei bewegbare Symbolleiste ausgerichtet.
Eine weitere Gruppe spezifischer Windows-95/98-Stile bestimmt das
Verhalten eines Fensters hinsichtlich der verwendeten Sprache. Die
Stile WS_EX_RIGHT, WS_EX_RTLREADING und WS_EX_LEFTSCROLLBAR knnen
beispielsweise zusammen mit einer von rechts nach links ausgerichteten Sprache, wie Hebrisch oder Arabisch, verwendet werden.

9.3

Zeichnen der Inhalte eines


Fensters

Das Zeichnen in ein Fenster geschieht mit GDI-Zeichenfunktionen.


Anwendungen ermitteln die Zugriffsnummer des Anzeige-Gertekontextes mit einer Funktion, wie GetDC. Anschlieend ruft die Anwendung
GDI-Funktionen auf, wie z.B. LineTo, Rectangle oder TextOut.
Ein Fenster wird neu gezeichnet, nachdem die Nachricht WM_PAINT
empfangen wurde.

9.3.1

Die Nachricht WM_PAINT

Die Nachricht WM_PAINT wird einem Fenster gesendet, wenn Bereiche


desselben erneut von der Anwendung gezeichnet werden mssen. Auerdem darf keine andere Nachricht in der Nachrichtenwarteschlange
des Threads enthalten sein, der das Fenster besitzt. Anwendungen reagieren auf diese Nachricht mit einigen Zeichenanweisungen, die in den
Funktionen BeginPaint und EndPaint eingeschlossen sind.
Die Funktion BeginPaint nimmt einige Parameter entgegen, die in der
Struktur PAINTSTRUCT gespeichert sind:
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;

Zeichnen der Inhalte eines Fensters

BeginPaint lscht den Hintergrund, sofern dies erforderlich ist, indem


die Funktion der Anwendung die Nachricht WM_ERASEBKGND sendet.

Die Funktion BeginPaint sollte lediglich dann aufgerufen werden,


wenn eine WM_PAINT-Nachricht empfangen wurde. Jedem Aufruf von
BeginPaint mu ein Aufruf von EndPaint folgen.
Anwendungen knnen den hDC-Member der Struktur verwenden, um
in den Client-Bereich des Fensters zu zeichnen. Der rcPaint-Member
reprsentiert das kleinste Rechteck, das alle Bereiche des Fensters umschliet, die aktualisiert werden mssen. Sie beschleunigen den Zeichenproze, indem Sie die Aktivitten der Anwendung auf diesen
rechteckigen Bereich begrenzen.

9.3.2

Erneutes Zeichnen eines Fensters durch Lschen


des Inhalts

Die Funktionen InvalidateRect und InvalidateRgn lschen den gesamten Fensterinhalt oder einige Bereiche des Inhalts. Windows sendet einem Fenster die Nachricht WM_PAINT, wenn dessen zu aktualisierender
Bereich nicht leer ist, und wenn fr den Thread, der das Fenster besitzt,
keine Nachrichten mehr in der Nachrichtenwarteschlange vorhanden
sind. Der zu aktualisierende Bereich ist die Menge aller zu aktualisierenden Bereiche, die in den vorherigen Aufrufen von InvalidateRect und
InvalidateRgn spezifiziert wurden.
Diese Vorgehensweise ist ein sehr effizienter Mechanismus fr Anwendungen, die Bereiche ihres Fensters aktualisieren mssen. Das Fenster
wird nicht sofort aktualisiert. Statt dessen wird zunchst der entsprechende Bereich gelscht. Whrend der Bearbeitung der WM_PAINTNachrichten knnen die Anwendungen den zu aktualisierenden Bereich berprfen (der rcPaint-Member der Struktur PAINTSTRUCT) und lediglich die Elemente im Fenster aktualisieren, die in diesem Bereich
angeordnet sind.

159

160

Kapitel 9: Fenster, Dialogfelder und Steuerelemente

9.4

Fensterverwaltungsnachrichten

Ein gewhnliches Fenster reagiert, abgesehen von der WM_PAINT-Nachricht, auf viele weitere Nachrichten.
Tabelle 9.3:
Fensterverwaltungsnachrichten

Nachricht

Beschreibung

WM_CREATE

Die erste Nachricht, die eine Fensterfunktion eines neu erstellten Fensters erhlt. Diese Nachricht wird versendet, bevor das Fenster sichtbar ist und die Ausfhrung der Funktionen CreateWindow und CreateWindowEx beendet ist.
Die Anwendung kann auf diese Nachricht reagieren, indem
sie einige initialisierende Funktionen ausfhrt, bevor das
Fenster angezeigt wird.

WM_DESTROY

Wird an ein Fenster gesendet, das bereits von dem Bildschirm entfernt wurde und nun zerstrt werden kann.

WM_CLOSE

Gibt an, da ein Fenster geschlossen werden soll. Die Standardimplementierung in DefWindowProc ruft DestroyWindow auf, wenn diese Nachricht eingeht. Anwendungen knnen beispielsweise einen Besttigungsdialog anzeigen und
DestroyWindow nur dann aufrufen, wenn der Anwender das
Schlieen des Fensters besttigt.

WM_QUIT

Gewhnlich die letzte Nachricht, die das Hauptfenster einer Anwendung erhlt. Nach dieser Nachricht gibt GetMessage 0 zurck, woraufhin die Nachrichtenschleifen der meisten Anwendungen verlassen werden.
Diese Nachricht weist darauf hin, da die Anwendung beendet werden kann. Sie wird nach einem Aufruf von PostQuitMessage generiert.

WM_QUERYENDSESSION

Benachrichtigt die Anwendung, da die Windows-Sitzung


beendet wird. Eine Anwendung kann FALSE als Antwort auf
diese Nachricht zurckgeben, um das Herunterfahren des
Systems zu verhindern. Nachdem die Nachricht
WM_QUERYENDSESSION bearbeitet wurde, sendet Windows allen Anwendungen die Nachricht WM_ENDSESSION mit den
Ergebnissen der vorangegangenen Bearbeitung.

Fensterverwaltungsnachrichten

Nachricht

Beschreibung

WM_ENDSESSION

Wird an die Anwendungen gesendet, nachdem die Nachricht WM_QUERYENDSESSION bearbeitet wurde. Die Nachricht
zeigt an, ob Windows heruntergefahren wird oder ob das
Herunterfahren abgebrochen wurde.
Steht das Herunterfahren unmittelbar bevor, kann die Windows-Sitzung zu jeder Zeit nach Bearbeitung der Nachricht
WM_ENDSESSION durch alle Anwendungen beendet werden. Es ist daher wichtig, da jede Anwendung alle Aufgaben ausfhrt, bevor Windows heruntergefahren wird.

WM_ACTIVATE

Zeigt an, da ein Top-Level-Fenster aktiviert oder deaktiviert wird. Die Nachricht wird zunchst zu einem Fenster
gesendet, das aktiviert werden soll. Ein Fenster, das deaktiviert werden soll, erhlt die Nachricht zuletzt.

WM_SHOWWINDOW

Wird gesendet, wenn ein Fenster versteckt oder angezeigt


werden soll. Sie verstecken ein Fenster, indem Sie die
Funktion ShowWindow aufrufen oder die Gre eines anderen Fensters maximieren.

WM_ENABLE

Wird an ein Fenster gesendet, wenn der Zugriff auf dieses


freigegeben oder gesperrt wird. Der Zugriff auf ein Fenster
wird mit einem Aufruf der Funktion EnableWindow freigegeben oder gesperrt. Ein gesperrtes Fenster kann keine Eingaben von der Maus oder Tastatur entgegennehmen.

WM_MOVE

Zeigt an, da die Position eines Fensters verndert wurde.

WM_SIZE

Zeigt an, da die Gre eines Fensters verndert wurde.

WM_SETFOCUS

Zeigt an, da ein Fenster fokussiert wurde. Eine Anwendung kann beispielsweise die Schreibmarke darstellen,
nachdem sie diese Nachricht erhalten hat.

WM_KILLFOCUS

Zeigt an, da ein Fenster den Fokus verliert. Stellt eine Anwendung eine Schreibmarke dar, sollte diese zerstrt werden, nachdem die Nachricht erhalten wurde.

WM_GETTEXT</