Sdílet prostřednictvím


TN021: Příkaz a směrování zpráv

[!POZNÁMKA]

Následující technické poznámce nebyly aktualizovány od byla poprvé zahrnuta v dokumentaci online.Proto některé postupy a témata mohou být nesprávné nebo zastaralé.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, jakož i Pokročilá témata v okně Obecné směrování zpráv.

Naleznete Visual C++ obecné podrobnosti na 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á velmi obeznámeni s problémy popsané v tištěné dokumentaci a řeší pouze velmi Pokročilá témata.

Příkaz Směrování a odeslání MFC 1.0 funkce vývoj na MFC 2.0 architektura

Systém Windows má WM_COMMAND zpráva, že je přetížena poskytovat oznámení příkazy nabídky, klávesové zkratky a upozornění v dialogovém okně Ovládací.

MFC 1.0 součástí na tomto trochu tím, že popisovač příkazu (například "OnFileNew") CWnd odvozené třídy získat volán v odpověď na konkrétní WM_COMMAND.Je připevněn spolu s datovou strukturu nazývá mapa zprávy a výsledek příkazu velmi místa efektivní mechanismus.

MFC 1.0 k dispozici také další funkce pro oddělení řízení oznámení z příkazu zprávy.Příkazy jsou představovány 16bitové ID, bývá označována také jako identifikátor příkazu.Příkazy spustit normálně z CFrameWnd (, výběr nabídky nebo přeložené akcelerátor) a získat směrovány na řadu windows.

MFC 1.0 používá příkaz směrování v omezené smyslu 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 všeobecné a extended MFC 2.0 povolit příkazy, které má být zpracováno širší rozsah objekty (nikoli pouze objekty okna).Poskytuje další formální a rozšiřitelné architektury pro směrování zpráv a opakovaně používá příkaz cíl směrování pouze zpracování příkazů, ale také pro aktualizaci tak, aby odrážely aktuální dostupnost příkazu objekty uživatelského rozhraní (například položky nabídky a tlačítka).

ID příkazu

Vysvětlení příkaz Směrování a vázání procesu naleznete v části Visual C++.Technická poznámka: 20 obsahuje informace o ID názvů.

ID příkazu používáme obecný předponu "ID_".ID příkazu > = 0x8000.Zobrazí panel zpráv řádku nebo stav příkazový řetězec popisu Pokud je STRINGTABLE prostředku se stejným ID jako ID příkazu.

Prostředky aplikace zobrazí příkaz, který lze ID na několika místech:

  • V jedné STRINGTABLE prostředek, který má stejné ID jako zpráva øádky.

  • V případně mnoho nabídce prostředky, které jsou připojeny k položky 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, ID, mohou se na několika místech:

  • V prostředku.H (nebo jiný soubor záhlaví hlavní symbol) definovat ID specifické příkazů.

  • MOŽNÁ v poli ID slouží k vytvoření panelu nástrojů.

  • V ON_COMMAND makro.

  • MOŽNÁ v ON_UPDATE_COMMAND_UI makro.

V současné době se pouze implementace v MFC, který vyžaduje ID příkazu > = 0x8000 je provádění GOSUB dialogy/příkazy.

GOSUB příkazy, pomocí příkazu architektury v dialogových oknech

Příkaz architekturu směrování a povolení příkazů pracuje s rám okna položky nabídky, tlačítka panelu nástrojů, tlačítek panelu dialogového okna, ostatní ovládací panely a dalších prvků uživatelského rozhraní poptávky a trasa příkazy aktualizace nebo ID ovládacího prvku příkaz hlavní cíl (obvykle hlavní rámec okna).Tento příkaz hlavní cíl může směrovat jiné cílové objekty příkaz podle potřeby oznámení příkazu nebo ovládacího prvku.

Dialogové okno (modální nebo nemodální) využívat některé funkce architektury příkazu přiřadíte ID ovládací prvek dialogu ID příslušný příkaz.Podpora pro dialogová okna není automaticky, takže máte některé další kód.

Všechny tyto funkce pracovat správně vaše ID příkazu by měly být > = 0x8000.Protože mnoho dialogových oken nelze získat směrovány na stejný rámec, sdílené příkazy by měly být > = 0x8000, by měly být sdíleném IDCs v konkrétní dialogové okno < = 0x7FFF.

Normální tlačítko můžete umístit do normální modální dialogové okno s IDC tlačítka nastavit ID příslušný příkaz.Po klepnutí na tlačítko (obvykle hlavní rámec okna) v dialogovém okně Vlastník získá příkaz stejně jako ostatní příkaz.Protože obvykle slouží k jiné dialogové okno (GOSUB první dialogové okno) se nazývá příkaz GOSUB.

