Diese Applikationsschrift beschreibt die MFC-Nachricht Karte Anlage.
Das Problem
Microsoft Windows implementiert, was im wesentlichen virtuelle Funktionen im Fensterklassen mit ihrer messaging-Service sind. Aufgrund der großen Anzahl von Nachrichten an in eine übermäßig große Vtable Ergebnisse Bereitstellen einer separaten virtuellen Funktion für jede Windows-Nachricht.
Außerdem bietet da die Anzahl der vom System definierte Windows-Meldungen im Laufe der Zeit ändert, und eine bestimmte Anwendung einige Windows-Meldungen für sich definieren möchten, der Meldungszuordnung Mechanismus eine Dereferenzierungsebene, die verhindert, dass Änderungen an der Benutzeroberfläche vorhandenen Code beschädigen.
Übersicht
MFC bietet eine Alternative zu der Switch-Anweisung, die in traditionellen Windows-Programmen verwendet, um Nachrichten an ein Fenster zu behandeln. Eine Zuordnung von Nachrichten zu Memberfunktionen kann definiert werden, so dass wenn eine Nachricht von einem Fenster verarbeitet werden, automatisch die entsprechende Memberfunktion aufgerufen wird. Diese Einrichtung Meldungszuordnung virtuelle Funktionen ähneln soll aber hat zusätzliche Vorteile mit virtuelle C++-Funktionen nicht möglich.
Definieren einer Meldungszuordnung
Das DECLARE_MESSAGE_MAP Makro deklariert drei Member für eine Klasse.
Dieses Makro sollte in der Deklaration einer Klasse mit Meldungszuordnungen platziert werden. Gemäß der Konvention ist es am Ende der Klassendeklaration. Zum Beispiel:
klasse CMyWnd: öffentliche CMyParentWndClass
{
&Nbsp; / / meine Sachen...
geschützt:
//{{AFX_MSG(CMyWnd)
Afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
Dies ist das Format von AppWizard und ClassWizard generiert, wenn sie neue Klassen erstellen. Der / / {{und / /}} Klammern sind erforderlich für die Klassen-Assistent.
Die Meldungszuordnung Tabelle wird mit einem Satz von Makros definiert, die auf Nachricht Zuordnungseinträge zu erweitern. Eine Tabelle beginnt mit einem BEGIN_MESSAGE_MAP Makro-Aufruf, der definiert die Klasse, die von diesem Meldungszuordnung verarbeitet wird und die übergeordnete Klasse, nicht verarbeitete Nachrichten übergeben werden. Die Tabelle endet mit dem END_MESSAGE_MAP -Makro-Aufruf.
Zwischen diesen beiden Makroaufrufe ist ein Eintrag für jede Nachricht von diesem Meldungszuordnung verarbeitet werden. Jedes standard Windows-Nachricht hat ein Makro der Form ON_WM_xxx (wobei Xxx der Name der Nachricht ist), die einen Eintrag für diese Nachricht generiert.
Eine Standardfunktion-Signatur wurde für die Parameter der einzelnen Windows-Nachrichten Auspacken und bieten Typsicherheit definiert. Diese Signaturen finden in der Datei AFXWIN.H in der Deklaration von CWnd. Jeder ist mit dem Wort Afx_msg für einfache Identifizierung markiert.
Hinweis&Nbsp; Klassen-Assistent erfordert, dass Sie das Afx_msg -Schlüsselwort in Ihre Nachricht Karte Handler Deklarationen verwenden.
Diese Funktionssignaturen wurden mit eine einfache Konvention abgeleitet. Der Name der Funktion beginnt immer mit "On". Es folgt der Name der Windows-Nachricht mit der WM_ entfernt und nur der erste Buchstaben jedes Wortes groß geschrieben. Ist die Reihenfolge der Parameter wParam gefolgt von LOWORD (, dann HIWORD(lParam)lParam) . Nicht verwendete Parameter werden nicht weitergegeben. Alle Handles, die von MFC-Klassen eingeschlossen sind, werden in Zeiger auf die entsprechende MFC-Objekte konvertiert. Im folgenden Beispiel wird veranschaulicht, wie die WM_PAINT -Nachricht verarbeiten und dazu führen, dass die CMyWnd:: OnPaint Funktion aufgerufen werden
BEGI&N_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
Nbsp; //{{AFX_MSG_MAP(CMyWnd)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Der Nachricht Zuordnungstabelle muss außerhalb des Bereichs der jede Funktion oder Klassendefinition definiert werden. Es sollte nicht in einen Extern "C"-Block platziert werden.
Hinweis&Nbsp; ClassWizard bearbeiten wird die Nachricht anzeigen-Einträge, die zwischen den / / {{und / /}} Kommentar Halterung.
Benutzerdefinierte Windows-Meldungen
Benutzerdefinierte Meldungen können mithilfe des Makros ON_MESSAGE in eine Meldungszuordnung aufgenommen werden. Dieses Makro akzeptiert eine Meldungsnummer und eine Member-Funktion der form:
&Nbsp; / / innerhalb der Klassendeklaration der
Afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
Zum Beispiel:
# define WM_MYMESSAGE (WM_USER + 100)
BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
ON_MESSAGE (WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()
In diesem Beispiel erstellen wir einen Handler für eine benutzerdefinierte Meldung mit eine Windows-Meldungs-ID abgeleitet aus der Norm WM_USER Basis für benutzerdefinierte Meldungen. Sie könnte dieser Handler mit Code wie z. B. aufrufen:
CWnd * pWnd =...;
pWnd-≫SendMessage(WM_MYMESSAGE)
Der Bereich der benutzerdefinierte Nachrichten mit diesem Ansatz muss im Bereich WM_USER bis 0x7fff sein.
Hinweis&Nbsp; Klassen-Assistent unterstützt keine Eingabe ON_MESSAGE Handler-Routinen aus der Klassen-Assistent-Benutzeroberfläche: müssen Sie sie manuell aus dem Visual C++-Editor eingeben. Einmal eingegeben, Klassen-Assistent analysiert diese Einträge und können Sie sie wie jede andere Meldungszuordnungseinträge durchsuchen.
Registrierte Windows-Meldungen
Die :: RegisterWindowMessage Funktion wird verwendet, um eine neue Fensternachricht definieren, die garantiert ist eindeutig im gesamten System. Das Makro ON_REGISTERED_MESSAGE wird verwendet, um diese Meldungen zu behandeln. Das Makro akzeptiert ein der Namen einer nahe UINT-Variablen, die den registrierten Windows enthält message ID Zum Beispiel
klasse CMyWnd: öffentliche CMyParentWndClass
{
Öffentliche:
&Nbsp; CMyWnd();
//{{AFX_MSG(CMyWnd)
Afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
statische UINT in der Nähe von WM_FIND = RegisterWindowMessage("COMMDLG_FIND");
BEGIN_MESSAGE_MAP (CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_REGISTERED_MESSAGE (WM_FIND, OnFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Die registrierte Windows-ID Nachrichtenvariable (WM_FIND im obigen Beispiel) muss eine nahe Variable aufgrund der Art und Weise ON_REGISTERED_MESSAGE implementiert ist.
Das Spektrum der benutzerdefinierte Nachrichten mit diesem Ansatz werden im Bereich von 0xC000 bis 0xFFFF.
Hinweis&Nbsp; ClassWizard Eingabe ON_REGISTERED_MESSAGE Handler-Routinen aus der Klassen-Assistent-Benutzeroberfläche nicht unterstützt, müssen Sie sie manuell aus dem Texteditor eingeben. Einmal eingegeben, Klassen-Assistent analysiert diese Einträge und können Sie sie wie jede andere Meldungszuordnungseinträge durchsuchen.
Befehlsmeldungen
Befehlsmeldungen von Menüs und Zugriffstasten werden in Meldungszuordnungen mit dem Makro ON_COMMAND behandelt. Dieses Makro akzeptiert eine Befehls-ID als auch eine Member-Funktion. Nur die bestimmte WM_COMMAND -Meldung mit wParam gleich den angegebenen Befehl, die, den von der Memberfunktion ID behandelt wird, in der Meldungszuordnung Eintrag angegeben. Befehl Handler-Memberfunktionen nehmen keine Parameter und void zurückgeben. Das Makro hat die form:
ON_COMMAND (Id, MemberFxn)
Befehl Update Nachrichten werden durch den gleichen Mechanismus wie Handler ON_COMMAND weitergeleitet. Das Makro ON_UPDATE_COMMAND_UI wird stattdessen verwendet. Befehl Update Member Handlerfunktionen nehmen einen einzelnen Parameter, der einen Zeiger auf ein Objekt der CCmdUI und void zurückgeben. Das Makro hat die form
ON_UPDATE_COMMAND_UI-Id (MemberFxn)
Eine erweiterte Form der Befehl Message Handler ist verfügbar für Fortgeschrittene Anwender. Das ON_COMMAND_EX -Makro wird stattdessen verwendet und stellt eine Obermenge der ON_COMMAND -Funktionalität. Erweiterte Befehlshandler Member-Funktionen nehmen einen einzelnen Parameter, mit die Befehls-ID, UINT und einen booleschen Wert zurück. Die BOOL zurückgeben true sollte darauf hinweisen, dass der Befehl verarbeitet wurde, wird sonst auf andere Zielobjekte Befehl weiterzuleiten.
Beispiele für die genannten Formen:
#defi&nenbsp; ID_MYCMD 100
# define ID_COMPLEX 101
afx_msg void OnMyCommand();
Afx_msg void OnUpdateMyCommand (CCmdUI * pCmdUI);
Afx_msg BOOL OnComplexCommand(UINT nID)
ON_COMMAND (ID_MYCMD, OnMyCommand)
ON_UPDATE_COMMAND_UI (ID_MYCMD, OnUpdateMyCommand)
ON_COMMAND_EX (ID_MYCMD, OnComplexCommand)
void CMyClass::OnMyCommand()
{
&Nbsp; / / handle des Befehls
}
privatevoid CMyClass::OnUpdateMyCommand (CCmdUI pCmdUI)
{
/ / set den Benutzeroberflächenzustand mit pCmdUI
}
BOOL CMyClass::OnComplexCommand(UINT nID)
{
/ / handle des Befehls
TRUE zurück;
}
Auch erhältlich für fortgeschrittene Benutzer ist ON_COMMAND_RANGE und ON_COMMAND_RANGE_EX , die Ihnen ermöglichen, eine Reihe von Befehlen mit einem einzigen Befehl Ereignishandler behandeln. Lesen Sie die Produktdokumentation für weitere Informationen zu diesen Makros.
Hinweis&Nbsp; ClassWizard unterstützt ON_COMMAND und ON_UPDATE_COMMAND_UI -Handler erstellen, aber es unterstützt nicht die Erstellung von ON_COMMAND_EX oder ON_COMMAND_RANGE -Handler. Jedoch Klassen-Assistent analysiert und ermöglichen es Ihnen, alle drei Befehl Handler Varianten durchsuchen.
Steuerelement-Benachrichtigungen
Nachrichten, die gesendet werden von untergeordneten Steuerelementen in einem Fenster haben eine zusätzliche bit von Informationen in ihrer Nachricht Zuordnung Eintrag: die Steuerelement-ID Der Message-Handler in einer Nachricht Zuordnungseintrag angegeben wird nur aufgerufen, wenn (1) die Benachrichtigung Steuerungscode (hohe Wort von lParam), wie z. B. BN_CLICKED, entspricht der Benachrichtigungscode in der Meldungszuordnung Eintrag angegeben und (2) die Steuerelement-ID (wParam) der in der Meldungszuordnung Eintrag angegebenen Steuerelement-ID entspricht.
Benutzerdefiniertes Steuerelement-Benachrichtigungen können das ON_CONTROL -Makro verwenden, um eine Nachricht Zuordnungseintrag mit einer benutzerdefinierten Benachrichtigung zu definieren. Dieses Makro hat die form
ON_CONTROL (Id, wNotificationCode, MemberFxn)
Für die Fortgeschrittene Benutzung kann ON_CONTROL_RANGE verwendet werden, um eine bestimmtes Steuerelement-Benachrichtigung aus einer Reihe von Steuerelementen mit den gleichen Handler behandeln.
ClassWizard unterstützt nicht das Erstellen eines ON_CONTROL oder ON_CONTROL_RANGE -Handlers in der Benutzeroberfläche; Sie müssen sie manuell mit dem Texteditor eingeben. Einmal eingegeben, Klassen-Assistent analysiert diese Einträge und können Sie sie wie jede andere Nachricht Zuordnungseinträge durchsuchen.
Der allgemeinen Windows-Steuerelementen nutzen die leistungsfähigere WM_NOTIFY für komplexe Steuerelement-Benachrichtigungen. Diese Version von MFC hat direkten Unterstützung für diese neue Meldung mit den Makros ON_NOTIFY und ON_NOTIFY_RANGE . Lesen Sie die Produktdokumentation für weitere Informationen zu diesen Makros.
Technische Hinweise von &Nummer |nbsp; Technische Hinweise nach Kategorie