TN021: Směrování příkazů a zpráv
[!POZNÁMKA]
Následující technická poznámka nebyla aktualizována, protože byla poprvé zahrnuta v dokumentaci online.V důsledku toho některé postupy a témata mohou být nesprávné nebo zastaralé.Pro nejnovější informace je vhodné vyhledat téma zájmu v dokumentaci online index.
Tato poznámka popisuje architekturu směrování a odeslání příkazu, stejně jako pokročilá témata v okně Obecné směrování zpráv.
Naleznete Visual C++ pro obecné informace o architekturách popsané zde, zejména rozdíl mezi příkazy, řízení oznámení a zprávy systému Windows.Tato poznámka se předpokládá, jsou velmi dobře obeznámeni s problémy popsané v tištěné dokumentaci a řeší pouze velmi Pokročilá témata.
Příkazy směrování a odeslání MFC 1.0 funkce vývoj ke knihovně MFC 2.0 architektura
Systém Windows má WM_COMMAND zpráva, že je přetížena poskytovat příkazy nabídky, klávesové zkratky a prvku dialogu upozornění upozornění.
1.0 knihovny MFC součástí na tomto poněkud tím, že obslužná rutina příkazů (například "OnFileNew") CWnd odvozené třídy získat volání v reakci na konkrétní WM_COMMAND.Je slepené strukturu dat s názvem mapu zpráv a má za následek velmi prostorově úsporné příkaz mechanismus.
1.0 knihovny MFC k dispozici také další funkce pro oddělení řízení sdělení zprávy příkazu.Příkazy jsou reprezentovány 16-bit ID, která bývá označována také jako identifikátor příkazu.Příkazy spustit normálně z CFrameWnd (to znamená, nabídka vybrat nebo přeložené akcelerátor) a získat směrovány na celou řadu jiných oken.
1.0 knihovny MFC používá příkaz směrování v omezené smysl pro implementaci rozhraní více dokumentů (MDI). (Rámci okna aplikace MDI delegovat příkazy k jeho aktivní podřízené okno MDI).
Tato funkce byla zobecněna a rozšířen v MFC 2.0 Chcete-li povolit příkazy ke zpracování pomocí nejrůznějších objektů (nikoli pouze okno objekty).Poskytuje více formální a rozšiřitelné architektury pro směrování zpráv a znovu použije příkaz cíl směrování pro nejen zpracování příkazů, ale také tak, aby odrážely aktuální dostupnost příkazu Aktualizovat objekty uživatelského rozhraní (například položky nabídky a tlačítka panelu nástrojů).
ID příkazu
Vysvětlení příkaz Směrování a proces vázání naleznete v tématu Visual C++.Technická poznámka: 20 obsahuje informace o ID názvů.
Obecný předponu "ID_" používáme pro ID příkazů.ID příkazu jsou >= 0x8000.Zpráva řádku nebo stavový řádek se zobrazí příkazový řetězec popis Pokud je STRINGTABLE zdroje se stejným ID jako identifikátor příkazu.
Prostředky aplikace zobrazí příkaz, který lze ID na několika místech:
V jednom STRINGTABLE zdroje, který má stejné ID jako zpráva řádku.
V případně mnoho nabídek prostředků připojených položek nabídky, které vyvolávají stejný příkaz.
(UPŘESNIT) v dialogovém okně tlačítko příkazu GOSUB.
Ve zdrojovém kódu aplikace zobrazí příkaz, který ID můžete na několika místech:
V prostředku.H (nebo jiný soubor záhlaví hlavní symbol) definovat ID příkazů specifických pro aplikaci.
MOŽNÁ v poli ID použité k vytvoření panelu nástrojů.
V ON_COMMAND makra.
TŘEBA v ON_UPDATE_COMMAND_UI makra.
V současné době se pouze implementace v knihovně MFC, který vyžaduje ID příkazů >= 0x8000 je provádění dialogy/příkazy GOSUB.
GOSUB příkazy, pomocí příkazu architektury v dialogových oknech
Příkaz architekturu směrování a příkazy umožňující pracuje s rámečkům oken, položky nabídky, tlačítka panelu nástrojů, tlačítka panelu dialogového okna, ostatní ovládací panely a další prvky uživatelského rozhraní, který je navržen tak, aby aktualizace poptávky a trasa příkazy nebo ovládací ID příkazu hlavní cíl (obvykle hlavním oknem rámce).Tento příkaz hlavní cíl může směrovat další příkaz cílové objekty podle potřeby oznámení příkazu nebo ovládacího prvku.
Dialogové okno (modální nebo nemodální) mohou těžit z některých funkcí architektury příkazu přiřadíte ID ovládacího prvku dialogu ID příslušný příkaz.Podpora pro dialogová okna není automaticky, takže máte psát další kód.
Všimněte si, že vaše ID příkazů pro všechny tyto funkce pracovat správně, bude >= 0x8000.Vzhledem k tomu, že mnoho dialogových oken může získat směrovány na stejný snímek, sdílené příkazy by měly být >by měla být sdíleném IDCs v konkrétní dialogovém okně = 0x8000, <= 0x7FFF.
Běžná tlačítka můžete umístit do normální modální dialogové okno s IDC tlačítka nastavte na odpovídající příkaz ID.Po klepnutí na tlačítko vlastníka dialogu (obvykle hlavním oknem rámce) získá příkaz stejně jako jakýkoli jiný příkaz.Vzhledem k tomu, že obvykle slouží k vyvolání jiného dialogu (v prvním dialogovém okně GOSUB) se nazývá příkaz GOSUB.
Můžete také volat funkci CWnd::UpdateDialogControls na dialogu a předat jeho adresu v hlavním okně rámce.Tato funkce bude povolit nebo zakázat dialogové okno Ovládací prvky založené na zda mají v rámci příkazu obslužné rutiny.Tato funkce je volána automaticky můžete pro ovládací panely ve vaší aplikaci nečinnou smyčku, ale je třeba volat přímo pro běžné dialogová okna, které chcete mít tuto funkci.
Když se nazývá ON_UPDATE_COMMAND_UI
Uchování stavu povoleno kontrolovat položky nabídky všech programu vždy může být problém výpočetně náročné.Je běžnou technikou/Kontrola povolení položky nabídky pouze v případě, že uživatel vybere místní nabídce.Implementace MFC 2.0 CFrameWnd úchyty WM_INITMENUPOPUP zpráva a používá architekturu směrování příkazu lze zjistit stav nabídky prostřednictvím ON_UPDATE_COMMAND_UI obslužné rutiny.
CFrameWnd také zpracovává WM_ENTERIDLE zpráva popisující aktuální nabídky vybrané položky na stavovém řádku (také označovaný jako řádek zprávy).
Struktury nabídky aplikace, upravit pomocí aplikace Visual C++, je použita k reprezentaci možné příkazy k dispozici na WM_INITMENUPOPUP čas.ON_UPDATE_COMMAND_UI obslužné rutiny můžete změnit stav nebo text nabídky nebo pro pokročilé použití (například seznamu naposledy použitých souborů nebo v rozbalovací nabídce slovesa OLE) skutečně změnit strukturu nabídky před v nabídce Kreslení.
Stejné řazení z ON_UPDATE_COMMAND_UI zpracování je provedeno pro panely nástrojů (a ostatní ovládací panely) při použití smyčce jeho nečinnosti.Najdete Knihovny tříd a Technická poznámka: 31 pro další informace o ovládacích panelech.
Vnořené rozbalovacích nabídek
Pokud používáte nabídku vnořené struktury, zjistíte, že ON_UPDATE_COMMAND_UI ve dvou různých případech je volána obslužná rutina pro první položku v rozbalovací nabídce.
Nejprve se nazývá pro rozbalovací nabídku.To je nezbytné, protože rozbalovací nabídky nemají ID a ID první položku v rozbalovací nabídce používáme odkázat na celý rozbalovací nabídky.V tomto případě m_pSubMenu členské proměnné CCmdUI objekt bude mít jinou hodnotu než NULL a ukazoval v rozbalovací nabídce.
Za druhé se nazývá těsně před v rozbalovací nabídce položky nabídky jsou k tomu.V tomto případě ID odkazuje pouze na první položku a m_pSubMenu členské proměnné CCmdUI objekt bude mít hodnotu NULL.
Umožňuje povolit rozbalovací nabídky, které se liší od jeho položky nabídky, ale vyžaduje, abyste napsali kód si uvědomit některé nabídky.Například v vnořené nabídky s následující strukturou:
File>
New>
Sheet (ID_NEW_SHEET)
Chart (ID_NEW_CHART)
Příkazy ID_NEW_SHEET a ID_NEW_CHART lze nezávisle povolit nebo zakázat.Nové rozbalovací nabídky by měly být povoleny buď ze dvou.
Obslužná rutina příkazů pro ID_NEW_SHEET (první příkaz v místní nabídce) by vypadat nějak takto:
void CMyApp::OnUpdateNewSheet(CCmdUI* pCmdUI)
{
if (pCmdUI->m_pSubMenu != NULL)
{
// enable entire pop-up for "New" sheet and chart
BOOL bEnable = m_bCanCreateSheet || m_bCanCreateChart;
// CCmdUI::Enable is a no-op for this case, so we
// must do what it would have done.
pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex,
MF_BYPOSITION |
(bEnable ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
return;
}
// otherwise just the New Sheet command
pCmdUI->Enable(m_bCanCreateSheet);
}
Obslužná rutina příkazů pro ID_NEW_CHART by bylo normální aktualizace obslužná rutina příkazů a hledat něco jako:
void CMyApp::OnUpdateNewChart(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bCanCreateChart);
}
ON_COMMAND a ON_BN_CLICKED
Makra mapy zprávy pro ON_COMMAND a ON_BN_CLICKED jsou stejné.ID příkazu knihovny MFC příkazy a ovládání oznamovací mechanismus směrování používá pouze rozhodnout, kde chcete směrovat.Řízení oznámení s řídícím kódem oznámení nula (BN_CLICKED) jsou interpretovány jako příkazy.
[!POZNÁMKA]
Ve skutečnosti všechny zprávy s oznámením ovládací prvek přejít pomocí řetězce příkazu obslužné rutiny.Například, je technicky možné psát obslužné rutiny oznámení ovládacího prvku EN_CHANGE ve třídě dokumentu.Není vhodnější vzhledem k tomu, že jsou několik praktického použití této funkce, funkce není podporována pomocí ClassWizard a funkce může způsobit křehké kód.
Zakázání automatické vypnutí tlačítka
Pokud umístíte ovládací prvek button na panelu dialogové okno nebo dialogové okno použití voláte CWnd::UpdateDialogControls na vlastní, si všimnete, že tlačítka, které nemají ON_COMMAND nebo ON_UPDATE_COMMAND_UI obslužné rutiny bude automaticky zakázán pro vás architekturou.V některých případech nebudete mít obslužnou rutinu, ale chcete tlačítko zůstávají povoleny.Nejjednodušší způsob, jak toho dosáhnout je přidat popisovač příkazu figuríny (lze snadno provést pomocí ClassWizard) a nic v ní.
Okno směrování zpráv
Následující část popisuje některé další upřesňující témata pro třídy knihovny MFC a směrování zpráv systému Windows a dalších tématech vliv je.Zde uvedené informace je pouze stručně popsány.Najdete Knihovny tříd podrobnosti o veřejných rozhraní API.Viz zdrojový kód knihovny MFC Další informace týkající se podrobností provádění.
Najdete na Technická poznámka: 17 pro podrobnosti v okně Vyčištění, velmi důležité téma pro všechny CWnd-odvozené třídy.
Problémy CWnd
Implementace členské funkce CWnd::OnChildNotify poskytuje výkonné a rozšiřitelné architektury pro systém windows (prvky) podřízené k zavěšení nebo jinak informována zprávy, příkazy a ovládací prvek oznámení, které patří do jejich nadřazené (nebo "vlastník").Pokud podřízené okno (/ řízení) je C++ CWnd objekt samotný, virtuální funkce OnChildNotify jako první s parametry z původní zprávy (to znamená, MSG struktury).Podřízené okno můžete ponechat zprávy samostatně, jíst ho nebo změňte uvedenou zprávu pro nadřazenou (vzácné).
Ve výchozím nastavení CWnd provádění následujících zpráv zpracovává a využívá OnChildNotify zavěšení systému windows (ovládací prvky) první přístup zprávy povoleno dítě:
WM_MEASUREITEM a WM_DRAWITEM (pro automatické kreslení)
WM_COMPAREITEM a WM_DELETEITEM (pro automatické kreslení)
WM_HSCROLL a WM_VSCROLL
WM_CTLCOLOR
WM_PARENTNOTIFY
Zjistíte OnChildNotify zavěšení slouží pro změnu vlastníka vystavení zprávy do nakreslit vlastní zprávy.
Navíc OnChildNotify hák, posouvání zprávy budou obsahovat další směrování chování.Níže naleznete podrobnosti o zdroje a posuvníky WM_HSCROLL a WM_VSCROLL zprávy.
CFrameWnd problémy
CFrameWnd třída poskytuje většinu příkazů směrování a uživatelské rozhraní implementace aktualizace.Používá se především pro hlavní okno aplikace (CWinApp::m_pMainWnd), ale platí pro všechna okna rámce.
Okno rámce, hlavní okno panelu nabídek a je nadřazený stavový řádek nebo řádek zprávy.Najdete na výše uvedené diskuse na příkaz Směrování a WM_INITMENUPOPUP.
CFrameWnd třída poskytuje správu aktivní zobrazení.Následující zprávy jsou směrovány přes aktivní zobrazení:
Všechny zprávy příkazu (první přístup k nim získá aktivní zobrazení).
WM_HSCROLL a WM_VSCROLL zprávy od sourozenců posuvníky (viz níže).
WM_ACTIVATE (a WM_MDIACTIVATE pro MDI) získat převeden volání virtuální funkce CView::OnActivateView.
CMDIFrameWnd/CMDIChildWnd problémy
Obě třídy rámeček okno MDI jsou odvozeny z CFrameWnd a proto jsou povoleny pro stejný druh příkazu směrování a aktualizace uživatelského rozhraní podle CFrameWnd.V typické aplikaci MDI, pouze hlavní okno rámce (to znamená CMDIFrameWnd objekt) obsahuje řádek nabídek a na stavovém řádku a proto je hlavním centrem technologického postupu provádění příkazu.
Obecné schéma technologického postupu je, že aktivní podřízené okno MDI získá první přístup k příkazům.Ve výchozím nastavení PreTranslateMessage funkce zpracování tabulek akcelerátor pro obě podřízených oken MDI (první) a rámec MDI (druhý) a standardní akcelerátory MDI příkaz systému obvykle řeší TranslateMDISysAccel (poslední).
Posuvník problémy
Při zpracování zprávy posuvníku (WM_HSCROLL/OnHScroll a WM_VSCROLL/OnVScroll), pokuste se psát kód pro obslužnou rutinu, nespoléhá na odkud pocházejí zprávy pruhu posuvníku.Nejedná se pouze o obecné Windows problém, protože posouvání zprávy mohou pocházet z true posuvníku panel ovládací prvky nebo z WS_HSCROLL/WS_VSCROLL posuvníky, které nejsou ovládacími prvky pruhu posuvníku.
Rozšiřuje knihovny MFC, který povoluje ovládací prvky panelu posun podřízený nebo sourozenci okna se posunul (ve skutečnosti vztah nadřazený podřízený mezi posuvník a okno se posunul může být cokoliv).Toto je obzvláště důležité pro sdílené posuvníky se systémem windows rozdělovač.Najdete na Technická poznámka: 29 podrobné informace o provádění CSplitterWnd včetně Další informace o sdílených problémů pruhu posuvníku.
Na poznámky na okraj jsou dvě CWnd odvozených tříd, kde vytvořit styly pruhů přejít na zadaný čas se do pasti a nebyl předán do systému Windows.Když předán rutina vytvoření, WS_HSCROLL a WS_VSCROLL může být nastavena samostatně, ale po vytvoření nelze změnit.Samozřejmě by měl přímo testovat nebo nastavit WS_?POSUNUTÍ bitů styl okna, které sami vytvořili.
Pro CMDIFrameWnd Styly pruhu posuvníku můžete předat v vytvořit nebo LoadFrame slouží k vytvoření MDICLIENT.Pokud chcete mít posuvný MDICLIENT plochu (podobně jako správce systému Windows Program), je nutné nastavit obě posuvníku styly (WS_HSCROLL | WS_VSCROLL) použitý k vytvoření stylu CMDIFrameWnd.
Pro CSplitterWnd Styly pruhu posuvníku se nevztahuje na zvláštní sdílené posuvné lišty pro rozdělování oblastí.Pro statický rozdělovač windows obvykle nastavíte buď styl pruhu posuvníku.Dynamický rozdělovač windows bude obvykle mít posuvník sadu stylů ve směru, bude rozdělení, který je WS_HSCROLL Pokud rozdělíte řádků, WS_VSCROLL Pokud můžete rozdělit sloupce.