TN001: Fensterklassenregistrierung

In diesem Hinweis werden die MFC-Routinen beschrieben, die die speziellen WNDCLASS-Routinenregistrieren, die von Microsoft Windows benötigt werden. Spezifische WNDCLASS Attribute, die von MFC und Windows verwendet werden, werden erläutert.

Problemstellung

Die Attribute eines CWnd-Objekts , z. B. ein HWND Handle in Windows, werden an zwei Stellen gespeichert: das Fensterobjekt und das WNDCLASS. Der Name des WNDCLASS Fensters wird an allgemeine Fenstererstellungsfunktionen wie CWnd::Create und CFrameWnd::Create im lpszClassName-Parameter übergeben.

Dies WNDCLASS muss mit einem von vier Mitteln registriert werden:

  • Implizit mithilfe eines bereitgestellten WNDCLASSMFC.

  • Implizit durch Unterklassen eines Windows-Steuerelements (oder eines anderen Steuerelements).

  • Explizit durch Aufrufen der MFC AfxRegisterWndClass oder AfxRegisterClass.

  • Explizit durch Aufrufen der Windows-Routine RegisterClass.

WNDCLASS-Felder

Die WNDCLASS Struktur besteht aus verschiedenen Feldern, die eine Fensterklasse beschreiben. Die folgende Tabelle zeigt die Felder und gibt an, wie sie in einer MFC-Anwendung verwendet werden:

Feld Beschreibung
lpfnWndProc Fenster proc, muss ein AfxWndProc
cbClsExtra nicht verwendet (sollte null sein)
cbWndExtra nicht verwendet (sollte null sein)
Hinstance automatisch mit AfxGetInstanceHandle gefüllt
hIcon symbol für Rahmenfenster, siehe unten
hCursor cursor for when mouse is over window, see below
hbrBackground Hintergrundfarbe, siehe unten
lpszMenuName nicht verwendet (sollte NULL sein)
lpszClassName Klassenname, siehe unten

Bereitgestellte WNDCLASSes

Frühere Versionen von MFC (vor MFC 4.0) haben mehrere vordefinierte Window-Klassen bereitgestellt. Diese Window-Klassen werden standardmäßig nicht mehr bereitgestellt. Anwendungen sollten mit den entsprechenden Parametern verwendet werden AfxRegisterWndClass .

Wenn die Anwendung eine Ressource mit der angegebenen Ressourcen-ID (z. B. AFX_IDI_STD_FRAME) bereitstellt, verwendet MFC diese Ressource. Andernfalls wird die Standardressource verwendet. Für das Symbol wird das Standardanwendungssymbol verwendet, und für den Cursor wird der Standardpfeilcursor verwendet.

Zwei Symbole unterstützen MDI-Anwendungen mit einzelnen Dokumenttypen: ein Symbol für die Standard Anwendung, das andere Symbol für Iconic-Dokument-/MDIChild-Fenster. Für mehrere Dokumenttypen mit unterschiedlichen Symbolen müssen Sie zusätzliche WNDCLASSEs registrieren oder die CFrameWnd::LoadFrame-Funktion verwenden.

CFrameWnd::LoadFrame registriert eine WNDCLASS Verwendung der Symbol-ID, die Sie als ersten Parameter und die folgenden Standardattribute angeben:

  • Klassenformat : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

  • symbol AFX_IDI_STD_FRAME

  • Pfeilcursor

  • COLOR_WINDOW Hintergrundfarbe

Die Werte für Hintergrundfarbe und Cursor für cmDIFrameWnd werden nicht verwendet, da der Clientbereich des Fensters CMDIFrameWnd vollständig vom MDICLIENT-Fenster abgedeckt wird. Microsoft ermutigt die Unterklassen des MDICLIENT-Fensters nicht, sodass Sie nach Möglichkeit die Standardfarben und Cursortypen verwenden.

Unterklassen- und Superklassensteuerelemente

Wenn Sie eine Unterklasse oder eine Superklasse eines Windows-Steuerelements (z. B. CButton) verwenden, ruft Ihre Klasse automatisch die Attribute ab, die WNDCLASS in der Windows-Implementierung dieses Steuerelements bereitgestellt werden.

Die AfxRegisterWndClass-Funktion

MFC stellt eine Hilfsfunktion zum Registrieren einer Fensterklasse bereit. Angesichts einer Reihe von Attributen (Fensterklassenformat, Cursor, Hintergrundpinsel und Symbol), wird ein synthetischer Name generiert, und die resultierende Fensterklasse wird registriert. Ein auf ein Objekt angewendeter

const char* AfxRegisterWndClass(UINT nClassStyle,
    HCURSOR hCursor,
    HBRUSH hbrBackground,
    HICON hIcon);

Diese Funktion gibt eine temporäre Zeichenfolge des generierten Namen der registrierten Fensterklasse zurück. Weitere Informationen zu dieser Funktion finden Sie unter AfxRegisterWndClass.

Die zurückgegebene Zeichenfolge ist ein temporärer Zeiger auf einen statischen Zeichenfolgenpuffer. Es ist gültig, bis der nächste Aufruf von AfxRegisterWndClass. Wenn Sie diese Zeichenfolge beibehalten möchten, speichern Sie sie wie in diesem Beispiel in einer CString-Variablen :

CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);

...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);

...

AfxRegisterWndClass löst eine CResourceException aus, wenn die Fensterklasse nicht registriert werden konnte (entweder aufgrund fehlerhafter Parameter oder außerhalb des Windows-Speichers).

Die Funktionen RegisterClass und AfxRegisterClass

Wenn Sie etwas komplexeres tun möchten als das, was AfxRegisterWndClass bereitgestellt wird, können Sie die Windows-API RegisterClass oder die MFC-Funktion AfxRegisterClassaufrufen. Die CWndFunktionen CFrameWnd und CMDIChildWndCreate verwenden einen lpszClassName-Zeichenfolgennamen für die Fensterklasse als ersten Parameter. Sie können jeden registrierten Fensterklassennamen verwenden, unabhängig von der Methode, die Sie zum Registrieren verwendet haben.

Es ist wichtig, in einer DLL in Win32 (oder AfxRegisterWndClass) zu verwenden AfxRegisterClass . Win32 hebt die Registrierung von Klassen, die von einer DLL registriert wurden, nicht automatisch auf, daher müssen Sie die Registrierung von Klassen explizit aufheben, wenn die DLL beendet wird. AfxRegisterClass Anstelle dieses Vorgangs RegisterClass wird dies automatisch für Sie behandelt. AfxRegisterClassStandard enthält eine Liste eindeutiger Klassen, die von Ihrer DLL registriert sind, und hebt die Registrierung automatisch auf, wenn die DLL beendet wird. Wenn Sie in einer DLL verwenden RegisterClass , müssen Sie sicherstellen, dass alle Klassen nicht registriert werden, wenn die DLL beendet wird (in Ihrer DllMain-Funktion ). Dies kann dazu führen RegisterClass , dass unerwartet ein Fehler auftritt, wenn eine andere Clientanwendung versucht, Ihre DLL zu verwenden.

Siehe auch

Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet