Achtung! Hier werden lediglich einige Betriebssystem-Aspekte wiederholt ( vorrangig wird auf die Veranstaltung Betriebssysteme hingewiesen )!
Ein Computer-Hardwaresystem besteht aus Mikroprozessoren, Chips, Uhren, Schaltungen, Eingabegeräten, Tastatur, Maus, Laufwerk; Ausgabegeräten, Bildschirm, Plattenlaufwerken; Peripheriegeräten, Drucker, Modem, Netzwerkkomponenten und weiteren Komponenten.
Moderne Prozessoren können eine aufwendige Architektur haben:Ein Betriebssystem ( Operating System, Systemsoftware, Basisprogramme ) besteht aus Software mit Basisroutinen für die Hardware - Ansteuerung und die Hardware - Resourcen - Verwaltung. Ein Betriebssystem erfüllt 2 Aufgaben:
Die Betriebssystem - Architektur ( Instruktionssatz der zentralen Verarbeitungseinheit, der Speicher- organisation, Ein/Ausgabe auf Platten und Disketten, Bildschirm ) erfordert die (schwierige) Programmierung der Kontrollerbausteine. Diese Maschinen - Programme, wie Unterbrechungen ( interrupt ), Zeitgeber ( timer ) und die Speicherverwaltung ( memory management ) sind in den BIOS enthalten. Für den Anwender ist die Benutzung dieser Programmteile einfacher, als die direkte Programmierung der zugrundeliegende Hardware. Für den Anwender verhaelt sich das Betriebssystem wie eine Virtuelle Maschine.
Wenn auf einem Computer mehrere Benutzer gleichzeitig arbeiten wollen, entsteht die Notwendigkeit, Speicher, Ein-/Ausgabegeraete und andere ( teure ) Komponenten zu verwalten und zu sichern. Aus dieser Sicht hat das Betriebssystem die Aufgabe, festzustellen, wer welche Resourcen verwendet, Resourcen auf Anforderung zu gewaehren, Unterbrechungens - Informationen zu sammeln und zwischen den gegenseitig sich überschneidenden Anforderungen mehrerer Benutzer oder Programme zu vermitteln.
Die Software - Schichten:
Die Punkte 1, 2, 3 werden auch zu einer Hardware - Schicht zusammengefaßt. Die Punkte 4, 5 bilden die Systemprogramme. Zu den Applikationen ( Anwendungsprogrammen 6 ) gehören Datenbanken, CAD, Spiele, Banksystem, Simulatoren, usw. ).
Etwa 1980 hat Jim Paterson (ausgehend vom CP/M-80) ein 6 KB umfassendes Betriebssystem QDOS (Quick and Durty Operating System) entwickelt. IBM wollte eine neue 16-Bit-Maschine auf Intel-Basis auf den Markt bringen. Mircosoft übernahm Jim Paterson und entwickelte MS-DOS unter strenger Geheimhaltung die Version 1.0 (1981). 1983 war die Version 2.0 ( hierarchisches Dateisystem mit 9 Sektoren für 360 kB Laufwerke, installierbare Geraetetreiber, Bildschirmtreiber ANSI.SYS, Backgroundprozessing ). 1984 entstand für den PC-AT die Version 3.0 ( Netzwerk, 20 MB Festplatte, 1.2 MB Diskettenlaufwerke, Verbesserungen der Ausführungszeiten ).
Der interne Aufbau des DOS - Kerns
DOS-BIOS ( : ROM) DOS-Kern ( I/O : IBMDOS.COM) Kommandoprozessor (Shell: COMMAND.COM)
Unter DOS ausführbare DOS-Programme sind z.B. *.EXE und *.COM. *.COM-Programme können maximal 64 KB Code enthalten. Beim Laden von *.EXE Programmen werden die absoluten Speicher- bezüge angepasst.
Nach dem Einschalten wird geprüft ob im Laufwerk A: (falls leer dann B:, dann C:, usw.) eine Diskette ist. Der Boot-Sektor wird automatisch geladen, die Boot-Routine wird ausgeführt und IBMBIO.COM und IBMDOS.COM geladen. Nun wird die Datei CONFIG.SYS gesucht und die in CONFIG.SYS enthaltenen Treiber werden geladen (DEVICE-Befehl). Dadurch wird der Kern des Betriebssystems zusammengebaut (SYStem CONFIGurieren). Dann wird der Kommando- prozessor (COMMAND.COM) geladen, der automatisch die in
Beim Starten von DOS wird zuerst die Datei CONFIG.SYS (Gerätetreiber) und dann die Datei AUTOEXEC.BAT abgearbeitet. Die in AUTOEXEC.BAT enthaltenen *.COM- und *.EXE-Programme der Reihe nach ausführt. *.Bat steht für eine BATch-Job-Stapeldatei.
Achtung! Das folgenden Beispiele ( DOS 5.0 ) können nicht kritiklos übernommen werden!
Beispiel für CONFIG.SYS:
shell =c:\dos\command.com c:\dos\ /e:256 /p country=49,,c:\dos\country.sys device =c:\dos\himem.sys device =c:\dos\emm386.exe 2048 noems dos=high,umb lastdrive = g files =30 buffers=15 dh =c:\dos\smartdrv.sys 2048 1024 dh =c:\dos\ansi.sys dh =c:\dos\ramdrive.sys 1024 /e install=c:\dos\share.exe | Beispiel für AUTOEXEC.BAT:
@ECHO OFF set comspec=c:\dos\command.com path C:\DOS;c:\bc\bin; append=c:\dos in not "%prompt%"=="" goto ende prompt $p$g lh keyb gr lh c:\dos\mouse.com nc :ende |
Wesentliche Teile des MS-Dos-Betriebssystem werden über eine Interrupt-Adress-Tabelle abgewickelt. Diese Tabelle beginnt bei der Speicher-Adresse 0 und enthält 256 Adressen. Jeder Adress-Eintrag verwendet 4 Byte. Wird ( durch ein Gerät ) dem Interrupt-Controller-Baustein ein Hardware - Interrupt angezeigt, so legt das Gerät danach den Tabelle-Index auf den Datenbus. Der Tabelle wird dann die Ziel-Adresse entnommen. Ab der Zielstelle wird das unterbrechende Programm ( ähnlich einem Unterprogramm ) ausgeführt.
Bei einem Software-Interrupt ( z.B. INT 21h ) enthält der INT-Maschinen-Befehl bereits den Tabellen-Index. Ab der Zielstelle wird das unterbrechende Programm ( ähnlich einem Unterprogramm ) ausgeführt.
Speicher-Bild:
+-----------------------------------+
| |
↑ ↓
Tabellen- |----|----|----| ... |----|----|----| ... |----|-- ... -------------
Index 0. 1. 2. 33. 34. 35. 255. Zielstelle
Wesentliche Teile des MS-Dos-Betriebssystem werden über eine Interrupt-Adress-Tabelle abgewickelt. Dadurch ergeben sich die folgenden Vorteile: Wird das Betriebssystem verbessert oder erweitert, so wird der Maschinencode an der Zielstelle geändert. Die Folge der Adressen an den Zielstellen verschieben sich. Wenn Anwendungsprogramme die direkte Adresse der Zielstelle verwenden würden, so müßten bei jeder Betriebssystemänderung alle Anwendungsprogramme angepaßt werden. Wenn ein Anwendungsprogramm Funktionen des Betriebssystems verwendet, so wird lediglich den Index der Interrupt - Tabelle benutzt ( z.B. INT 21h ). Dadurch funktionieren die alten Anwendungsprogramme auch unter einer neueren Version des Betriebssystems.
UNIX ist ein Mehrprogrammsystem. Die einzigen aktiven Einheiten in einem UNIX-System sind die ( sequeltiellen ) Prozesse. Jeder Prozess hat einen eigenen Programmzähler. Viele Prozesse laufen im Hintergrund ( Dämon, z.B.Terminplanung mit cron ).
Nachdem Ken Thomson aus dem MIT - Projekt ( MULTiplexed Information and Computing Service, PL/I ) verlassen hatte, schrieb er auf der PDP-7 ein kleineres Betriebssystem UNICS ( UNiplexed Information and Computing Service, kastriertes MULTICS, späterer Name UNIX ). Die Übertragung des gesamten Assembler - Codes auf PDP-11/20, PDP-11/45, PDP-11/70 war schwierig. Deshalb wurde ein Programmiersprache B ( vereinfachtes BCPL, stark vereinfachtes PL/I ) entwickelt. B hatte keine Strukturen. Dennis Ritchie erweiterte B zu C.
Um das Betriessystem auf einen neuen Computer zu übertragen wurde zunächste ( mit mittleren Aufwand ) der C - Compiler portiert. Die meisten Software - Anteile konnten dann übernommen werden. Der Quellcode wurde kostenlos an Universitäten abgegeben.
C wurde die Sprache der Systemprogrammierung.
Ausgehend von der typenlosen Sprache BCPL wurde die Programmiersprache C von Ken Thomson und Dennis Ritchie bei den Bell Laboratories auf einer PDP-11 entwickelt. Das Betriebssystem UNIX ist weitgehend in C geschrieben. UNIX Ver. 6 ist zu 95% in C geschrieben. C ist eine einfache und universelle Programmiersprache, die auch bei Mikrocontrollern als Assembler-Ersatz verwendbar ist. C ist heute i.a. die erste hoehere Programmiersprache, die auf einem neuen Computer, Microcomputers, Minicomputers oder Mainframe laeuft. Wir wollen immer zwischen der Programmiersprache C und den Bibliotheken unterscheiden. Bibliotheken enthalten eingebaute Funktionen und Dienstleistungen. Bei Projekten werden solche Bibliotheken mit Hilfe eines C-Compilers oft selbst erstellt (z.B. Window-, Grafik-, Device-Bibliotheken). 1988 wurde ANSI-C X3J11 genormt.
C ist für Programmier-Anfaenger wegen der cryptischen-Schreibweise nicht so einfach wie z.B. BASIC. Mit C kann man flexibel bis auf Betriebssystem- und Maschinenebene programmieren. Anders als z.B. bei OBERON gilt:Die Verantwortung beim Programmieren mit C ( C++ ) liegt stets beim Programmierer!
Die Universität Kalifornia in Berkeley nutzte den C - Quellcode und entwickelte eigene UNIX-Erweiterungen ( vi, csh, Compiler für Pascal und Lisp, usw. ). Sun baute auf dem Berkeley-Unix auf. Es gab unterschiedliche Unix-Normungsgremien z.B. AT&T SVID ( System V Interface Definition ), BSD ( Berkeley Sooftware Distribution ), IEEE POSIX 1003.1 ( Portaples Operating System ). OSF ( IBM und weitere, Open Software Foundation, starke Erweiterungen X11, MOTIF, DCE, DME ), UI ( AT&T und weitere, Unix International ).
Für UNIX hat sich die sogenannte Mach Gruppe schon frühzeitig bemüht, einen Kernel weiter zu entwickeln, der die folgenden Eigenschaften vereint:
Windows ist überwiegend in ANSI - C geschrieben. Einige wenige zeitkritische Teile des Betriebssystem - Kerns für die Hardware Abstraktions Layer ( HAL ) sind in Assembler - Code geschrieben. Das Betriebssystem ist modular. Bei Bedarf werden die benötigten Teile ( DLL's ) geladen/entfernt.
Es gibt verschiedene Windows-Betriebssysteme:
1985 MS präsentiert Windows 1.01; 1987 Windows 2; 1987 OS/2 von IBM / MS, zeichenorientiert 1988 OS/2 von IBM/MS mit grafischer Oberfläche 1990 Windows 3.0 ( 16 Bit ) erscheint und wird ein großer Erfolg ( Trennung IBM – MS ). Im Oktober startet die Inmarsat-Organisation eigene Satelliten für die maritime Kommunikation. In den USA nimmt der erste kommerzielle Internet-Provider den Dienst auf. Unter Federführung der Bundespost entsteht der Treiber-Standard CAPI 1.1 für ISDN-Karten. James Gosling und Bill Joy beginnen mit der Entwicklung der Programmiersprache Java; 1992 Windows 3.1; 1993 Windows 3.11; 1993 Windows NT ( Windows New Technology, 32-Bit-Betriebssystem, für Workstations Windows NT 3.1, für Windows NT 3.1 Advanced Server und Netzwerke ); 1996 Windows NT 3.5, und Windows NT 4.0, Sicherheit, Erweiterbarkeit, Stabilität und Skalierbarkeit, zentrale Administration, NT-Server tritt in Konkurrenz zu Novell, Banyan oder UNIX 1995 Windows 95, ( unterstützt 32-Bit-Anwendungen und die so genannte Plug-and-Play-Technologie, mitgeliefert wurde der Internet-Browser Internet Explorer, für Heimmarkt = Small Office/Home Office; 1998 Windows 98 ( Update für Windows 95, Active Desktop bindet den Webbrowser Internet Explorer, unterstützt werden: FAT32, DVD- und MMX-Technologie, AGP (siehe Graphikkarte) USB-Anschlüsse ( Universal Serial Bus ), AGP ( Accelerated Graphics Port, 1997 Intel, direkte Verbindung von der Grafikkarte zum Prozessor sowie zum Arbeitsspeicher, Taktfrequenz 66 MHz, AGP 1X = 266 MByte/s, AGP 2X = 533 MByte/s, AGP 4X = 1066 MByte/s, Pipelining, 8 zusätzliche Leitungen, DIME-Auslagerungsmodus für Texturen ); 2000 Windows 2000 wird in 4 Zusammenstellungen ausgeliefert: Windows 2000 Professional ( für PC und Notebook ), Windows 2000 Server ( einfache Netzanwendungen ), Windows 2000 Advanced Server ( Unternehmenskritische und komplexe Netzanwendungen ) Windows 2000 Datacenter Server ( für Rechenzentren, Lagerverwaltungssysteme und Finanzsysteme ); 2001 Windows ME; 2002 Windows XP
NT-Design Ziele | NT-Server |
|
|
Wichtige Teile des Betriebssystems sind im ( privilegierten ) Executive Modus geschützt.
NT-Subsysteme | ||
Darüber hinaus stellt Windows NT eine Reihe
geschlossener Subsysteme zur Ausführung von Applikationen
zur Verfügung. Sie alle kommunizieren mit dem
darunterliegenden Betriebssystem und regeln ihre
Bildschirmausgaben über die
Windows32-Graphikschnittstelle.
| ||
NT-Objekte | NT-Objekte | NT-Objekte |
Resourcen als Objekte:
|
Ein NT-Thread:
|
Unterschiedliche Objekte sind:
|
Dateisysteme: | ||
Die von Windows NT unterstützten Dateisysteme
können parallel nebeneinander laufen.
|
Alle binär gespeicherten Informationen bestehen aus kleinen, typisierten Einheiten. Jedem Buchstaben ist z.B. ein Bitmuster zugeordnet. Text besteht z.B. aus Buchstaben und diese aus Binärcode. Maschinencode besteht z.B. aus kleinen binären Einheiten ( prozessor-spezifischen OpCode-Befehlen ). Zu einer ganzen Zahl im Speicher gehört z.B. der Umfang von Bits, eine bestimmte Art des Bit-Muster-Aufbaues ( Interpretation dieser Bits ) und die Position, bei der diese Bits im Speicher sind ( Speicheradresse, Zeiger ).
Zu jeder vorhandenen Information gehört ein Identifizierer ( physikalische RAM-Adresse, Entität, Ort der Information )
und ein Binärcode ( Bitmuster, Bedeutung, Semantik ).
Daten-Typen legen die elementare Bedeutung eines Speicher-Bit-Musters fest. Mit Daten-Typen sind sinnvolle Operationen möglich. Zu einer Programmiersprache gehören Grundtypen, die für Zeichen, Zahlen, Strukturen verwendet werden können. Strukturen und Objekte legen die elementare Bedeutung einer Kombination von Grundtypen fest.
Zahlen in wissenschaftlicher Notation bestehen aus Vorzeichen ( Sign Bit ) , Mantisse ( Significant ) und Exponent ( Biased Exponent ). Wir müssen daher bei en sehr genau zwischen der Von der Größe einer Gleitpunktzahl ( Wert des Exponenten ) ist die Darstellungsgenauigkeit ( Anzahl der gespeicherten Ziffern ) zu unterscheiden. Das Format von Gleitpunktzahlen ist in IEEE 754 ( Floating Point Standard ) festgelegt.
Es gibt die Daten-Formate:
Gleitpunktzahlen werden vielfältig benötigt ( naturwissenschaftlichen, technischen Anwendungen, Grafik, numerische Mathematik, usw. ). Wegen des Zeitbedarfes werden Fließkommaoperationen von Gleitpunktzahlen (engl. Floating Point Numbers ) in digitalen Einheiten ( Coprozessor ) ausgeführt.
Bitweise Darstellung einer double-Zahl | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
63 .. 56 | 55 .. 48 | 47 .. 40 | 39 .. 32 | 31 .. 24 | 23 .. 16 | 15 .. 8 | 7 .. 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 0 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
s | - |
e = Exponent ( -1022 ...1023 ), e0 := 1023 und 1 <= normalisierte Mantisse < 2
Beispiel:
dez 25678.34 =
= dez 2.567834*104 =
= bin 0110 0100 0100 1110.0101 0111 =
= bin 0110 0100 0100 1110. 0101 0111 =
( . um 14 Positionen verschieben, begrenzen der Mantisse auf 3 Byte: )
= bin 1.1001 0001 0011 1001 0101 11oo * 2dez 14
( e0+14 = dez 1023 + 14 = dez 1037 = bin 100 0000 1101 )
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
4 | 6 | C | 8 | 9 | C | A | E | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Eine lesbare Schrift besteht aus Schriftzeichen. Eine Repräsentation von Bildern als Zeichen wird Font genannt. Outline-Typeface ist eine Konturschrift ( Vektoren, Zeichen nur aus Umrisslinien ). TrueType-Fonts wurden von Apple und Microsoft entwickelt ( Zeichen werden füllbare Hüllkurven-Konturen ).
Bitmapped-Fonts entsprechen binären Bildern. Ein Font besteht z.B. aus einer "Bildersammlung" aus 256 einzelnen Elementen, die mit 8 Bits eindeutig identifiziert werden können ( Code, z.B. ASCII ). Der Windows-ANSI-Zeichensatz enthält 256 Zeichen. Die ersten 32 Zeichen sind Steuerbefehle. Der ANSI-Zeichensatz ist von Zeichen 32 bis Zeichen 127 mit dem ASCII-Zeichensatz identisch.
Unicode benutzt 16 Bits und kann 216 = 65536 verschieden Zeichen adressieren. Zu einem Zeichensatz gehören:
Bei der darstellung von Zeichen können diese auch dynamisch kombiniert werden ( z.B."ä" aus "a" und darüber gesetzten Doppelpunkt ).
Das Unicode-Konsortium ( gegründet 1991, Linguisten, Fachleute ) koordiniert die weltweiten Schrift-Zeichen-Standardisierungen. Zeichen-Codes sollten systemunabhängig, programmunabhängig, sprachunabhängig sein und dennoch eine Vielfalt der Zeichen-Darstellung unterstützen.
Die vergebenen Codes ( Zahl-Zeichenwert-Zuordnung ) haben verbindlichen Charakter. Das Unicode-System ( Version 2.0 ) ist eine internationale Norm ISO/IEC 10646. Das Unicode-System ist in Zahlenbereiche aufgeteilt ( ASCII, Schriftkultur, Sonderzeichen, auch noch Platz für Zukünftiges ).
Windows-Zeichen-Typen | ||||||
Generisch | TCHAR | LPTSTR | ||||
ANSI | UNICODE | ANSI | UNICODE | |||
Explizit | CHAR | WCHAR | LPSTR | LPWSTR | ||
Aufgelöst | char | wchar_t | char * | wchar_t | ||
Unicode |
Damit die generischen Typen den Unicode-Size verwenden, muß #define UNICODE ( vor den #include ) definiert sein.
ANSI-Zeichen werden auf dem Tastatur-Ziffernblock
unter Windows erzeugt durch:
[Alt]-Taste drücken und die ANSI-Nummer mit vorangestellter [0] eingeben.
Beispiel: ø = [Alt]+[0]+[2]+[4]+[8].
TCHAR.H enthält Typen für die "automatische" Anpassung von MBCS (Multi-Byte-Characters) und SBCS (Single-Byte-Characters).
Generic-text data type name |
SBCS (_UNICODE, _MBCS not defined) |
_MBCS defined |
_UNICODE defined |
---|---|---|---|
_TCHAR | char | char | wchar_t |
_TINT | int | int | wint_t |
_TSCHAR | signed char | signed char | wchar_t |
_TUCHAR | unsigned char | unsigned char | wchar_t |
_TXCHAR | char | unsigned char | wchar_t |
_T or _TEXT | No effect (removed by preprocessor) | No effect (removed by preprocessor) | L (converts following character or string to its Unicode counterpart) |
Generische Textroutinen sind: _fgetts, _fputtc, _fputts, _ftprintf, _ftscanf, _gettchar, _getts, _istascii, _istcntrl, _istgraph, _istlower, _istprint, _istpunct, _istspace, _istupper, _istxdigit, _itot, _ltot, _puttchar, _putts, _sntprintf, _stprintf, _stscanf, _tcscat, _tcschr, _tcsclen, _tcscmp, _tcscpy, _tcscspn, _tcsdup, _tcsicmp, _tcslen, _tcslwr, _tcsncat, _tcsnccat, _tcsncmp, _tcsnccmp, _tcsnccpy, _tcsncpy, _tcsncicmp, _tcsnset, _tcsncset, _tcspbrk, _tcsrchr, _tcsrev, _tcsset, _tcsspn, _tcsstr, _tcstod, _tcstok, _tcstol, _tcstoul, _tfdopen, _tfopen, _tfreopen, _totlower, _totupper, _tprintf, _tscanf, _ttoi, _ttol, _ultot, _ungettc, _vftprintf, _vsntprintf, _vstprintf, _vtprintf
printf() | verwendet char* |
_tprintf() | verwendet generische _TCHAR |
_tprintf() | kann generische _TCHAR verwenden bei #define UNICODE wird wprintf() benutzt, ohne #define UNICODE wird printf() benutzt |
#ifdef UNICODE typedef LPWSTR LPTSTR; // LPTSTR = LPWSTR typedef LPCWSTR LPCTSTR;// LPCTSTR = LPCWSTR #else typedef LPSTR LPTSTR; // LPTSTR = LPSTR unter ANSI typedef LPCSTR LPCTSTR; // LPTCSTR = LPCSTR unter ANSI #endif
LPWSTR zeigt auf einen "null-terminated Unicode-Character-Array", der keine eingebtteten Nullen enthalten darf.
"help" ist repräsentiert durch ... | |
als WSTR : | |
im memory : | |
Anders bei BSTR.
BSTR ist in der OLE 2.0-Spezifikation (ein Teil der ActiveX-Spezifikation).
Dem BSTR-Unicode-Charakter-Array wird mit 2-Null-Byte beendet.
Innerhalb des BSTR-Unicode-Charakter-Array können Null-Bytes vorkommen.
Dem BSTR-Unicode-Charakter-Array geht ein 4-byte-Längen-Feld voraus.
Das "length-field" enthält die Anzahl von Zeichen.
#ifndef UNICODE #define UNICODE #endif #include <windows.h> /* hFile möge bereits existieren ... */ TCHAR Buf[1024]; int cc = wsprintf(Buf, TEXT("\r\n hwnd=0x%08x"),hwnd); #ifdef UNICODE char buf[512]; /* ansi-Buffer */ WideCharToMultiByte(CP_ACP,0,Buf,-1,buf,sizeof(buf),NULL,NULL); cc = (cc+1)/2; fwrite(buf, sizeof(TCHAR), cc, hFile); #else fwrite(Buf, sizeof(TCHAR), cc, hFile); #endif
Ein Betriessystem wird oft mit speziellen Entwicklungswerkzeugen entwickelt und gepflegt. Neuerungen (z.B. Einführung von DLL's) ändern auch die Unterstützung durch "Standard-CPP-Compiler". CPP-Schlüsselwörter (hier MS-Keywords) sind reservierte, vordefinierte Identifizierer, die eine besondere Bedeutung haben und deshalb im eigenen C++-Quelltext nicht frei verwende werden können. Identifizierer mit führenden Underscores ("__...") sind MS-Erweiterungen.
Schlüsselwörter des CPP-Betriessystem-Compilers | |||||||
__abstract | __alignof | __asm | __assume | __based | __box | __cdecl | __declspec |
__delegate | __event | __except | __fastcall | __finally | __forceinline | __gc | __hook |
__identifier | __if_exists | __if_not_exists | __inline | __int8 | __int16 | __int32 | __int64 |
__interface | __leave | __m128 | __m128d | __m128i | __multiple_inheritance | __nogc | |
__noop | __pin | __property | __raise | __sealed | __single_inheritance | __stdcall | __super |
__try_cast | __try/__except, __try/__finally |
__unhook | __uuidof | __value | __virtual_inheritance | __w64 | |
bool | break | case | catch | char | class | const | const_cast |
continue | default | delete | deprecated | dllexport | dllimport | do | double |
dynamic_cast | else | enum | explicit | extern | false | float | for |
friend | goto | if | inline | int | |||
long | mutable | naked | namespace | new | noinline | noreturn | nothrow |
novtable | operator | private | property | protected | public | register | reinterpret_cast |
return | selectany | short | signed | sizeof | static | static_cast | struct |
switch | template | this | thread | throw | true | try | typedef |
typeid | typename | union | unsigned | using declaration, using directive |
uuid | virtual | void |
volatile | wchar_t,__wchar_t | while |
Windows verwendet zahlreiche MACROS, die in C/C++-Header-File enthalten sind. Beispiel: Windows-Header-File windowsx.h
C++ kennt main() für Program Startup and Termination und die Standard-Streams: cin ( for standard input ), cout ( for standard output ), cerr ( for unbuffered standard error output ), clog ( for buffered standard error output ).
C++ kennt die Header-Files ( bzw. subset ) : algorithm, bitset, cassert, cctype, cerrno, cfloat, ciso646, climits, clocale, cmath, complex, csetjmp, csignal, cstdarg, cstddef, cstdio, cstdlib, cstring, ctime, cwchar, cwctype, deque, exception, fstream, functional, iomanip, ios, iosfwd, iostream, istream, iterator, limits, list, locale, map, memory, numeric, ostream, queue, set, sstream, stack, stdexcept, streambuf, string, strstream, utility, valarray, vector
Unterschiedliche Maschinen haben unterschiedlich geeignete Darstellungen ( Speicherbedarf, Geschwindigkeit, Vorzeichen, Big/Little Endian, usw. ).
C++ garantiert die folgenden Relationen: 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(float) <= sizeof(double) | |
Typ | Beispiel |
Typen für Integer | |
char | entspricht bei vielen Maschinen einem 8-Bit-signed-Wert;
char t = '\t'; /* 0x09 */ char c0 = ( char ) 0x61;/* 'a' */ char *p = & c0; /* pStr -> c0 */ char c[5] = {'A', 'B', 'C'}; // 0x41 0x42 0x43 0x00 0x00 char *ptrs[5] = {"abc","ABC"}; // ptrs[0] -> 0x61 0x62 0x63 0x00 0x00 // ptrs[1] -> 0x41 0x42 0x43 0x00 0x00 // ptrs[2] == NULL // ptrs[3] == NULL // ptrs[4] == NULL char *pStr = "ABC"; // pStr -> 0x61 0x62 0x63 0x00 |
short int | entspricht signed short int vorzeichbehaftete Zahl, bei 32 Bit Maschinen meist 2 Byte; |
int | entspricht signed int;
all. darf int bei mehrfach Kombinationen weggelassen werden;
bei 32 Bit Maschinen meist sizeof(int) = 4;
int i1 = 256+255; char ch = i1;/* ch=255 */ int i2 = ch; /* i2 = -1 oder 255 */ |
long int | entspricht signed long int; bei 32 Bit Maschinen meist sizeof(long) = 4 |
Typen für Fließkommazahlen | |
float | bei 32 Bit Maschinen meist sizeof(float) = 4 |
double | bei 32 Bit Maschinen meist sizeof(double) = 8 |
long double | bei 32 Bit Maschinen meist sizeof(double) = 8 |
Typen für vorzeichenlose Integer, logische Werte, Bitfelder, usw. | |
unsigned char | entspricht bei 32 Bit Maschinen meist 1 Byte; |
unsigned short int | vorzeichenlose ganze Zahlen, bei 32 Bit Maschinen meist 2 Byte; unsigned short int shorti = -1; liefert ... |
unsigned int | vorzeichenlose ganze Zahlen, bei 32 Bit Maschinen meist 4 Byte; unsigned int ui = -1; liefert ... |
unsigned long int | vorzeichenlose ganze Zahlen, bei 32 Bit Maschinen meist 4 Byte; unsigned long l = -1; liefert ... |
Die C, C++-Prototypen von Funktionen, Macros, Datenstrukturen, usw. werden in Header-Files zusammengefaßt. Die beim Erstellen des Betriebssystems ( *.DLL's ) benutzten Header - Files werden zur Verfügung gestellt. Liegen auch die zugeordneten *.LIB - Files vor, so können die DLL - Funktionen in eigenen Applikationen eingebunden werden.
Standard C++ library headers | |||
algorithm.h | for defining numerous templates that implement useful algorithms | bitset.h | for defining a template class that administers sets of bits |
cassert.h | for enforcing assertions when functions execute | cctype.h | for classifying characters |
cerrno.h | for testing error codes reported by library functions | cfloat.h | for testing floating-point type properties |
ciso646.h | for programming in ISO 646 variant character sets | climits.h | for testing integer type properties |
clocale.h | for adapting to different cultural conventions | cmath.h | for computing common mathematical functions |
complex.h | for defining a template class that supports complex arithmetic | csetjmp.h | for executing nonlocal goto statements |
csignal.h | for controlling various exceptional conditions | cstdarg.h | for accessing a varying number of arguments |
cstddef.h | for defining several useful types and macros | cstdio.h | for performing input and output |
cstdlib.h | for performing a variety of operations | cstring.h | for manipulating several kinds of strings |
ctime.h | for converting between various time and date formats | cwchar.h | for manipulating wide streams and several kinds of strings |
cwctype.h | for classifying wide characters | deque.h | for defining a template class that implements a deque container |
exception.h | for defining several functions that control exception handling | fstream.h | for defining several iostreams template classes
that manipulate external files |
functional.h | for defining several templates that help construct
predicates for the templates defined in algorithm.h and numeric.h |
iomanip.h | for declaring several iostreams manipulators that take an argument |
ios.h | for defining the template class that serves as the
base for many iostreams classes |
iosfwd.h | for declaring several iostreams template classes
before they are necessarily defined |
iostream.h | for declaring the iostreams objects that manipulate the standard streams | iso646.h.h | for programming in ISO 646 variant character sets |
istream.h | for defining the template class that performs extractions | iterator.h | for defining several templates that help define and manipulate iterators |
limits.h | for testing numeric type properties | list.h | for defining a template class that implements a list container |
locale.h | for defining several classes and templates that
control locale-specific behavior, as in the iostreams classes |
map.h | for defining template classes that implement associative containers |
memory.h | for defining several templates that allocate and
free storage for various container classes |
new.h | for declaring several functions that allocate and free storage |
numeric.h | for defining several templates that implement useful numeric functions | ostream.h | for defining the template class that performs insertions |
queue.h | for defining a template class that implements a queue container | set.h | for defining template classes that implement
associative containers with unique elements |
sstream.h | for defining several iostreams template classes
that manipulate string containers |
stack.h | for defining a template class that implements a stack container |
stdexcept.h | for defining several classes useful for reporting exceptions | streambuf.h | for defining template classes that buffer iostreams operations |
string.h | for defining a template class that implements a string container | strstream.h | for defining several iostreams classes that
manipulate in-memory character sequences |
typeinfo.h | for defining class type_info, the result of the typeid operator | utility.h | for defining several templates of general utility |
valarray.h | for defining several classes and template
classes that support value-oriented arrays |
vector.h | for defining a template class that implements a vector container |
Ein Betriessystem ( im Gegensatz zur C++-Definition ) arbeitet mit ( exakt ) festgelegten Typen, Strukturen und Speicherabbildern.
Es gibt Zahlreiche Betriebssystemstrukturen (Interface-Funktionen, Parameterart und -folge auf Stack, Nachrichtenspezifikationen, Systemparamter, Alignment, Hardware- und Treiber-Abhängigkeiten, usw.). In der folgenden Tabelle sind Daten-Typen für Character, Integer, Boolean, Pointer und Handles enthalten. Die meisten Pointer-Typen beginnen mit dem Prefix P oder LP.
Term | Header | Description |
ATOM | Windef.h: typedef WORD ATOM; | Atom |
BOOL | Windef.h: typedef int BOOL; | Boolean variable (should be TRUE or FALSE). |
BOOLEAN | Winnt.h:typedef BYTE BOOLEAN; | Boolean variable (should be TRUE or FALSE). |
BYTE | Windef.h: typedef unsigned char BYTE; | Byte (8 bits). |
CALLBACK | Windef.h: #define CALLBACK __stdcall | Calling convention for callback functions. |
CHAR | Winnt.h: typedef char CHAR; | 8-bit Windows (ANSI) character. |
COLORREF | Windef.h: typedef DWORD COLORREF; | Red, green, blue (RGB) color value (32 bits). See |
CONST | Windef.h:#define CONST const | Variable whose value is to remain constant during execution. |
DWORD | Windef.h: typedef unsigned long DWORD; | 32-bit unsigned integer. |
DWORDLONG | Winnt.h:typedef ULONGLONG DWORDLONG; | 64-bit unsigned integer. |
DWORD_PTR | Basetsd.h: typedef ULONG_PTR DWORD_PTR; | Unsigned long type for pointer precision. Use when casting a pointer to a long type to perform pointer arithmetic. (Also commonly used for general 32-bit parameters that have been extended to 64 bits in 64-bit Windows. ) |
DWORD32 | Basetsd.h:typedef unsigned int DWORD32; | 32-bit unsigned integer. |
DWORD64 | Basetsd.h: typedef unsigned __int64 DWORD64; | 64-bit unsigned integer. |
FLOAT | Windef.h: typedef float FLOAT; | Floating-point variable. |
HACCEL | Windef.h: typedef HANDLE HACCEL; | Handle to an ACCEL-Tab |
HANDLE | Winnt.h: typedef PVOID HANDLE; | Handle to an object. |
HBITMAP | Windef.h typedef HANDLE HBITMAP; | Handle to a |
HBRUSH | Windef.h: typedef HANDLE HBRUSH; | Handle to a |
HCOLORSPACE | Windef.h if(WINVER >= 0x0400) typedef HANDLE HCOLORSPACE; | Handle |
HCONV | Ddeml.h: typedef HANDLE HCONV; | Handle to a dynamic data exchange (DDE) conversation. |
HCONVLIST | Ddeml.h: typedef HANDLE HCONVLIST; | Handle to a DDE conversation list. |
HCURSOR | Windef.h: typedef HICON HCURSOR; | Handle to a |
HDC | Windef.h :typedef HANDLE HDC; | Handle to a |
HDDEDATA | Ddeml.h: typedef HANDLE HDDEDATA; | Handle to DDE data. |
HDESK | Windef.h: typedef HANDLE HDESK; | Handle to a |
HDROP | Shellapi.h :typedef HANDLE HDROP; | Handle to an internal drop structure. |
HDWP | Winuser.h: typedef HANDLE HDWP; | Handle to a deferred window position structure. |
HENHMETAFILE | Windef.h: typedef HANDLE HENHMETAFILE; | Handle to an |
HFILE | Windef.h: typedef int HFILE; | Handle to a file opened by |
HFONT | Windef.h : typedef HANDLE HFONT; | Handle to a |
HGDIOBJ | Windef.h: typedef HANDLE HGDIOBJ; | Handle to a GDI object. |
HGLOBAL | Windef.h: typedef HANDLE HGLOBAL; | Handle to a global memory block. |
HHOOK | Windef.h: typedef HANDLE HHOOK; | Handle to a |
HICON | Windef.h: typedef HANDLE HICON; | Handle to an |
HINSTANCE | Windef.h: typedef HANDLE HINSTANCE; | Handle to an instance. |
HKEY | Windef.h: typedef HANDLE HKEY; | Handle to a registry key. |
HKL | Windef.h: typedef HANDLE HKL; | Input locale identifier. |
HLOCAL | Windef.h: typedef HANDLE HLOCAL; | Handle to a local memory block. |
HMENU | Windef.h: typedef HANDLE HMENU; | Handle to a |
HMETAFILE | Windef.h: typedef HANDLE HMETAFILE; | Handle to |
HMODULE | Windef.h: typedef HINSTANCE HMODULE; | Handle to a module. The value is the base address of the module. |
HMONITOR | Windef.h : if(WINVER >= 0x0500) typedef HANDLE HMONITOR; | Handle to a display monitor. |
HPALETTE | Windef.h: typedef HANDLE HPALETTE; | Handle to a |
HPEN | Handle to a Pen | |
HRESULT | Winnt.h: typedef LONG HRESULT; | Return code used by interfaces. It is zero upon success and nonzero to represent an error code or status information. |
HRGN | Windef.h: typedef HANDLE HRGN; | Handle to a |
HRSRC | Windef.h: typedef HANDLE HRSRC; | Handle to a resource. |
HSZ | Ddeml.h: typedef HANDLE HSZ; | Handle to a DDE string. |
HWINSTA | Windef.h: typedef HANDLE WINSTA; | Handle to a |
HWND | Windef.h: typedef HANDLE HWND; | Handle to a |
INT | Windef.h:typedef int INT; | 32-bit signed integer. |
INT_PTR | Basetsd.h:#if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR; | Signed integral type for pointer precision. Use when casting a pointer to an integer to perform pointer arithmetic. |
INT32 | Basetsd.h: typedef signed int INT32; | 32-bit signed integer. |
INT64 | Basetsd.h: typedef signed __int64 INT64; | 64-bit signed integer. |
LANGID | Winnt.h: typedef WORD LANGID; | Language identifier. |
LCID | Winnt.h: typedef DWORD LCID; | Locale identifier. |
LCTYPE | Winnls.h: typedef DWORD LCTYPE; | Locale information type. |
LGRPID | Language group identifier. | |
LONG | Winnt.h: typedef long LONG; | 32-bit signed integer. |
LONGLONG | Winnt.h: #if !defined(_M_IX86) typedef __int64 LONGLONG; #else typedef double LONGLONG; | 64-bit signed integer. |
LONG_PTR | Basetsd.h: #if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR; | Signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic. |
LONG32 | Basetsd.h: typedef signed int LONG32; | 32-bit signed integer |
LONG64 | Basetsd.h: typedef __int64 LONG64; | 64-bit signed integer |
LPARAM | Windef.h: typedef LONG_PTR LPARAM; | Message parameter. |
LPBOOL | Windef.h:typedef BOOL *LPBOOL; | Pointer to a BOOL. |
LPBYTE | Windef.h: typedef BYTE *LPBYTE; | Pointer to a BYTE. |
LPCOLORREF | Windef.h: typedef DWORD *LPCOLORREF; | Pointer to a COLORREF value. |
LPCSTR | Winnt.h: typedef CONST CHAR *LPCSTR; | Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. |
LPCTSTR | Winnt.h: #ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; | An LPCWSTR if is defined, an LPCSTR otherwise. |
LPCVOID | Windef.h: typedef CONST void *LPCVOID; | Pointer to a constant of any type. |
LPCWSTR | Winnt.h: typedef CONST WCHAR *LPCWSTR; | Pointer to a constant null-terminated string of 16-bit Unicode characters. |
LPDWORD | Windef.h: typedef DWORD *LPDWORD; | Pointer to a DWORD. |
LPHANDLE | Windef.h: typedef HANDLE *LPHANDLE; | Pointer to a HANDLE. |
LPINT | Windef.h: typedef int *LPINT; | Pointer to an INT. |
LPLONG | Windef.h: typedef long *LPLONG; | Pointer to a LONG. |
LPSTR | Winnt.h: typedef CHAR *LPSTR; | Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. |
LPTSTR | Winnt.h: #ifdef UNICODE typedef LPWSTR LPTSTR; #else typedef LPSTR LPTSTR; | An LPWSTR if is defined, an LPSTR otherwise. |
LPVOID | Windef.h: typedef void *LPVOID; | Pointer to any type. |
LPWORD | Windef.h: typedef WORD *LPWORD; | Pointer to a WORD. |
LPWSTR | Winnt.h: typedef WCHAR *LPWSTR; | Pointer to a null-terminated string of 16-bit Unicode characters. |
LRESULT | Windef.h: typedef LONG_PTR LRESULT; | Signed result of message processing. |
PBOOL | Windef.h: typedef BOOL *PBOOL; | Pointer to a BOOL. |
PBOOLEAN | Winnt.h: typedef BOOLEAN *PBOOLEAN; | Pointer to a BOOL. |
PBYTE | Windef.h: typedef BYTE *PBYTE; | Pointer to a BYTE. |
PCHAR | Winnt.h: typedef CHAR *PCHAR; | Pointer to a CHAR. |
PCSTR | Winnt.h: typedef CONST CHAR *PCSTR; | Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. |
PCTSTR | Winnt.h: #ifdef UNICODE typedef LPCWSTR PCTSTR; #else typedef LPCSTR PCTSTR; | A PCWSTR if is defined, a PCSTR otherwise. |
PCWSTR | Winnt.h: typedef CONST WCHAR *PCWSTR; | Pointer to a constant null-terminated string of 16-bit Unicode characters. |
PDWORD | Windef.h: typedef DWORD *PDWORD; | Pointer to a DWORD. |
PDWORDLONG | Winnt.h: typedef DWORDLONG *PDWORDLONG; | Pointer to a DWORDLONG. |
PDWORD_PTR | Basetsd.h: typedef DWORD_PTR *PDWORD_PTR; | Pointer to a DWORD_PTR. |
PDWORD32 | Basetsd.h: typedef DWORD32 *PDWORD32; | Pointer to a DWORD32. |
PDWORD64 | Basetsd.h: typedef DWORD64 *PDWORD64; | Pointer to a DWORD64. |
PFLOAT | Windef.h: typedef FLOAT *PFLOAT; | Pointer to a FLOAT. |
PHANDLE | Winnt.h: typedef HANDLE *PHANDLE; | Pointer to a HANDLE. |
PHKEY | Windef.h: typedef HKEY *PHKEY; | Pointer to an HKEY. |
PINT | Windef.h: typedef int *PINT; | Pointer to an INT. |
PINT_PTR | Basetsd.h: typedef INT_PTR *PINT_PTR; | Pointer to an INT_PTR. |
PINT32 | Basetsd.h: typedef INT32 *PINT32; | Pointer to an INT32. |
PINT64 | Basetsd.h: typedef INT64 *PINT64; | Pointer to an INT64. |
PLCID | Winnt.h: typedef PDWORD PLCID; | Pointer to an LCID. |
PLONG | Winnt.h: typedef LONG *PLONG; | Pointer to a LONG. |
PLONGLONG | Winnt.h: typedef LONGLONG *PLONGLONG; | Pointer to a LONGLONG. |
PLONG_PTR | Basetsd.h: typedef LONG_PTR *PLONG_PTR; | Pointer to a LONG_PTR. |
PLONG32 | Basetsd.h: typedef LONG32 *PLONG32; | Pointer to a LONG32. |
PLONG64 | Basetsd.h: typedef LONG64 *PLONG64; | Pointer to a LONG64. |
POINTER_32 | Basetsd.h: #if defined(_WIN64) #define POINTER_32 __ptr32 #else #define POINTER32 | 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer. |
POINTER_64 | Basetsd.h: #define POINTER_64 __ptr64 | 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer. |
PSHORT | Winnt.h: typedef SHORT *PSHORT; | Pointer to a SHORT. |
PSIZE_T | Basetsd.h: typedef SIZE_T *PSIZE_T; | Pointer to a SIZE_T. |
PSSIZE_T | Basetsd.h: typedef SSIZE_T *PSSIZE_T; | Pointer to a SSIZE_T. |
PSTR | Winnt.h: typedef CHAR *PSTR; | Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. |
PTBYTE | Winnt.h: typedef TBYTE *PTBYTE; | Pointer to a TBYTE. |
PTCHAR | Winnt.h: typedef TCHAR *PTCHAR; | Pointer to a TCHAR. |
PTSTR | Winnt.h: #ifdef UNICODE typedef LPWSTR PTSTR; #else typedef LPSTR PTSTR; | A PWSTR if is defined, a PSTR otherwise. |
PUCHAR | Windef.h: typedef UCHAR *PUCHAR; | Pointer to a UCHAR. |
PUINT | Windef.h: typedef UINT *PUINT; | Pointer to a UINT. |
PUINT_PTR | Basetsd.h: typedef UINT_PTR *PUINT_PTR; | Pointer to a UINT_PTR. |
PUINT32 | Basetsd.h: typedef UINT32 *PUINT32; | Pointer to a UINT32. |
PUINT64 | Basetsd.h: typedef UINT64 *PUINT64; | Pointer to a UINT64. |
PULONG | Windef.h: typedef ULONG *PULONG; | Pointer to a ULONG. |
PULONGLONG | Windef.h: typedef ULONGLONG *PULONGLONG; | Pointer to a ULONGLONG. |
PULONG_PTR | Basetsd.h: typedef ULONG_PTR *PULONG_PTR; | Pointer to a ULONG_PTR. |
PULONG32 | Basetsd.h: typedef ULONG32 *PULONG32; | Pointer to a ULONG32. |
PULONG64 | Basetsd.h: typedef ULONG64 *PULONG64; | Pointer to a ULONG64. |
PUSHORT | Windef.h: typedef USHORT *PUSHORT; | Pointer to a USHORT. |
PVOID | Winnt.h: typedef void *PVOID; | Pointer to any type. |
PWCHAR | Winnt.h: typedef WCHAR *PWCHAR; | Pointer to a WCHAR. |
PWORD | Windef.h: typedef WORD *PWORD; | Pointer to a WORD. |
PWSTR | Winnt.h: typedef WCHAR *PWSTR; | Pointer to a null-terminated string of 16-bit Unicode characters. |
SC_HANDLE | Winsvc.h: typedef HANDLE SC_HANDLE; | Handle to a service control manager database. |
SC_LOCK | Winsvc.h: typedef LPVOID SC_LOCK; | Lock to a service control manager database. |
SERVICE_STATUS _HANDLE | Winsvc.h: typedef HANDLE SERVICE_STATUS_HANDLE; | Handle to a service status value. |
SHORT | Winnt.h: typedef short SHORT; | Short integer (16 bits). |
SIZE_T | Basetsd.h: typedef ULONG_PTR SIZE_T; | The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer. |
SSIZE_T | Basetsd.h: typedef LONG_PTR SSIZE_T; | Signed SIZE_T. |
TBYTE | Winnt.h: #ifdef UNICODE typedef WCHAR TBYTE; #else typedef unsigned char TBYTE; | A WCHAR if is defined, a CHAR otherwise. |
TCHAR | Winnt.h: #ifdef UNICODE typedef WCHAR TCHAR; #else typedef char TCHAR; | A WCHAR if is defined, a CHAR otherwise. |
UCHAR | Windef.h: typedef unsigned char UCHAR; | Unsigned CHAR. |
UINT | Windef.h: typedef unsigned int UINT; | Unsigned INT. |
UINT_PTR | Basetsd.h: #if defined(_WIN64) typedef unsigned __int64 UINT_PTR; #else typedef unsigned int UINT_PTR; | Unsigned INT_PTR. |
UINT32 | Basetsd.h: typedef unsigned int UINT32; | Unsigned INT32. |
UINT64 | Basetsd.h: typedef usigned __int 64 UINT64; | Unsigned INT64. |
ULONG | Windef.h: typedef unsigned long ULONG; | Unsigned LONG. |
ULONGLONG | Winnt.h: #if !defined(_M_IX86) typedef unsigned __int64 ULONGLONG; #else typedef double ULONGLONG | 64-bit unsigned integer. |
ULONG_PTR | Basetsd.h: #if defined(_WIN64) typedef unsigned __int64 ULONG_PTR; #else typedef unsigned long ULONG_PTR; | Unsigned LONG_PTR. |
ULONG32 | Basetsd.h: typedef unsigned int ULONG32; | Unsigned LONG32. |
ULONG64 | Basetsd.h: typedef unsigned __int64 ULONG64; | Unsigned LONG64. |
USHORT | Windef.h: typedef unsigned short USHORT; | Unsigned SHORT. |
USN | Winnt.h: typedef LONGLONG USN; | Update sequence number (USN). |
VOID | Winnt.h: #define VOID void | Any type. |
WCHAR | Winnt.h: typedef wchar_t WCHAR; | 16-bit Unicode character. |
WINAPI | Windef.h: #define WINAPI __stdcall | Calling convention for system functions. |
WORD | Windef.h: typedef unsigned short WORD; | 16-bit unsigned integer. |
WPARAM | Windef.h: typedef UINT_PTR WPARAM; | Message parameter. |
Windows-Standard Typen der RTL ( Run-Time Library ) | ||
Typ | Beschreibung | deklariert in |
clock_t structure | Stores time values; used by clock. | TIME.H |
_complex structure | Stores real and imaginary parts of complex numbers; used by _cabs. | MATH.H |
_dev_t short or unsigned integer | Represents device handles. | SYS\TYPES.H |
div_t, ldiv_t structures | Store values returned by div and ldiv, respectively. | STDLIB.H |
_exception structure | Stores error information for _matherr. | MATH.H |
FILE structure | Stores information about current state of stream; used in all stream I/O operations. | STDIO.H |
_finddata_t, _wfinddata_t _wfinddatai64_t structures | _finddata_t stores file-attribute information returned by _findfirst and _findnext. _wfinddata_t stores file-attribute information returned by _wfindfirst and _wfindnext. _wfinddatai64_t stores file-attribute information returned by _wfindfirsti64 and _wfindnexti64. | _finddata_t: IO.H _wfinddata_t: IO.H, WCHAR.H _wfinddatai64_t: IO.H, WCHAR.H |
_FPIEEE_RECORD structure | Contains information pertaining to IEEE floating-point exception; passed to user-defined trap handler by _fpieee_flt. | FPIEEE.H |
fpos_t (long integer, __int64, or structure, depending on the target platform) | Used by fgetpos and fsetpos to record information for uniquely specifying every position within a file. | STDIO.H |
_HEAPINFO structure | Contains information about next heap entry for _heapwalk. | MALLOC.H |
jmp_buf array | Used by setjmp and longjmp to save and restore program environment. | SETJMP.H |
lconv structure | Contains formatting rules for numeric values in different countries. | LOCALE.H |
_off_t long integer | Represents file-offset value. | SYS\TYPES.H |
_onexit_t pointer | Returned by _onexit. | STDLIB.H |
_PNH pointer to function | Type of argument to _set_new_handler. | NEW.H |
ptrdiff_t integer | Result of subtraction of two pointers. | STDDEF.H |
sig_atomic_t integer | Type of object that can be modified as atomic entity, even in presence of asynchronous interrupts; used with signal. | SIGNAL.H |
size_t unsigned integer | Result of sizeof operator. | STDDEF.H and other include files |
_stat structure | Contains file-status information returned by _stat and _fstat. | SYS\STAT.H |
time_tlong integer | Represents time values in mktime and time. | TIME.H |
_timeb structure | Used by _ftime to store current system time. | SYS\TIMEB.H |
tm structure | Used by asctime, gmtime, localtime, mktime, and strftime to store and retrieve time information. | TIME.H |
_utimbuf structure | Stores file access and modification times used by _utime to change file-modification dates. | SYS\UTIME.H |
va_list structure | Used to hold information needed by va_arg and va_end macros. Called function declares variable of type va_list that can be passed as argument to another function. | STDARG.H |
wchar_t internal type of a wide character |
Useful for writing portable programs for international markets. | STDDEF.H, STDLIB.H |
wctrans_t integer | Represents locale-specific character mappings. | WCTYPE.H |
wctype_t integer | Can represent all characters of any national character set. | WCHAR.H |
wint_t integer | Type of data object that can hold any wide character or wide end-of-file value. | WCHAR.H |
Die Typen und Strukturen eines Betriessystems sind vielfältig und umfangreich. Windows-Typen werden u.a. für Funktions - Parameter, Funktions-Rückgabe-Werte, und für Nachrichten benötigt.
Handles werden benutzt, um mit einer Deskriptor-Tabelle auf geladenen Resourcen oder einen benötigten globalen Kontext zuzugreifen. Ein Handle entspricht dem Index der Deskriptor-Tabelle. Ein 8-Byte Deskriptor-Eintrag enthält die Ziel-Byte-Adresse, den Byte-Umfang, die Zugriffsrechte.
In Ungarn wird ( anstelle von "Hans Müller" ) der Familien - Name zuerst genannt ( "Müllers Hans" ). Bei Win16 existierten viele verschiedene Speicher - Modelle. Damit bei größeren Programmen an der Window - Variablen der zughörige Typ erkennbar ist, wurden dem Variablen - Namen Prä - Character voran gestellt. Z.B. steht "lp" für "long Pointer", "lpsz" für "long Pointer auf \0 begrenzten String", "dw" für "Doppel Wort", "h" für "Handle", "n" für "Anzahl", "f" für "Flag", usw.
Ein Beispiel ist der Aufruf von CreateWindowEx().
HWND CreateWindowEx( DWORD dwExStyle, // extended window style LPCTSTR lpClassName, // pointer to registered class name LPCTSTR lpWindowName, // pointer to window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // handle to menu, or child-window identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // pointer to window-creation data );| Prefix Naming Conventions
Prefix | Type | Description | Example |
ch | char | 8-bit character | chGrade |
ch | TCHAR | 16-bit character | if _UNICODE is defined chName |
b | BOOL | Boolean value | bEnabled |
n | int | Integer (size dependent on operating system) | nLength |
n | UINT | Unsigned value (size dependent on operating system) | nLength |
w | WORD | 16-bit unsigned value | wPos |
l | LONG | 32-bit signed integer | lOffset |
dw | DWORD | 32-bit unsigned integer | dwRange |
p | * | Pointer | pDoc |
lp | FAR* | Far pointer | lpDoc |
lpsz | LPSTR | 32-bit pointer to character string | lpszName |
lpsz | LPCSTR | 32-bit pointer to constant character string | lpszName |
lpsz | LPCTSTR | 32-bit pointer to constant character string | if _UNICODE is defined lpszName |
h | handle | Handle to Windows object | hWnd |
lpfn | callback | Far pointer to CALLBACK function | lpfnAbort |
Hungarian Notation (nach MS):
|
|
|
Das Betriessystem wurde überwiegend mit C/C++ entwickelt. Die System-Funktionen sind als Maschinencode in DLL's enthalten. Für die Entwicklung der System-Funktionen wurden Header-Quelltext-Files benutzt. Diese Header-Files werden auch für die Programm-Entwicklungen verwendet. Es gibt zahlreiche Windows-Header-Files:
Um aus ASCII-Files ein lauffaehiges *.EXE-Programm zu erstellen werden Übersetzungsprogramme benötigt, die aus lesbarem Buchstaben-Code maschinen-Code generieren. Ein direkter Entwurf der Bitmuster des Maschinencodes ist wegen des Umfanges und der Komplexität nicht möglich.
Moderne Werkzeuge bestehen aus Software - Komponenten zur Programmentwicklung. Die Zahl der benötigten Tools wächst. Anstatt diese Programme einzeln (oder mit Kommandozeile, bzw. make-File) zu verwenden, werden integrierende Bedienungsumgebung interaktiv verwendet. Es bestehen vielschichtige Abhängigkeiten zu ( standardisierten ) Software-Systemen, die durch die gleiche Bedienungsumgebung unterstützt werden und Entwicklungen mit unterschiedlichen Biblioteken und Programmiersprachen (Java, C, Assembler, C++, VB, usw.) ermöglichen. Je moderner und komplexer ein Entwicklungssystem ist, um so größer ist die Zahl der Einstellungen und Variationen und die Einarbeitungszeit.
Windows verwendet für Nachrichten-, Style-, Control- Konstanten die folgenden Gruppen:
BM_ | Button Control Messages | BN_ | User Button Notification Codes |
BS_ | Button Control Styles | CBS_ | Combo Box styles |
CCS_ LVS_ TVS_ TCS_ ACS_ |
COMMON CONTROL STYLES | CS_ | Class styles |
CF_ | Predefined Clipboard Formats | DS_ | Dialog Styles |
ES_ | Edit Control Styles | HELP_ | Commands to pass to WinHelp() |
HT | WM_NCHITTEST, MOUSEHOOKSTRUCT Mouse Pos | ID | Dialog Box Command IDs |
IDI_ | Standard Icon IDs | LANG_ | language IDs. |
LBS_ | Listbox Styles | MA_ | WM_MOUSEACTIVATE Return Codes |
MF_ | Menu flags for Add/Check/EnableMenuItem() | MFS_ | Menu flags for Add/Check/EnableMenuItem() |
MK_ | Key State Masks for Mouse Messages | OBM_ | OEM Resource Ordinal Numbers |
PWR_ | wParam for WM_POWER | SBS_ | Scroll Bar Styles |
SC_ | System Menu Command Values | SIZE_ | WM_SIZE message wParam values |
SORT_ | Sorting IDs. | SS_ | Static Control Constants |
SW_ | ShowWindow() Commands | TBS_ | Tab style |
VK_ | Virtual Keys, Standard Set | WA_ | WM_ACTIVATE state values |
WM_ | Window Messages | WM_DDE_ | DDE - Mesages |
WS_ | Window Styles | WS_EX_ | Extended Window Styles |
WVR_ | WM_NCCALCSIZE return values |
Windows.h enthält die Funktions - Prototypen. Dadurch kann der Compiler die Schreibweise ( Syntax ) in dem eigenen Programm überprüfen. Damit der Linker dnden kann, sind außerdem z.B. die folgenden Bibliotheken
in das Projekt aufzunehmen. Soll zusätzlich die "messaging functionality" in das eigene Programm aufgenommen werden, so ist #include Msgstore.h erforderlich. Soll zusätzlich die "e-mail functionality" in das eigene Programm aufgenommen werden, so ist #include Addrstor.h erforderlich. Natürlich sind auch die zugehörigen *.lib - Files in die Entwicklungs - Umgebung aufzunehmen. Oft werden die folgenden ( voreingstellten ) *.lib - Files verwerdet:
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Von den Entwicklungs - Werkzeugen mußte der Linker immer mehr Aufgaben übernehmen. Die Linker - Zeiten übersteigen vielfach die Compiler - Zeiten. Eine Teilung der Linker - Aufgaben in traditionelles Linken und der Resourcen - Erstellung ist angezeigt.
Der Linker fügt Binärcode aneinander und verbindet die wechselseitigen Zuordnungen ( Adressen ). Bei einem Linker - Fehler ist der Zusammenhang mit dem lesbaren ASCII - Quelltext verloren. Der Linker gibt im Fehlerfall die Namen der nicht gefundenen bzw. doppelt vorhanden Symbole aus. Weil bei C und C++ - Code gemäß
#ifdef __cplusplus extern "C" { #endif ... ... #ifdef __cplusplus } #endif
gemischt werden können, ist zur Fehlererkennung vielfach auf die Schreibweise der ausgegebenen Namen zu beachten.
Linker- Fehler- Anzeige | Diagnose |
myFkt$int$int | Es wurde mit C++ compiliert, bzw. eine C++ Bibliothek wird verwendet. |
MYFKT | Es wurde mit PASCAL deklariert compiliert, bzw. Linkerschalter auf Großbuchstaben, bzw. Win16 - Bibliothek wird verwendet. |
_myFkt | Es wurde mit C, CDECL compiliert, bzw. es werden C - Bibliotheken verwendet. |
Windows - Applikationen benötigen viele statische Daten ( Fenstergröße, Farbe, Controls, ... ). In den meisten Fällen werden die Geometrie - Resourcen mit Hilfe visueller, interaktiver Tools ( z.B. Resourcen Workshop ) erstellt.
Diese Resourcen können im *.RC - ASCII - File ( oder in einem binären *.RCT - Template - File ) gespeichert werden.
Ein RC - Compiler übersetzt diesen *.RC - ASCII - File in einen binären *.RES - File, der durch den Linker dem *.EXE - File hinzugefügt wird.
Weil eine standardisierte Binärform benutzt wird, ist es mit dem Resourcen Workshop auch möglich, aus einem *.EXE - Programm den *.RC - ASCII - File zu erhalten.
Für den Übersetzungsvorgang von Windows - Applikationen werden die Header-Files
#define STRICT #include <windows.h> #include <commdlg.h> #include <windowsx.h>
mit den Funktions - Prototypen in den C, C++ - Quelltext eingebunden. Dadurch kann bereits der Compiler in unseren *.C, *.CPP - Files die richtige Schreibweise der Window - Typen und -Funktionen überprüfen. Der Compiler übersetzt die *.CPP - Files in *.OBJ - Files. Wenn der Linker-Pfad zu *.LIB richtig gesetzt ist, kann der Linker aus den Window-Bibliotheken *.LIB die Einsprüngen in die Window-dll´s entnehmen und in unser Programm einbauen. Unser Programm verwendet dann die benötigten Window-DLL’s. Der Resourcen-Compiler erzeugt aus *.RC den binären *.RES-File:
Um einen ausführbaren, binär - File ( *.EXE ) zu erzeugen, müssen ASCII - Files in Maschinen-Code übersetzt werden:
*.C, *.CPP ===> Compiler ===> *.OBJ *.H, *.RC ===> Resourcen-Compiler ===> *.RES *.OBJ, *.DEF ===> Linker ===> (*.EXE) (*.EXE), *.RES ===> Resourcen-Compiler ===> *.EXE
Die Steuerung des Übersetzungs-Vorganges wird i.a. von der Projekt - Entwicklungs - Umgebeung oder von make.exe (nmake.exe ) übernommen. Der Übersetzungsvorgang kann auch die automatische Hyphertext - Help - Erzeugung enthalten.
Am Anfang bestand das Windows-Betriebssystem aus weniger als 10 DLL's. Bei XP gibt es bis zu 2000 DLL's. Der eigentliche Betriebssystem - Kern besteht aus den drei Dateien (nativ-Funktionen in DLL). Diese DLL's werden bei Start des Betriessystems geladen (und heissen deshalb nicht .dll sondern .exe).
Bei diesen Dateien handelt es sich um sogenannte DLL’s ( Dynamic Link Libarys ). Dies sind binäre Funktionsbibliotheken. Zum Betriebssystem gehören noch weitere Komponenten, wie z.B.
DLL’s sind binäre Instanzen von Objekte und enthalten Daten ( Properties ) und Methoden ( Funktionen ). Benötigt eine Applikation eine DLL, so wird diese geladen und die benötigte Funktion ausgeführt. Falls die Dateiendung nicht *.DLL ist ( z.B. *.EXE ), so muß die Datei explizit geladen/freigegeben werden.
Ist die DLL bereits geladen, so wird in der DLL lediglich ein Zähler hochgezählt. Ein DLL darf bei Bedarf aus dem Speicher entfernt werden, wenn dieser Zäher 0 ist. Eine DLL wird nur einmal geladen, auch wenn diese DLL von mehreren Anwendungen benutzt wird. Der Zugriff auf eine Funktion und deren Ausführung kann über die ASCII - Namen - Tabelle ( langsamer ) oder den Index der Funktions - Adress - Tabelle ( schneller ) erfolgen. Der hinterlegte Wert in der Funktions - Tabelle zeigt auf den Anfang der eigentlichen Funktion. Diese Zugriffsart ist schneller, als der Zugriff über die ASCII - Namen - Tabelle.
| Adress-Tabelle | | Tabelle | | der enthaltenen | | der | | Funktionen | Dat1 | Dat2 | Func1 | Func2 | Func3 | Func4 | Namen | ---|-----------------|------|------|-------|-------|-------|-------|---------|--- DLL Dat1 Dat2 Func1 Func1 Func1 Func1 Tab Adr Adr Adr Adr Adr Adr Adr Adr
Die DOS - Interrupttabelle ist grob mit der DLL - Funktionstabelle vergleichbar (die Zuordnung von Interruptzeiger zu Interruptserviceroutinen). Bei interoperablen Systemen ( UNIX - WINDOWS ) wird der Zugriff über die ASCII - Namen - Tabelle benutzt. Bevor eine DLL - Funktion ausgeführt wird, werden die Funktionsparameter auf den Stack des aurufenden Programmes gelegt.
DLL-Funktionsaufrufe erfolgen
über den Benutzerstack.
Die Funktions - Adress - Tabelle bedingt, daß das aurufende Programm ( Applikation ) den gewünschten Index der DLL - Funktions - Adress - Tabelle kennt. Die Namen - Index - Zuordnungen sind in LIB - Dateien ( Libary ) enthalten. Beim Erstellen eines Programmes werden diese Indizes der DLL - Funktions - Adress - Tabelle in den Maschinencode eingefügt. Der Linker trägt den Index in das Maschinenprogramm ein. Der DLL - Name wird nur einmal in das Applikationsprogramm eingetragen.
Die Dateien KRNL386.EXE ist eine DLL ( Dynamic Link Libarys ). KRNL386.EXE
In KRNL386.EXE sind binäre Funktionen enthalten. Die wesentlichen Funktionen sind in der folgende Tabelle zusammengefaßt.
Object | Creator function | Destroyer function | Object | Creator function | Destroyer function |
Change notification Communications | FindFirstChangeNotification | FindCloseChangeNotification | device | GetStdHandle | CloseHandle |
Event | CreateEvent, OpenEvent | CloseHandle | Event log | OpenEventLog, RegisterEventSource, OpenBackupEventLog | CloseEventLog |
File | CreateFile | CloseHandle, DeleteFile | File mapping | CreateFileMapping, OpenFileMapping | CloseHandle |
Find file | FindFirstFile | FindClose | Heap | HeapCreate | HeapDestroy |
Mailslot | CreateMailslot | CloseHandle | Module | LoadLibrary, GetModuleHandle | FreeLibrary |
Mutex | CreateMutex, OpenMutex | CloseHandle | Pipe | CreateNamedPipe, CreatePipe | CloseHandle, DisconnectNamedPipe |
Process | CreateProcess, OpenProcess, GetCurrentProcess | CloseHandle, TerminateProcess | Semaphore | CreateSemaphore, OpenSemaphore | CloseHandle |
Thread | CreateThread, CreateRemoteThread, GetCurrentThread | CloseHandle, TerminateThread | Timer | CreateWaitableTimer, OpenWaitableTimer | CloseHandle |
Update resource | BeginUpdateResource | EndUpdateResource |
Der File USER.EXE ist eine DLL, die die auf dem Bildschirm die Fenster erzeugt und manipuliert ( create, move, size, remove), die Icons und andere Komponenten des Benutzer-Interface behandelt, die Eingaben ( dispatch ) von Keyboard, Mause und anderen Eingabe-Geräten an die zugehörige Applikation verteilt. Mit den Funktionen von USER.EXE können interaktive Fenster ( desktop - shell ) erstellt werden. Die User Interface Services
USER.EXE enthält | ||||
Funktionen für die Dialogelemente ( Controls ): | lesbare Daten ( Resources ) sind: | Programmierschnittstelle ( Shell and Common Controls ): |
Benutzer-Eingaben ( User Input ) | Fensternhirachie ( Windowing ) |
Auslöseknöpfe ( Buttons ), Textboxen ( List Boxes ), aufklappbare Textboxen ( Combo Boxes ), Text - Editor ( Edit Controls ), RTF - Text - Bearbeitung ( Rich Edit Controls ), Rollbalken ( Scroll Bars ), feste Texte ( Static Controls ) | Textcursor ( Carets ), Mauscursor ( Cursors ), kleines Symbolbild ( Icons ), Menus, benutzerdefinierte Resourcen-Daten | Windows Shell API, standardisierter Dialogelemente ( Common Controls ), Wizard97 Specifications | Nachrichtenzugriff ( Accessibility ), Mauseingaben ( Mouse Input ), Tasten - Code der Tastatur ( Keyboard Input ), standardisierter Tastencode ( Virtual-Key Codes ), Alt-Tasten ( Keyboard Accelerators ), fertige Dialoge ( Common Dialog Box Library ) | Fensterbehandlung ( Windows ) Datenzuordnung zu Fenstern ( Window Properties ), mehrere Fenster mit gleichen Eigenschhaften ( Window Classes ), Nachrichtenbearbeitung ( Message and Message Queues ), ereignisgesteuerter Funktionsaufruf ( Callback, Window Procedures ), Behandlung von Dialogen ( Dialog Boxes ), alle Fenster innerhalb des Eltern Fenster ( Multiple Document Interface ) |
Die folgenden Funktionen werden zum Erzeugen und Manipulieren von Fenstern benutzt.
|
GDI ist eine Abkürzung für (G)raphic (D)evice (I)nterface. Der File GDI.EXE ist eine DLL, die das Graphics Device Interface ( GDI ) mit den Funktionen zur Bild - Erzeugung und Bild - Anzeige ( nicht nur Screen ) enthält. Hierher gehören z.B. auch Fonts und Device - Kontext.
Den Device Kontext benutzen die folgenden Funktionen.
|
Mit Fonts und Texten werden die folgenden Funktionen benutzt:
|
Im Zusammenhang mit der Paint - Nachricht werden die folgenden Funktionen benutzt:
|
Als ein Beispiel für den Umfang einer Funktion soll hier GetDeviceCaps() angegeben werden. GetDeviceCaps() gibt Informationen zum Device Kontext zurück.
int GetDeviceCaps(
HDC hDC, // device-context handle
int nIndex // index of capability to query
);
Für den Parameter nIndex kann eine der folgenden Zahlen gewählt werden. Die eingerückten Konstanten kennzeichnen die zugehörigen Rückgabewerte.
|
|
Mit der Funktion GetSystemMetrics köennen ( geometrische ) Fenster - und Screen - Werte abgefragt werden. Durch
RECT rc ; //Dialog mittig zentrieren GetWindowRect ( hWnd , & rc ) ; rc.left = ( GetSystemMetrics ( SM_CXSCREEN ) - rc.right + rc.left ) / 2 ; rc.top = ( GetSystemMetrics ( SM_CYSCREEN ) - rc.bottom + rc.top ) / 2 ; SetWindowPos ( hWnd, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
wird ein Fenster zentriert.
Weil bereits ein erstes Programm unübersichtlich ist, wird das Grundgerüst zunächst im Pseudocode betrachtet. Ein einfaches Programm hat die folgende Struktur: Ein Window-Programm besteht aus der WinMain()-Funktion, die
Wegen der vielen Parameter wird der C/C++ - Quelltext z.T. bereits unuebersichtlich. Auch verfuegbare Klassen - Bibliotheken verwenden den gleichen Aufbau ( und sind oft ebenfalls unuebersichtlich! ).
Das folgende Beispiel besteht aus der WinMain() und der WndProc() - CALLBACK - Funktion. Es wird ein Hauptfenster angelegt und Text zentriert hinein geschrieben. // cpp-Rahmen für Window-Applikation:
#define UNICODE
LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg,WPARAM wParam, LPARAM lParam) { switch(umsg) {case WM_DESTROY: { PostQuitMessage(0); break; }case WM_RBUTTONDOWN: { int xPos = (int)LOWORD(lParam); break; }
case WM_KEYDOWN:{ switch (wParam) { case VK_CLEAR: case VK_NUMPAD5: break; } // ende switch break; } // ende WM_KEYDOWNcase WM_SIZE:{ // w = (int)LOWORD(lParam); h = (int)HIWORD(lParam); break; }
case WM_PAINT:{ PAINTSTRUCT ps;HDC hdc = BeginPaint(hwnd, &ps); RECT rc; GetClientRect(hwnd, &rc) ; DrawText(hdc,TEXT("Hallo, Win!"),-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER);break; }HPEN hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); HPEN hPenOld = (HPEN)SelectObject(hdc, hPen); MoveToEx(hdc, 20, 20, NULL); LineTo(hdc, 200, 100); SelectObject(hdc, hPenOld); DeleteObject(hPen);EndPaint(hwnd, &ps);default: return DefWindowProc(hwnd,umsg,wParam,lParam);} return 0; }
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {// HINSTANCE hInstance = GetModuleHandle(0); WNDCLASSEX wndClass = {0}; wndClass.cbSize = sizeof( WNDCLASSEX ) ; wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.lpszClassName = TEXT("my_class"); wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.lpszMenuName = NULL; wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION ) ; if (!RegisterClassEx(&wndClass)) return -1 ;HWND hwnd = CreateWindow( TEXT("my_class"), // window class name TEXT("Titelzeile"), // window caption WS_OVERLAPPEDWINDOW, // window style 20, 20,// initial position x,y,(CW_USEDEFAULT) 500,500,// initial x size cx,cy, (CW_USEDEFAULT) NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow (hwnd, SW_SHOW); UpdateWindow(hwnd);MSG msg ; while ( GetMessage ( & msg, NULL, 0, 0 ) ) { //TRUE, FALSE, -1 TranslateMessage ( & msg ) ; DispatchMessage ( & msg ) ; }// hier kann aufgräumt werden return (int) msg.wParam; } // ende WinMain
Diese Programm besteht aus Teilen:
WinMain entspricht der main() - Funktion in C. Der (W)indow -(S)tyle WS_OVERLAPPEDWINDOW entspricht
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX) #define WS_POPUPWINDOW (WS_POPUP|WS_BORDER|WS_SYSMENU)
Die Start - Adresse einer Window - Applikation ist die WinMain() - Funktion( APIENTRY ). WinMain ist der Haupt - Eintritts - Punkt für eine Windows - Anwendung. Diese Funktion entspricht der Funktion main() bei einem C-Programm. Der WinMain - Startup - Code ruft die WinMain-Funktion durch den Namen auf. Windows verwendet diese Funktion als "initial entry point" APIENTRY). Beim Start wird der Startup-Code ausgeführt, der u.a. die Windows-Funktionen
aufruft. Danach ruft der Startup - Code unsere WinMain - Funktion auf. Diese Schritte bei Start eines Win - Programmes können grob skizziert werden:
InitTask füllt bei Win16 die folgenden Register mit Werten, die beim Laden der Applikation auf den Stack gelegt werden:
BX = Stack-Grösse, CX = Heap-Grösse, DI = Instanz-Handle, SI = vorherige Instanz, ES = PSP-Adresse
Außerdem initialisiert InitTask pStackTop, pStackMin, pStackBottom im Task - Header der aufrufenden Tastk. DLL´s sind keine Task´s, rufen aber in ihrem Startup-Code auch InitTask auf.
Durch InitApp ( USER ) wird eine User - Nachrichten - Warte - Schlange ( Application - Message - Queue ) eingerichtet. Die Nachrichten der Application - Message - Queue haben ein einheitliches Format.
Die Nachrichten, die zu unserem Programm gehören, werden durch Windows der
Die C-Laufzeit-Bibliothek wird initialisiert. Die statischen Konstruktoren von C++ werden initialisiert. Der Startup-Code legt die WinMain - Parameter auf den Stack und ruft WinMain auf.
WaitEvent ( KRNL386 ) prüft ( PostEvent, Reschedule ), ob bereits ein Ereignis an die aktuelle Task ( 0 ) geschickt wurde. Wenn das Ereignis abgeschickt und noch nicht eingetroffen ist, so wird gewartet und dann die bisher eingetroffenen Ereignisse gelöscht (siehe: Start-Up-Code).
Hat eine Applikation mehrere Fenster, so gibt es Daten, die von allen Fenstern benötigt werden. Diese Daten werden in der WNDCLASSEX - Struktur gespeichert. The WNDCLASSEX structure is similar to the WNDCLASS structure. There are two differences. WNDCLASSEX includes the cbSize member, which specifies the size of the structure, and the hIconSm member, which contains a handle to a small icon associated with the window class.
typedef struct _WNDCLASSEX { UINT cbSize; // sizeof( WNDCLASSEX ) ; UINT style; // CS_HREDRAW, CS_VREDRAW, CS_DBLCLKS,CS_CLASSDC,CS_OWNDC, // CS_PARENTDC,CS_BYTEALIGNWINDOW,CS_BYTEALIGNCLIENT, // CS_NOCLOSE,CS_GLOBALCLASS,CS_SAVEBITS WNDPROC lpfnWndProc; // CALLBACK-Funktion int cbClsExtra; // < 40 Byte int cbWndExtra; // < 40 Byte HANDLE hInstance; // von WinMain() HICON hIcon; // LoadIcon ( NULL, IDI_APPLICATION ); HCURSOR hCursor; // LoadCursor( NULL, IDC_ARROW ); HBRUSH hbrBackground; // ( HBRUSH ) GetStockObject( WHITE_BRUSH ); LPCTSTR lpszMenuName; // NULL LPCTSTR lpszClassName; // static char szAppName[] = "HelloWin" ; HICON hIconSm; // LoadIcon( NULL, IDI_APPLICATION ); } WNDCLASSEX;
Damit später mit ( CreateWindow oder CreateWindowEx ) spezielle Fenster angelegt werden können, müssen vorher der Speicherbereich für die gemeinsamen Daten angelegt und initialisiert werden.
WNDCLASSEX wc = { 0 }; wc.cbSize = sizeof( WNDCLASSEX ) ; wc.style = ... wc.lpfnWndProc = ... ... wc.lpszClassName = ... if ( ! RegisterClass( & wc ) ) Fehler;
Die hinterlegten Daten können mit GetClassInfoEx() erhalten werden.
Damit bei einem Aufruf von RegisterClassEx() ( oder RegisterClass() ) nicht 13 Parameter übergeben werden müssen, werden die Eingabewerte in eine WNDCLASSEX - Struktur geschrieben, die dann an die Funktion
ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx );
übergeben wird. Wenn kein Speicher für die Daten angelegt werden konnte und diese Funktion erfolglos war, wird 0 zurück gegeben. In diesem Fall kann der Fehler mit GetLastError() näher untersucht werden. Achtung! Ist RegisterClassEx() in einer DLL, so wird beim 'unloaden' der Speicher nicht automatisch freigegeben. Es ist unRegisterClassEx() erforderlich.
Bis auf dwExStyle ist CreateWindowEx() identisch mit CreateWindow(). CreateWindowEx() kann ein Overlapped -, Pop - Up -, oder Child - Window erstellen.
Dabei ist das Fenster noch nicht sichtbar, obwohl das Handle != NULL den allokierten Speicher referenziert und Fenster-Daten eingetragen wurden.
HWND CreateWindowEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu, or child-window identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
);
dwExStyle spezifiziert erweiterte Styles: WS_EX_ACCEPTFILES, WS_EX_APPWINDOW, WS_EX_CLIENTEDGE, WS_EX_CONTEXTHELP, WS_EX_CONTEXTHELP, WS_EX_CONTROLPARENT, WS_EX_DLGMODALFRAME(double border), WS_CAPTION, WS_EX_LEFT, WS_EX_LEFTSCROLLBAR, WS_EX_LTRREADING, WS_EX_MDICHILD, WS_EX_NOPARENTNOTIFY,WS_EX_OVERLAPPEDWINDOW, WS_EX_PALETTEWINDOW, WS_EX_RIGHT, WS_EX_RIGHTSCROLLBAR,WS_EX_RTLREADING, WS_EX_STATICEDGE, WS_EX_TOOLWINDOW, WS_EX_TOPMOST, WS_EX_TRANSPARENT, WS_EX_WINDOWEDGE
lpClassName zeigt auf einen "null-terminated string" der den Window - Class - Namen spezifiziert oder ist ein integer atom ( GlobalAddAtom ). lpClassName zeigt auf einen "null-terminated string" der den Window - Namen spezifiziert ( Titelzeile, Text eines Controls ). dwStyle spezifiziert den Style des Fensters und Funktionalität:
WS_BORDER, WS_CAPTION, WS_CHILD, WS_CHILDWINDOW, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, WS_DISABLED, WS_DLGFRAME, WS_GROUP, WS_HSCROLL, WS_ICONIC, WS_MAXIMIZE, WS_MAXIMIZEBOX, WS_MINIMIZE, WS_MINIMIZEBOX,WS_OVERLAPPED, WS_OVERLAPPEDWINDOW, WS_POPUP, WS_POPUPWINDOW, WS_SIZEBOX, WS_SYSMENU, WS_TABSTOP, WS_THICKFRAME, WS_TILED, WS_TILEDWINDOW, WS_VISIBLE, WS_VSCROLL
Alle Fenster haben bereits die WS_CLIPSIBLINGS und WS_CLIPCHILDREN Styles. lpParam kann in der CREATESTRUCT - Struktur unter WM_CREATE an die CALLBACK - Funktion weitergereicht werden.
In CreateWindowEx() können für die horizontale/vertikale Fenster - Position anstelle von festen int x-, y-, nWidth-, nHeight- Werten auch Bildschirm - bezogene Werte ( z.B. GetSystemMetrics(SM_CXSCREEN)*1/8, GetSystemMetrics(SM_CYSCREEN)*1/5, GetSystemMetrics(SM_CXSCREEN)*6/8, GetSystemMetrics(SM_CYSCREEN)*6/5 ) verwendet werden.
Win32 nutzt die 32-Bit-CPU-Architektur. Bei Win32 entspricht das Datensegment-Register DS nicht mehr einer direkten Adresse auf das aktuelle Datensegment.
Ein 8 - Byte - Element aus der Deskriptor - Tabelle enthält die endgültige Byte - Zieladresse und das Sicherheits - Byte.
Beim erstmaligen Benutzen wird mit dem DS - Index das 8 - Byte - Element aus der Deskriptor - Tabelle geholt und in die CPU übertragen. Jeder CPU - Befehl kann damit ( ohne Verzögerung ) das Element innerhalb der CPU nutzen ( Sicherheitsbyte, Protected Mode, Privileg Level ).
Beinahe jede Window - Funktion benötigt globale Window - Daten, Fenstergröße, Device - Kontext, usw. Damit die Funktion richtig ausgeführt wird, muß vorher das Handle beschafft werden. Nur dann kann die Windows - Funktion die benötigten globalen Daten erreichen und nutzen.
// Die Nachrichtenschleife enthält: while ( GetMessage( & msg, NULL, 0, 0 ) ) { TranslateMessage( & msg ) ; DispatchMessage ( & msg ) ; }
GetMessage() holt aus dem Applikations - Buffer ( thread's message queue ) die nächste Nachricht und stellt diese in der MSG - Struktur zur Verfügung. GetMessage() erhält keine Nachrichten von einer anderen Applikation. Entnimmt GetMessage() dem Buffer die WM_QUIT - Nachricht, so sendet die aufgerufene DefWindowProc() WM_DESTROY und PostQuitMessage(); beendet die Haupt-Nachrichtenschleife.
BOOL GetMessage(
LPMSG lpMsg, // address of structure with message
HWND hWnd, // handle of window
UINT wMsgFilterMin, // first message
UINT wMsgFilterMax // last message
);
Wenn mit PostThreadMessage() per Programm eine Nachricht versendet wird, so ist hWnd == NULL, sonst identifiziert hWnd das Fenster. wMsgFilterMin, wMsgFilterMax werden zum Eingrenzen der Nachrichten verwendet ( z.B. WM_KEYFIRST, WM_KEYLAST, WM_MOUSEFIRST, WM_MOUSELAST ).
Die Funktion BOOL TranslateMessage( CONST MSG *lpMsg ) wandelt eine Virtual-Key-Nachricht in eine Zeichen-Nachricht um ( WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP ). WM_KEYDOWN und WM_KEYUP Kombinationen ergeben WM_CHAR oder WM_DEADCHAR - Nachrichten. WM_SYSKEYDOWN und WM_SYSKEYUP Kombinationen ergeben WM_SYSCHAR oder WM_SYSDEADCHAR - Nachrichten. Die Zeichen - Nachricht wird in die Applikations - Nachrichten - Buffer gestellt. Mit GetMessage() oder PeekMessage() wird diese Nachricht geholt.
Existiert Accelerator-Tabelle hAccel ("Hot-Keys" für das Menü),
so können in der Hauptnachrichten-Schleife, nach GetMessage(),
die "Hot-Keys"-Ereignisse abgefangen und
mit Hilfe der Funktion
int TranslateAccelerator(HWND hWnd, HACCEL hAccel, LPMSG lpMsg);
die dem hWnd-Fenster zugeordnete CALLBACK-Funktion aufgerufen werden.
Aus dem Handle der Nachricht kann das Fenster ersehen werden. DispatchMessage() bestimmt das Fenster und leitet eine gültige Nachricht an die CALLBACK - Funktion des Fensters. LONG DispatchMessage( CONST MSG *lpmsg ). Wenn lpmsg auf eine WM_TIMER - Nachricht zeigt wird anstelle der Window - CALLBACK - Funktion die Funktion lParam() != NULL aufgerufen.
Das System verwaltet die Tastatur, die Maus und den Bildschirm.
Wenn z.B. eine Taste gedrückt wird,
so tritt ein Ereignis ein.
Dieses Ereignis
kommt über den einen System-Buffer in den Applikations-Nachrichten-Buffer,
wird dort entnommen und ruft die CALLBACK - Funktion
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
des Fensters mit DispatchMessage() auf.
Aus dem Handle
der Tasten-Nachricht kann das Fenster ersehen werden.
DispatchMessage() bestimmt das Fenster und ruft
die CALLBACK - Funktion des Fenster auf.
Kurz-Sprechweise: Die (Tasten-)Nachricht wird an das Fenster geschickt.
Vor dem Aufruf der Fensters - CALLBACK - Funktion werden ( durch das Windows - System ) die Parameter der Nachricht auf den Stack gelegt, d.h. die Nachricht wird über den Aufrufer - Stack an die CALLBACK - Funktion übergeben. Nachrichten rufen dieFenster CALLBACK - Funktion auf. Die Nachrichten werden innerhalb der CALLBACK - Funktion bearbeitet oder an die DefWindowProc() weiter geleitet.
Ist z.B. ein Teilbereich des Bildschirm - Fensters verdeckt und wird die Überdeckung beseitigt, so entsteht ein "weißes Rechteck". Das Windows - System legt die WM_PAINT - Nachricht in den Applikations - Message - Buffer. In der Hauptnachrichten - Schleife wird durch DispatchMessage() die CALLBACK - Funktion aufgerufen. Wenn Windows oder eine andere Applikation ein Neuzeichnen wünscht, so wird eine WM_PAINT - Nachricht gesendet. In der CALLBACK - Funktion kann
uMsg = WM_PAINT hdc = (HDC) wParam;
benutzt werden. Wenn z.B. das Fenster vergrößert wird, so wird automatisch die WM_PAINT - Nachricht durch das Windows - System gesendet. Die WM_PAINT - Nachricht ist eine nachrangige Nachricht. Sind neben WM_PAINT weitere Nachrichten im Applikations - Nachrichten - Buffer, so werden diese zuerst abgearbeitet. Die WM_PAINT - Nachricht wird auch durch die Funktionen UpdateWindow(), RedrawWindow() ausgelöst. Eine WM_PAINT - Nachricht steht in Zusammenhang mit den WM_ERAEBKGND -, WM_NCPAINT - Nachrichten und den Funktionen DispatchMessage(), DefWindowProc(), BeginPaint(), EndPaint(), GetUpdateRect(), UpdateWindow(), RedrawWindow()
Eine Applikation zeichnet und aktualisiert ein Fenster
Eine WM_PAINT - Nachricht wird meist verarbeitet durch
case WM_PAINT : hDC = BeginPaint( hWnd, & ps ) ; GetClientRect( hWnd, & rect ) ; DrawText ( hDC, "Hallo, Win32!",-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); EndPaint ( hWnd, & ps ) ; break ; //return 0;
Der Hintergrund wird gelöscht und der Text wird erneut durch DrawText() zentriert ausgegeben. Die BeginPaint() - Funktion wird benutzt, um gemäß hDC = BeginPaint( hWnd, & ps ) ;
Der Device - Kontext enthält globale Daten, die von vielen GDI - Funktionen zum Zeichnen gebraucht werden. Praktisch alle GDI - Funktionen benötigen den Device - Kontext.
Durch EndPaint ( hWnd, & ps )
BeginPaint() und EndPaint() benutzen PAINTSTRUCT |
Das Update- Rechteck wird in einer RECT- Struktur gespeichert |
typedef struct tagPAINTSTRUCT { // ps HDC hdc; BOOL fErase; // TRUE: erase background // with hbrBackground of WNDCLASSEX RECT rcPaint; // painting rectangle BOOL fRestore; // Reserved; used internally BOOL fIncUpdate; // Reserved; used internally BYTE rgbReserved[32];// Reserved; used internally } PAINTSTRUCT; | typedef struct _RECT { // rc LONG left; LONG top; LONG right; LONG bottom; } RECT; |
Ein Handle auf den Device-Context hDC ( das zum gesamten Client - Bereich gehört ), wird erhalten durch
hDC = GetDC( hWnd ) ;
...
ReleaseDC( hWnd, hDC ) ;
Das Update - Recheck ( validates ) wird auch gelöscht durch den Aufruf von DefWindowProc(), die ( falls erforderlich ) WM_NCPAINT, WM_ERASEBKGND - Nachrichten sendet.
Mit der GetUpdateBeginPaint() ... EndPaint() erforderlich. Wenn die Update - Rechteck nicht leer ist, so sendet Windows eine WM_PAINT - Nachricht zu dem Fenster. Durch die InvalidateRect() kann ein Rechteck zu dem Update - Fenster - Rechteck hinzugefügt werden.
Durch InvalidateRect( hWnd, NULL, TRUE ) wird der gesamte Fenster - Client - Bereich zur Update - Rechteck hinzugefügt, d.h. mit WM_PAINT - Nachricht soll der Fenster - Hintergrund gelöscht und das gesamte Fenster neu gezeichnet werden. Durch BeginPaint(), ValidateRect()/ValidateRgn() wird das Update - Rechteck/Region gelöscht.
BOOL InvalidateRect( HWND hWnd, // handle of window with changed update Rect CONST RECT *lpRect, // address of rectangle coordinates BOOL bErase // TRUE: BeginPaint() erased background );
Mit der GetUpdateRect() kann untersucht werden, ob eine Update Rechteck vorhanden ist. Falls GetUpdateRect den wert 0 zurück gibt, so ist kein BeginPaint() ... EndPaint() erforderlich. Falls ein Update Rechteck vorhanden ist, so sendet die UpdateWindow( hWndMain ) eine synchrone WM_PAINT - Nachricht. Ebenso die RedrawWindow( hWndMain ) Funktion, die eine erweiterte Kontrolle ( not Client, BackGround ) erlaubt.
Ein Fenster kann in den Vordergrund geholt werden. Beispiel:
BOOL bVisible = IsWindowVisible(hwnd); SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW |(bVisible ? SWP_NOACTIVATE : 0)); if (wParam == TRUE) SetForegroundWindow(hwnd);
Wird durch einen
so wird die CALLBACK - Funktionmit uMsg = WM_CLOSE aufgerufen. Um mit Hilfe eines Anzeige - Fensters ( MessageBox ) eine Rückfrage zu ermöglichen wird unter WM_CLOSE
case WM_CLOSE: if ( GetParent( hWnd ) != NULL ) break; char buf[256]; GetWindowText( hWnd, buf, 256 ) ; // Text der Titelzeile wird nach buf kopiert if ( MessageBox ( hWnd, "Do you want to Exit?", buf, MB_ICONQUESTION | MB_YESNO) == IDYES ) { DestroyWindow( hWnd ); //sendet WM_DESTROY } return 0; case WM_DESTROY: // Hauptfenster schliessen, zerstoert automatisch die Child-Windows. PostQuitMessage( 0 ); return 0;
ausgeführt. Falls der MessageBox - Rückgabewert TRUE ist, so wurde der "YES" - Button gedrück. Dann wird durch DestroyWindow( hWnd ) die WM_DESTROY - Nachricht gesendet, d.h. die
Einige Nachrichten werden in der eigenen CALL-Klassen-CALBACK-Funktionen behandelt. Alle anderen Nachrichten werden an die "default - Windows - CALLBACK - Funktion" DefWindowProc() übergeben. DefWindowProc() ist wie eine Applikations - CALLBACK - Funktion aufgebaut. DefWindowProc() behandelt die folgenden Nachrichten:
WM_NCCREATE, WM_NCCALCSIZE, WM_NCHITTEST, WM_NCPAINT, WM_NCACTIVATE, WM_CANCELMODE, WM_SETTEXT, WM_GETTEXT, WM_GETTEXTLENGTH, WM_PAINT, WM_PAINTICON, WM_ERASEBKGND, WM_ICONERASEBKGND, WM_SYNCPAINT, WM_SYSCOMMAND, WM_ACTIVATE, WM_SETREDRAW, WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED,WM_CTLCOLOR, WM_SETCURSOR, WM_MOUSEACTIVATE, WM_SHOWWINDOW, WM_NCLBUTTONDOWN, WM_NCLBUTTONUP, WM_NCLBUTTONDBLCLK, WM_NCMOUSEMOVE, WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP, WM_SYSCHAR, WM_CLOSE, WM_QUERYOPEN, WM_QUERYENDSESSION, WM_ISACTIVEICON, WM_CHARTOITEM, WM_VKEYTOITEM, WM_DRAWITEM, WM_GETHOTKEY, WM_SETHOTKEY, WM_QUERYDRAGICON, WM_QUERYDROPOBJECT, WM_DROPOBJECT,
Hier ist ein Beispiel das zeigt, wie Console-Programm mit CreateThread() ein Window-Fenster erzeugt und die Console-Eingaben in ein EDIT-Fenster schreiben kann.