Můžete také volání funkce CWnd::UpdateDialogControls v dialogovém okně a předá adresu okna Hlavní rámec.Tato funkce bude povolení nebo zakázání ovládacích prvků dialogového okna založené na tom, zda jsou popisovače příkazu v rámci.Tato funkce je volána automaticky můžete pro ovládací panely aplikace nečinnosti smyčku, ale je třeba zavolat přímo pro normální dialogy, které chcete mít tuto funkci.

Když se nazývá ON_UPDATE_COMMAND_UI

Zachování vždy povolena nebo zkontrolovat stav položky nabídky všech programu lze výpočetně náročné problém.Běžnou technikou je povolit nebo zaškrtnutí položky nabídky pouze v případě, že uživatel vybere v místní nabídce.Provádění MFC 2.0 CFrameWnd úchyty WM_INITMENUPOPUP zprávy a architekturu směrování příkaz používá k určení států 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 na stavovém řádku (také známé jako řádek zprávy) vybrané položce.

Struktury nabídky aplikace, upravil Visual C++ je použita k reprezentaci potenciální příkazy k dispozici na adrese 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 seznam naposledy použitých souborů nebo rozbalovací nabídky Akce OLE) skutečně Změna struktury nabídky před v nabídce Kreslení.

Stejné řazeny ON_UPDATE_COMMAND_UI zpracování je provedeno panelů nástrojů (a ostatní ovládací panely) při použití smyčce jeho nečinnosti.Najdete Reference knihovny třídy a Technická poznámka: 31 Další informace o ovládacích panelů.

Vnořené rozbalovacích nabídek

Používáte-li nabídku vnořené struktury, zjistíte, ON_UPDATE_COMMAND_UI ve dvou různých případech se nazývá popisovač pro první položku v rozbalovací nabídce.

Nejprve se nazývá rozbalovací nabídky sama.To je nezbytné, protože rozbalovací nabídky nemají ID a můžeme použít ID první položku v rozbalovací nabídce celou místní nabídku.V tomto případě m_pSubMenu členské proměnné CCmdUI objekt bude mít hodnotu NULL a budou odkazovat v rozbalovací nabídce.

Za druhé se nazývá těsně před jsou v rozbalovací nabídce položky nabídky se stanoví.V tomto případě ID odkazuje pouze na první položku a m_pSubMenu členské proměnné CCmdUI bude objekt NULL.

Umožňuje povolit odlišné od jeho položky nabídky rozbalovací nabídky, ale vyžaduje psaní kódu si některé nabídky.Například ve vnořených 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 povoleno nebo zakázáno.Nový rozbalovací nabídky být povoleno, pokud je povoleno buď dvě.

Popisovač příkazu ID_NEW_SHEET (první příkaz v místní nabídce) by vypadat podobně jako:

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);
}

Popisovač příkazu ID_NEW_CHART by popisovač příkazu normální aktualizace a vzhled něco jako:

void CMyApp::OnUpdateNewChart(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(m_bCanCreateChart);
}

ON_COMMAND a ON_BN_CLICKED

Mapa makra zprávu pro ON_COMMAND a ON_BN_CLICKED jsou stejné.ID příkazu MFC příkazy a ovládání oznámení mechanismus směrování používá pouze rozhodnout, kam chcete směrovat.Řízení oznámení s řídicí kód oznámení nula (BN_CLICKED) jsou interpretovány jako příkazy.

[!POZNÁMKA]

Ve skutečnosti všechny řídicí zprávy oznámení procházejí obslužnou rutinu řetězci příkazu.Například je technicky možné zapisovat popisovač oznámení ovládací EN_CHANGE ve své třídě dokumentu.To není vhodnější, protože několik praktického použití této funkce ClassWizard není podporována funkce a funkce může mít za následek křehké kód.

Zakázání automatické vypnutí tlačítka ovládacích prvků

Pokud umístíte ovládací tlačítka na panelu dialogového okna nebo v dialogovém okně, kde pomocí volání CWnd::UpdateDialogControls na vlastní, si všimnete, že tlačítka, které nemají ON_COMMAND nebo ON_UPDATE_COMMAND_UI obsluhy bude automaticky zakázán můžete v rámci.V některých případech není třeba mít obslužnou rutinu, ale chcete tlačítko zůstávají povoleny.Nejjednodušším způsobem, jak toho dosáhnout, je přidání obsluhu figuríny příkazu (snadné s ClassWizard) a neprovádět žádnou akci v ní.

Okno směrování zpráv

Následující část popisuje některé pokročilejší témata tříd MFC a směrování zpráv a dalších tématech vliv jejich.Informace zde pouze stručně popsány.Odkaz Reference knihovny třídy podrobnosti o veřejných rozhraní API.Viz zdrojový kód knihovny MFC Další informace o podrobnosti implementace.

Najdete na Technická poznámka 17 podrobnosti v okně Vyčištění, velmi důležité téma pro všechny CWnd-odvozené třídy.

