Windows-Codierungskonventionen
Wenn Sie noch nicht mit der Windows-Programmierung sind, kann es beunruhigend sein, wenn Sie zum ersten Mal ein Windows-Programm sehen. Der Code ist mit seltsamen Typdefinitionen wie DWORD_PTR und LPRECT gefüllt, und Variablen haben Namen wie hWnd und pwsz (ungarische Notation genannt). Es lohnt sich, sich einen Moment Zeit zu nehmen, um einige der Windows-Codierungskonventionen kennenzulernen.
Die überwiegende Mehrheit der Windows-APIs besteht aus Funktionen oder COM-Schnittstellen (Component Object Model). Nur sehr wenige Windows-APIs werden als C++-Klassen bereitgestellt. (Eine bemerkenswerte Ausnahme ist GDI+, eine der 2D-Grafik-APIs.)
TypeDefs
Die Windows-Header enthalten viele Typbeschreibungen. Viele davon sind in der Headerdatei WinDef.h definiert. Hier sind einige, die Sie häufig treffen werden.
Ganzzahltypen
Datentyp | Size | Unterzeichnet? |
---|---|---|
BYTE | 8 Bit | Ohne Vorzeichen |
DWORD | 32 Bit | Ohne Vorzeichen |
INT32 | 32 Bit | Signiert |
INT64 | 64 Bit | Signiert |
LONG | 32 Bit | Signiert |
LONGLONG | 64 Bit | Signiert |
UINT32 | 32 Bit | Ohne Vorzeichen |
UINT64 | 64 Bit | Ohne Vorzeichen |
ULONG | 32 Bit | Ohne Vorzeichen |
ULONGLONG | 64 Bit | Ohne Vorzeichen |
WORD | 16 Bit | Ohne Vorzeichen |
Wie Sie sehen, gibt es in diesen Typbeschreibungen eine gewisse Redundanz. Einige dieser Überschneidungen sind einfach auf den Verlauf der Windows-APIs zurückzuführen. Die hier aufgeführten Typen haben eine feste Größe, und die Größen sind in 32-Bit- und 64-Anwendungen identisch. Der DWORD-Typ ist beispielsweise immer 32 Bit breit.
Boolescher Typ
BOOL ist ein Typalias für int, der sich vom Bool von C++ und anderen Typen unterscheidet, die einen booleschen Wert darstellen. Die Headerdatei WinDef.h
definiert auch zwei Werte für die Verwendung mit BOOL.
#define FALSE 0
#define TRUE 1
Trotz dieser Definition von TRUE können die meisten Funktionen, die einen BOOL-Typ zurückgeben, einen beliebigen Wert ungleich 0 zurückgeben, um die boolesche Wahrheit anzugeben. Daher sollten Sie immer Folgendes schreiben:
// Right way.
if (SomeFunctionThatReturnsBoolean())
{
...
}
// or
if (SomeFunctionThatReturnsBoolean() != FALSE)
{
...
}
und nicht folgendes:
if (result == TRUE) // Wrong!
{
...
}
BOOL ist ein ganzzahliger Typ und kann nicht mit dem Bool von C++ ausgetauscht werden.
Zeigertypen
Windows definiert viele Datentypen des Formulars zeiger-auf-X. Diese haben in der Regel das Präfix P- oder LP- im Namen. LPRECT ist beispielsweise ein Zeiger auf ein RECT, wobei RECT eine Struktur ist, die ein Rechteck beschreibt. Die folgenden Variablendeklarationen sind gleichwertig.
RECT* rect; // Pointer to a RECT structure.
LPRECT rect; // The same
PRECT rect; // Also the same.
Auf 16-Bit-Architekturen (16-Bit-Windows) gibt es zwei Arten von Zeigern, P für "Zeiger" und LP steht für "langer Zeiger". Lange Zeiger (auch als Fernzeiger bezeichnet) wurden benötigt, um Speicherbereiche außerhalb des aktuellen Segments zu adressieren. Das LP-Präfix wurde beibehalten, um das Portieren von 16-Bit-Code auf 32-Bit-Windows zu erleichtern. Heute gibt es keine Unterscheidung, und diese Zeigertypen sind alle gleichwertig. Vermeiden Sie die Verwendung dieser Präfixe. oder wenn Sie einen verwenden müssen, verwenden Sie P.
Zeigergenauigkeitstypen
Die folgenden Datentypen sind immer die Größe eines Zeigers, d. h. 32 Bit breit in 32-Bit-Anwendungen und 64 Bit breit in 64-Bit-Anwendungen. Die Größe wird zur Kompilierzeit bestimmt. Wenn eine 32-Bit-Anwendung unter 64-Bit-Windows ausgeführt wird, sind diese Datentypen immer noch 4 Bytes breit. (Eine 64-Bit-Anwendung kann nicht unter 32-Bit-Windows ausgeführt werden, sodass die umgekehrte Situation nicht auftritt.)
- DWORD_PTR
- INT_PTR
- LONG_PTR
- ULONG_PTR
- UINT_PTR
Diese Typen werden in Situationen verwendet, in denen eine ganze Zahl in einen Zeiger umgewandelt werden kann. Sie werden auch verwendet, um Variablen für die Zeigerarithmetik zu definieren und Schleifenzähler zu definieren, die über den gesamten Bytebereich in Speicherpuffern durchlaufen. Im Allgemeinen werden sie an Stellen angezeigt, an denen ein vorhandener 32-Bit-Wert auf 64 Bit unter 64-Bit-Windows erweitert wurde.
Ungarische Notation
Ungarische Notation ist die Praxis des Hinzufügens von Präfixen zu den Namen von Variablen, um zusätzliche Informationen über die Variable zu geben. (Der Erfinder der Notation, Charles Simonyi, war ungarisch, daher sein Name).
In ihrer ursprünglichen Form gibt die ungarische Notation semantische Informationen über eine Variable und informiert Sie über die beabsichtigte Verwendung. Zum Beispiel bedeutet i einen Index, cb bedeutet eine Größe in Bytes ("Anzahl der Bytes"), und rw und col mittlere Zeilen- und Spaltennummern. Diese Präfixe sind so konzipiert, dass die versehentliche Verwendung einer Variablen im falschen Kontext vermieden wird. Wenn Sie beispielsweise den Ausdruck rwPosition + cbTable
sehen, würden Sie wissen, dass einer Größe eine Zeilennummer hinzugefügt wird. Dies ist mit ziemlicher Sicherheit ein Fehler im Code.
Eine häufigere Form der ungarischen Notation verwendet Präfixe, um Typinformationen zu geben, z. B . dw für DWORD und w für WORD.
Hinweis
In den C++-Kernrichtlinien wird die Präfixnotation (z. B. ungarische Notation) abgeraten. Siehe NL.5: Vermeiden von Codierungstypinformationen in Namen. Intern verwendet das Windows-Team sie nicht mehr. Seine Verwendung bleibt jedoch in Beispielen und dokumentationen bestehen.