TN006: Mapy zprávy
Tato poznámka popisuje zařízení MFC zpráva mapy.
Problém
Microsoft Windows implementuje virtuální funkce tříd okno používající její zařízení pro zasílání zpráv.Kvůli velký počet zpráv, které by poskytování oddělené virtuální funkce každé zprávy systému Windows vytvořit virtuální prohibitively velká tabulka.
Protože počet zpráv definované v systému Windows v čase, a protože aplikace můžete definovat své vlastní zprávy systému Windows, mapuje zprávy poskytují úroveň nepřímé odkazování, který zabrání rozdělení existující kód změny rozhraní.
Přehled
MFC poskytuje alternativu k příkazu switch použitý tradiční programy systému Windows do okna zprávami.Mapování ze zpráv metod lze definovat tak, aby při přijetí zprávy pomocí okna je vhodná metoda je volána automaticky.Tato zpráva mapa zařízení je určen podobat virtuálních funkcí, ale nemá další výhody, které není možné pomocí funkce virtuální C++.
Definování mapy zprávy
DECLARE_MESSAGE_MAP Makro deklaruje tři členy třídy.
Soukromé pole AFX_MSGMAP_ENTRY položky nazvané _messageEntries.
Chráněné AFX_MSGMAP struktury se nazývá messageMap , odkazuje _messageEntries pole.
Chráněné a virtuální funkci nazvanou GetMessageMap , který vrací adresu messageMap.
Toto makro by mělo být uvedeno v prohlášení všechny třídy pomocí mapy zprávy.Dle úmluvy je na konci deklarace třídy.Příklad:
class CMyWnd : public CMyParentWndClass
{
// my stuff...
protected:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Toto je formát generovaných AppWizard a ClassWizard při vytváření nové třídy./ / {{A / nebo}} ClassWizard potřebné závorky.
Tabulka mapování zprávy je definován pomocí sady maker, které rozbalení položek mapování zprávy.Tabulka začíná BEGIN_MESSAGE_MAP volání makra, které definuje třídu, která je zpracována zpráva mapa a nadřazené třídy, které jsou předány nezpracované zprávy.Tabulka končí END_MESSAGE_MAP volání makra.
Mezi tyto dva makro volání je položka pro každou zprávu zpracovat zprávu mapa.Všechny standardní zprávy systému Windows obsahuje makra formuláře ON_WM_MESSAGE_NAME , generuje položku pro tuto zprávu.
Standardní funkce podpisu byla definována pro rozbalení parametry každé zprávy systému Windows a poskytuje typ bezpečnosti.Tyto podpisy je možné najít v souboru Afxwin.h v prohlášení o CWnd.Každá z nich je označena klíčovým slovem afx_msg pro snadnou identifikaci.
[!POZNÁMKA]
Použití vyžaduje ClassWizard afx_msg klíčové slovo v deklaraci obslužné rutiny mapa vaší zprávy.
Tyto podpisy funkce byly získány pomocí jednoduchého úmluvy.Název funkce vždy začíná "On".Následuje název zprávy systému Windows s "WM_" odebrán a první písmeno každého slova velkými písmeny.Pořadí parametrů je wParam a LOWORD(lParam) pak HIWORD(lParam).Nevyužité parametry nejsou předány.Všechny popisovače, které jsou zabaleny podle tříd MFC budou převedeny na odkazy na příslušné objekty MFC.Následující příklad ukazuje, jak zpracovat WM_PAINT zprávy a způsobit CMyWnd::OnPaint zavolat funkci:
BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Tabulka mapování zprávy musí být definována mimo rozsah jakékoli funkce nebo definice třídy.By měly být uváděny nejsou v bloku extern "C".
[!POZNÁMKA]
ClassWizard bude změnit položky mapy zprávy mezi / / {{a / /}} komentář závorka.
Uživatelem definované zprávy systému Windows
Uživatelem definované zprávy mohou být zahrnuty do zprávy mapy pomocí ON_MESSAGE makro.Toto makro přijímá číslo zprávy a metoda formuláře:
// 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()
V tomto příkladu jsme vytvořit obslužnou rutinu pro vlastní zprávu, která obsahuje ID zprávy systému Windows odvozené od standardního WM_USER základní zpráv definované uživatelem.Následující příklad ukazuje, jak tento popisovač volání:
CWnd* pWnd = ...;
pWnd->SendMessage(WM_MYMESSAGE);
Rozsah uživatelem definované zprávy, které používají tento přístup musí být v rozsahu WM_USER na 0x7fff.
[!POZNÁMKA]
ClassWizard nepodporuje zadání ON_MESSAGE rutiny zpracování z uživatelského rozhraní ClassWizard.Musíte ručně zadávat z editoru jazyka Visual C++.ClassWizard bude analyzovat tyto položky a umožňují procházení je stejně jako ostatní položky mapy zprávy.
Registrované zprávy systému Windows
RegisterWindowMessage funkce slouží k definování nové okno zprávu, která je zaručena jedinečnost v celém systému.Makro ON_REGISTERED_MESSAGE slouží k ovládání těchto zpráv.Toto makro přijímá název UINT NEAR proměnná, která obsahuje ID registrované windows zprávy.Například
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()
Musí být registrované proměnná (v tomto příkladu WM_FIND) ID zprávy systému Windows NEAR proměnné z důvodu způsobu ON_REGISTERED_MESSAGE je implementována.
Rozsah uživatelem definované zprávy, které používají tento přístup bude v rozsahu 0xC000 až 0xFFFF.
[!POZNÁMKA]
ClassWizard nepodporuje zadání ON_REGISTERED_MESSAGE rutiny zpracování z uživatelského rozhraní ClassWizard.Je nutné ručně zadat z textového editoru.ClassWizard bude analyzovat tyto položky a umožňují procházení je stejně jako ostatní položky mapy zprávy.
Zprávy příkazu
Zprávy příkazu z nabídky a akcelerátory jsou zpracovány v mapách zprávu s ON_COMMAND makro.Toto makro přijímá ID příkazu a metoda.Pouze zvláštní WM_COMMAND zprávu wParam zadaný příkaz metodou zadané v položce mapa zpráva je zpracována ID rovno.Žádné parametry funkce členů popisovač příkazu a vrátíte se void.Makro má následující tvar:
ON_COMMAND(id, memberFxn)
Příkaz update zprávy směrovány na stejný mechanismus, ale použít ON_UPDATE_COMMAND_UI makro místo.Příkaz update popisovač členské funkce trvat jeden parametr ukazatel na CCmdUI objektu a vrátit void.Formulář má makro
ON_UPDATE_COMMAND_UI(id, memberFxn)
Pokročilí uživatelé mohou použít ON_COMMAND_EX makra je rozšířenou formou obslužné rutiny zpráv příkazu.Makro obsahuje nadmnožinou ON_COMMAND funkce.Funkce členů rozšířený popisovač příkazu trvat jeden parametr UINT obsahuje ID příkazu a vrátíte BOOL.Vrácená hodnota by měla být TRUE k označení nebylo zpracováno příkaz.Jinak směrování budou další příkaz cílové objekty.
Příklady těchto formulářů:
Vnitřní Resource.h (obvykle generován Visual C++)
#define ID_MYCMD 100 #define ID_COMPLEX 101
Uvnitř deklarace třídy
afx_msg void OnMyCommand(); afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI); afx_msg BOOL OnComplexCommand(UINT nID);
Uvnitř definice mapování zprávy
ON_COMMAND(ID_MYCMD, OnMyCommand) ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand) ON_COMMAND_EX(ID_MYCMD, OnComplexCommand)
Provádění souboru
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; }
Pokročilým uživatelům lze zpracovávat rozsah příkazy pomocí jediného příkazu zpracování: ON_COMMAND_RANGE nebo ON_COMMAND_RANGE_EX.Další informace o těchto maker v dokumentaci produktu.
[!POZNÁMKA]
ClassWizard podporuje vytváření ON_COMMAND a ON_UPDATE_COMMAND_UI obsluhy, ale nepodporuje vytváření ON_COMMAND_EX nebo ON_COMMAND_RANGE obslužné rutiny.Průvodce třídy však bude analyzovat a umožňují procházet všechny varianty popisovač příkazu čtyři.
Řídicí zprávy oznámení
Zprávy odeslané z podřízených ovládacích prvků do okna mají bit další informací ve zprávě mapovat položka: ID ovládacího prvku.Položku mapy zprávy v procesu zpracování zpráv se nazývá pouze tehdy, pokud jsou splněny následující podmínky:
Řídicí kód oznámení (vysoká slovo lParam), například BN_CLICKED, odpovídá zadané v položce mapa zpráva kód upozornění.
ID ovládacího prvku (wParam) odpovídá zadané v položce mapa zprávu ID ovládacího prvku.
Použít vlastní ovládací prvek oznamovací zprávy ON_CONTROL makro definujte položku mapy zpráva s kódem vlastní oznámení.Toto makro má tvar
ON_CONTROL(wNotificationCode, id, memberFxn)
Rozšířené použití ON_CONTROL_RANGE lze použít pro zpracování oznámení určitého ovládacího prvku z oblasti ovládacích prvků se stejným popisovač.
[!POZNÁMKA]
ClassWizard nepodporuje vytváření ON_CONTROL nebo ON_CONTROL_RANGE zpracování v uživatelském rozhraní.Musíte ručně zadávat pomocí textového editoru.ClassWizard bude analyzovat tyto položky a umožňují procházení je stejně jako všechny položky zpráva mapy.
Běžné ovládací prvky systému Windows používat více výkonné WM_NOTIFY pro komplexní řízení oznámení.Tato verze MFC má přímou podporu pro tuto novou zprávu pomocí ON_NOTIFY a ON_NOTIFY_RANGE makra.Další informace o těchto maker v dokumentaci produktu.