CWnd problémy

Provádění členské funkce CWnd::OnChildNotify poskytuje výkonné a rozšiřitelnou architekturu pro windows (prvky) podřízené zavěšení nebo jinak informována o zprávy, příkazy a ovládání upozornění, které na jejich nadřízené (nebo "vlastník").Pokud podřízené okno (/ řízení) je C++ CWnd samotný objekt virtuální funkce OnChildNotify se nazývá nejprve s parametry z původní zprávy (, MSG struktury).Podřízené okno můžete nechat zprávu samostatně, jej jíst nebo upravit zprávu pro nadřazenou (vzácné).

Výchozí CWnd provádění následujících zpráv zpracovává a používá OnChildNotify háčkem podřízené umožnit přístup první zprávy systému windows (ovládací prvky):

  • WM_MEASUREITEM a WM_DRAWITEM (self-draw)

  • WM_COMPAREITEM a WM_DELETEITEM (self-draw)

  • WM_HSCROLL a WM_VSCROLL

  • WM_CTLCOLOR

  • WM_PARENTNOTIFY

Zjistíte OnChildNotify háčkem slouží pro změnu překreslování zprávy do self-draw zpráv.

Kromě OnChildNotify zavěšení, posun zprávy mají další směrování chování.Níže naleznete podrobnosti o zdroje posuvníky a 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í provedení aktualizace.Používá se především pro hlavní rámec okno aplikace (CWinApp::m_pMainWnd) se však vztahuje na všechny rámce systému windows.

Hlavní rámec okna je okno panelu nabídek a nadřazeného stavový řádek nebo řádek zprávu.Naleznete v diskusi nad 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 prostřednictvím aktivní zobrazení:

  • Všechny zprávy příkazu (aktivní zobrazení stává první přístup).

  • 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í funkce virtuální CView::OnActivateView.

Problémy S CMDIFrameWnd/CMDIChildWnd

Obě třídy oken MDI rámeček odvodit z CFrameWnd a proto jsou povoleny pro stejný druh příkaz Směrování a aktualizace uživatelského rozhraní podle CFrameWnd.Typické aplikace MDI pouze okno hlavní rámec (je CMDIFrameWnd objektu) obsahuje panel nabídek a stavový řádek, a proto je hlavní zdroj směrování provedení příkazu.

Obecné schéma směrování je, že aktivní podřízené okno MDI získá první přístup k příkazům.Výchozí PreTranslateMessage funkce zpracování tabulek akcelerátor pro obě podřízených oken MDI (první) a snímek MDI (druhý) stejně jako standardní příkaz systému akcelerátory MDI 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 zpracování, tak není závislý na jakých zprávu posun řádku.Toto není pouze o obecné Windows problém, protože posouvání zpráv mohou pocházet z true posuvníku ovládací prvky nebo z WS_HSCROLL/WS_VSCROLL posuvníky, které nejsou prvky pruhu posuvníku.

Rozšiřuje MFC, který povoluje ovládací prvky pruhu posuvníku dítě nebo sourozenci se posouvat okno (ve skutečnosti vztah nadřazený podřízený mezi posuvník a okno se posouvat může být cokoli).To je zvláště důležité u sdílených posuvníky s rozdělováním windows.Najdete na Technická poznámka 29 podrobnosti o provádění CSplitterWnd včetně Další informace o sdílených problémů pruhu posuvníku.

Na straně poznámky jsou dvě CWnd jsou odvozené třídy, kde vytvářet styly pruhu posuvníku určeno na čas pohoda a nejsou předány do systému Windows.Po vytvoření rutině WS_HSCROLL a WS_VSCROLL lze nezávisle nastavit, ale po vytvoření nelze změnit.Samozřejmě by přímo testovat nebo nastavit WS_?POSUNUTÍ bitů styl okna, která byla vytvořena.

Pro CMDIFrameWnd Styly pruhu posuvníku předáte v vytvořit nebo LoadFrame slouží k vytvoření MDICLIENT.Pokud chcete mít posuvný MDICLIENT plochu (podobně jako Program Správce systému Windows) nastavte posouvání oba styly pruhů (WS_HSCROLL | WS_VSCROLL) použitý k vytvoření stylu CMDIFrameWnd.

Pro CSplitterWnd na zvláštní sdílené posuvníky pro rozdělování oblasti použít styly pruhu posuvníku.Statický rozdělovač Windows bude obvykle nastavit buď styl pruhu posuvníku.Pro dynamické rozdělovač windows bude mít obvykle posuvník nastavit styl bude rozdělíte, je směr WS_HSCROLL -li rozdělit řádky, WS_VSCROLL Pokud sloupce lze rozdělit.

Viz také

Další zdroje

Technické poznámky podle čísla

Technické poznámky podle kategorie