TN006: Meldungszuordnungen
Dieser Hinweis wird die Funktion für MFC-Meldungszuordnungs.
Das Problem
Microsoft Windows implementiert virtuelle Funktionen in Fensterklassen, die das Feature für Messaging verwenden.Aufgrund der großen Anzahl von Nachrichten, die eine separate virtuelle Funktion für jede Windows-Meldung Bereitstellen beteiligt sind, ist kostspielig. B. ein umfangreiches vtable erstellen.
Da die Anzahl der systemdefinierten Windows-Meldungen im Zeitverlauf ändert und da Anwendungen eigene Windows-Meldungen definieren können, stellen Meldungszuordnungen eine Dereferenzierungsebene Schnittstellen, die Änderungen aus dem Unterbrechen von vorhandenem Code verhindert.
Übersicht
MFC stellt eine Alternative zur switch-Anweisung bereit, die in herkömmlichen Windows-basierten Programmen verwendet wurde, um die Meldungen zu behandeln, die einem Fenster gesendet wurden.Eine Zuordnung von Nachrichten an Methoden kann definiert werden, dass, wenn eine Nachricht von einem Fenster empfangen wird, die entsprechende Methode automatisch aufgerufen wird.Diese Funktion ist für Meldungszuordnungs mit virtuellen Funktionen entsprechen aber die zusätzlichen Vorteile verfügt, die mit virtuellen Funktionen C++ nicht möglich sind.
Eine Meldungszuordnung definieren
Das DECLARE_MESSAGE_MAP Makro deklariert drei Member einer Klasse.
Ein privates Array AFX_MSGMAP_ENTRY Einträge namens _messageEntries an.
Eine geschützte AFX_MSGMAP-Struktur hat messageMap an, die dem _messageEntries Array verweist.
Eine geschützte virtuelle Funktion namens GetMessageMap an, die die Adresse von messageMap zurückgibt.
Dieses Makro sollte in die Deklaration einer Klasse unter Verwendung der Meldungszuordnungen platziert werden.Üblicherweise handelt es am Ende der Klassendeklaration.Beispiele:
class CMyWnd : public CMyParentWndClass
{
// my stuff...
protected:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Dies ist das Format, das vom Anwendungs-Assistenten generierten und ClassWizard, wenn sie neue Klassen erstellen.Die Klammern {{//und //}} werden für ClassWizard erfordert.
Die Tabelle der Meldungszuordnung wird definiert, indem eine Reihe von Makros verwendet, die den Meldungszuordnungs Einträgen erweitern.Starten einer Tabelle mit einem BEGIN_MESSAGE_MAP Makro-Aufruf, der die Klasse definiert, die von dieser Meldungszuordnung sowie die übergeordnete Klasse behandelt wird, auf die nicht behandelte Meldungen übergeben werden.Die Tabellen endet mit dem END_MESSAGE_MAP Makro-Aufruf.
Zwischen diesen beiden Makro-Aufrufen ist ein Eintrag für jede Meldung durch diese Meldungszuordnung behandelt werden kann.Jede Standardwert windows-meldung verfügt über ein Makro des Formulars ON_WM_MESSAGE_NAME, das einen Eintrag für diese Nachricht generiert.
Eine standardmäßige funktions Signatur ist für das Entpacken der Parameter jeder Windows-Meldung und Bereitstellen von Typsicherheit definiert.Diese Signaturen werden in der Datei Afxwin.h in der Deklaration von CWnd gefunden werden.Jedes ist dem Schlüsselwort afx_msg für eine problemlose Identifizierung markiert.
Hinweis |
---|
ClassWizard erfordert, dass Sie das afx_msg-Schlüsselwort in den Meldungszuordnungs für Deklarationen verwenden. |
Diese Funktion unterzeichnungen abgeleitet wurden, indem eine einfache Konvention frei.Der Name der Funktion immer mit "On" beginnt.Dies wird durch den Namen der Windows-Meldung mit dem "," gefolgt WM_ die entfernt wird und der erste Buchstabe jedes Worts gegroßschriebenen.Die Reihenfolge der Parameter ist wParam, das von LOWORD(lParam) und wird dann HIWORD(lParam).Nicht verwendete Parameter nicht übergeben.Alle Handles, die von MFC-Klassen umschlossen werden, werden den entsprechenden MFC-Objekten Zeiger konvertiert.Im folgenden Beispiel wird gezeigt, wie die WM_PAINT Meldung behandelt und die CMyWnd::OnPaint-Funktion wird aufgerufen:
BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Die Tabelle muss Meldungszuordnungs außerhalb des Gültigkeitsbereichs einer Funktion oder Klassendefinition definiert sind.Sie muss einen Block nicht extern "C" versetzt werden.
Hinweis |
---|
ClassWizard ändert die Meldungszuordnungs Dateisystemeinträgen, die zwischen dem Kommentar um auftretende Klammer //und //{{}}. |
Benutzerdefinierte Windows-Meldungen
Benutzerdefinierte Meldungen werden in einer Meldungszuordnung aufgenommen werden, indem das ON_MESSAGE Makro verwendet.Dieses Makro akzeptiert eine Meldungsnummer und eine Methode des Formulars:
// inside the class declaration
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
#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 Nachricht, die eine Windows-Meldung ID verfügt, die von der Standard- WM_USER Basis für benutzerdefinierte Meldungen abgeleitet ist.Das folgende Beispiel zeigt, wie dieser Handler aufgerufen wird:
CWnd* pWnd = ...;
pWnd->SendMessage(WM_MYMESSAGE);
Der Bereich von benutzerdefinierten Meldungen, die diesen Ansatz verwenden, muss im Bereich WM_USER zu 0x7fff sein.
Hinweis |
---|
ClassWizard unterstützt nicht das Eingeben von ON_MESSAGE-Handler routinen aus der ClassWizard-Benutzeroberfläche.Sie müssen sie vom Visual C++-Editor manuell eingeben.ClassWizard analysiert diese Einträge und Sie können sie gerade wie alle anderen Meldungszuordnungseinträge durchsuchen. |
Registrierte Windows-Meldungen
Die RegisterWindowMessage-Funktion wird verwendet, um eine Meldung des neuen Fensters zu definieren, die gewährleistet wird, um während des Systems eindeutig sein.Makro- ON_REGISTERED_MESSAGE wird verwendet, um diese Meldungen zu bearbeiten.Dieses Makro nimmt einen Namen einer UINT NEAR-Variable, die die registrierte Fenstermeldung ID enthält.Beispiel:
class CMyWnd : public CMyParentWndClass
{
public:
CMyWnd();
//{{AFX_MSG(CMyWnd)
afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
static UINT NEAR 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-Meldung ID variable (WM_FIND in diesem Beispiel) muss eine Variable sein NEAR aufgrund der Methode, die ON_REGISTERED_MESSAGE implementiert wird.
Der Bereich von benutzerdefinierten Meldungen, die diesen Ansatz verwenden, ist im Bereich 0xC000 0xFFFF soll.
Hinweis |
---|
ClassWizard unterstützt nicht das Eingeben von ON_REGISTERED_MESSAGE-Handler routinen aus der ClassWizard-Benutzeroberfläche.Sie müssen sie aus dem Texteditor manuell eingeben.ClassWizard analysiert diese Einträge und Sie können sie gerade wie alle anderen Meldungszuordnungseinträge durchsuchen. |
Befehls-Meldungen
Meldungen Befehls Menüs und Tastenkombinationen werden in den Meldungszuordnungen mit dem ON_COMMAND Makro behandelt.Dieses Makro akzeptiert eine Befehls-ID und eine Methode.Nur die bestimmte WM_COMMAND Meldung, die wParam gleich der angegebenen Befehls-ID besitzt, wird von der Methode behandelt, die im Meldungszuordnungseintrag angegeben wird.Befehlshandler Memberfunktionen keine Parameter annehmen und geben void.Das Makro hat das folgende Format:
ON_COMMAND(id, memberFxn)
Aktualisieren der Befehl Meldungen werden nach demselben Verfahren umgeleitet, aber das ON_UPDATE_COMMAND_UI Makro Version verwenden.Befehl aktualisierungshandler Memberfunktionen akzeptieren einen einzelnen Parameter, um einen Zeiger auf einen CCmdUI-Objekt und geben void.Das Makro hat das Formular
ON_UPDATE_COMMAND_UI(id, memberFxn)
Fortgeschrittene Benutzer können das ON_COMMAND_EX Makros, die ein erweitertes Form eines Befehls Message-Handlern ist.Das Makro stellt eine Obermenge der ON_COMMAND-Funktionalität.Erweiterte Befehl Handler Memberfunktionen akzeptieren einen einzelnen Parameter, UINT, der die Befehls-ID enthält, und geben BOOL zurück.Der Rückgabewert muss angegeben sein, TRUE, dass der Befehl verarbeitet wurde.Andernfalls wird das Routing zu einem anderen Befehl zielobjekten fort.
Beispiele für diese Arten:
Inneres Resource.h generiert (üblicherweise von Visual C++)
#define ID_MYCMD 100 #define ID_COMPLEX 101
Innerhalb der Klassendeklaration
afx_msg void OnMyCommand(); afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI); afx_msg BOOL OnComplexCommand(UINT nID);
Innerhalb der Definition Meldungszuordnungs
ON_COMMAND(ID_MYCMD, OnMyCommand) ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand) ON_COMMAND_EX(ID_MYCMD, OnComplexCommand)
In der Implementierungsdatei
void CMyClass::OnMyCommand() { // handle the command } void CMyClass::OnUpdateMyCommand(CCmdUI* pCmdUI) { // set the UI state with pCmdUI } BOOL CMyClass::OnComplexCommand(UINT nID) { // handle the command return TRUE; }
Fortgeschrittene Benutzer können eine Reihe von Befehlen behandeln, indem Sie einen Handler des einzigen Befehl verwenden: ON_COMMAND_RANGE oder ON_COMMAND_RANGE_EX.Informationen finden Sie in der Produktdokumentation Informationen zu diesen Makros.
Hinweis |
---|
ClassWizard unterstützt das Erstellen von ON_COMMAND und ON_UPDATE_COMMAND_UI-Handlern, aber es unterstützt keine die Erstellung von ON_COMMAND_EX oder ON_COMMAND_RANGE-Handlern.Klassen-Assistent und analysiert wurde jedoch alle vier Befehlshandler varianten durchsuchen. |
Steuerelementbenachrichtigungs-Meldungen
Meldungen, die von den untergeordneten Steuerelementen in einem Fenster gesendet wurden, verfügen über eine zusätzliche Informationen im Eintrag Meldungszuordnungs: die ID des SteuerelementsDer Meldungshandler, der sich in einem Eintrag Meldungszuordnungs angegeben ist, wird nur aufgerufen, wenn die folgenden Bedingungen erfüllt sind:
Der Code Steuerelementbenachrichtigungs (höherwertiges Wort lParam) aus, z. B. BN_CLICKED, stimmt mit dem Benachrichtigungscode ab, der im Meldungszuordnungseintrag angegeben wird.
Die Steuerelement-ID (wParam) stimmt die Steuerelement-ID ab, die im Meldungszuordnungseintrag angegeben wird.
Benutzerdefinierte Meldungen können das ON_CONTROL-Steuerelementbenachrichtigungs Makro, um Meldungszuordnungs einen Eintrag mit einem benutzerdefinierten Benachrichtigungscode zu definieren.Dieses Makro hat das Formular
ON_CONTROL(wNotificationCode, id, memberFxn)
Für erweiterte Verwendung ON_CONTROL_RANGE kann verwendet werden, um eine bestimmte Steuerelementbenachrichtigung von einem Bereich von Steuerelementen mit demselben Handler zu bearbeiten.
Hinweis |
---|
ClassWizard unterstützt nicht das Erstellen eines ON_CONTROL oder ON_CONTROL_RANGE-Handlers in der Benutzeroberfläche.Sie müssen sie mit dem Texteditor manuell eingeben.ClassWizard analysiert wurde und diese Einträge derzeit Sie diese wie alle anderen Meldungszuordnungs Dateisystemeinträgen durchsuchen. |
Die allgemeinen Windows-Steuerelemente verwenden leistungsstarkere für komplexe WM_NOTIFY-Steuerelementbenachrichtigungen.Diese Version von MFC verfügt über direkte Unterstützung für diese neue Meldung, indem die ON_NOTIFY und ON_NOTIFY_RANGE Makros verwendet.Informationen finden Sie in der Produktdokumentation Informationen zu diesen Makros.