Udostępnij za pośrednictwem


TN021: Polecenie i routingu wiadomości

[!UWAGA]

Następujące Uwaga techniczna została zaktualizowana, ponieważ najpierw została uwzględniona w dokumentacji online.W rezultacie niektóre procedur i tematów może być nieaktualne lub nieprawidłowe.Najnowsze informacje zaleca się wyszukać temat zainteresowanie Indeks dokumentacji online.

Uwaga ta opisuje architekturę polecenia routingu i wysyłki, jak również Tematy zaawansowane w routingu wiadomości Ogólne okna.

Można znaleźć Visual C++ ogólne szczegółowe informacje na temat architektury, opisem, szczególnie rozróżnienie między wiadomości, kontroli i poleceń systemu Windows.Uwaga ta zakłada znajomości problemy opisane w dokumentacji drukowanej i dotyczy tylko tematy bardzo zaawansowane.

Polecenia routingu i wysyłki MFC 1.0 funkcjonalność ewoluuje do MFC 2.0 architektury

System Windows ma WM_COMMAND komunikat jest przeciążony zapewnienie powiadomienia poleceń menu, klawisze skrótów i okna dialogowego Kontrola zgłoszeń.

MFC 1.0 zbudowany na tym trochę poprzez umożliwienie obsługi polecenia (na przykład "OnFileNew") w CWnd klasy do wywoływana w odpowiedzi na określony WM_COMMAND.Jest sklejone struktura danych o nazwie Mapa wiadomości i skutkuje mechanizm bardzo kompaktowa polecenia.

MFC 1.0 również dostarczane dodatkowe funkcje do oddzielania powiadomienia kontroli z wiadomości polecenia.Polecenia są reprezentowane przez identyfikator 16-bitowe, czasami znane jako nazwę polecenia.Poleceń rozpoczyna się zwykle z CFrameWnd (oznacza to, wybierz menu lub tłumaczone accelerator) i są routowane do różnych innych okien.

MFC 1.0 używane polecenia routingu w ograniczona poczucia implementacji interfejsu dokumentu wielu (MDI).(Okno ramek MDI delegować poleceń do jego aktywne okno potomne MDI).

Ta funkcja został generalized i rozszerzone MFC 2.0, aby umożliwić poleceń obsługiwanych przez szerszego zakresu obiektów (nie tylko obiekty okna).Zapewnia więcej formalne i rozszerzalną architekturę routingu wiadomości i używa polecenia docelowych routingu, nie tylko obsługi poleceń, ale również dla aktualizacji obiektów interfejsu użytkownika (takich jak elementy menu i przyciski paska narzędzi) dostępności bieżącego polecenia.

Identyfikatory poleceń

Wyjaśnienie polecenie routing i proces wiązania na ten temat można znaleźć w Visual C++.Techniczne 20 Uwaga zawiera informacje o identyfikatorze nazewnictwa.

Wykorzystujemy ogólny prefiksu "ID_" dla identyfikatorów poleceń.Identyfikatory polecenia > = 0x8000.Pasek komunikatów linii lub stan będzie pokazuj polecenia ciąg opisu, jeśli jest zasób STRINGTABLE z tych samych identyfikatorów jako identyfikatora polecenia.

Polecenie, które można ID w zasoby aplikacji pojawia się w kilku miejscach:

  • W jednej STRINGTABLE zasób, który ma ten sam identyfikator jako wiersza wiadomości.

  • Ewentualnie wiele MENU zasobów dołączonych do elementów menu, które wywołują tego samego polecenia.

  • (Zaawansowane) w oknach przycisku polecenia GOSUB.

W kodzie źródłowym aplikacji polecenie, które można identyfikator pojawia się w kilku miejscach:

  • W przypadku ZASOBU.H (lub innych głównych symbolu nagłówka pliku) do definiowania identyfikatorów polecenia specyficzne dla aplikacji.

  • Być może w tablicy identyfikator używany do tworzenia paska narzędzi.

  • W ON_COMMAND makro.

  • Być może w ON_UPDATE_COMMAND_UI makro.

Obecnie wprowadzenie tylko w MFC wymagającej identyfikatory polecenia być > = 0x8000 jest implementacją GOSUB okien dialogowych/commands.

GOSUB polecenia, za pomocą polecenia architektury w oknach dialogowych

Architektura polecenia routingu i włączanie polecenia działa dobrze z windows ramki, elementy menu, przyciski paska narzędzi, okna dialogowego przyciski paska, innych pasków i innych elementów interfejsu użytkownika służące do aktualizacji na żądanie i trasę poleceń lub formant identyfikatory docelowe główne polecenia (zwykle okno główne ramki).Główne polecenia obiektu docelowego może marszruty powiadomienia polecenie lub formant do innych obiektów docelowych polecenia odpowiednio.

Okno dialogowe (modalny lub niemodalny) mogą korzystać z niektórych funkcji architektury polecenie, jeśli identyfikator formantu dialog control przypisać identyfikator odpowiednie polecenie.Obsługa okien dialogowych nie jest automatyczne, więc może zapisać niektórych dodatkowy kod.

Zauważ, że wszystkie te funkcje działały poprawnie, Twoje nazwy polecenia powinny być > = 0x8000.Ponieważ wiele okien dialogowych może routowane do tej samej ramce, powinny być udostępnione polecenia > = 0x8000, podczas gdy powinna być udostępniana IDCs w określonego okna dialogowego < = 0x7FFF.

Normalny przycisk można umieścić w normalnym modalne okno dialogowe z IDC przycisku Ustaw ID odpowiednie poleceniePo wybraniu przycisku (zwykle okno główne ramki) w oknie dialogowym Właściciel pobiera polecenia, podobnie jak inne polecenie.Jest to polecenie GOSUB, ponieważ zwykle jest on używany do innego okna dialogowego (GOSUB pierwsze okno dialogowe)

Można również wywołać funkcję CWnd::UpdateDialogControls na Twoje okno dialogowe i przekazać jej adres w ramce głównej okna.Ta funkcja będzie Włączanie lub wyłączanie formantów okna dialogowego, w zależności od tego, czy mają one obsługi polecenia w ramce.Ta funkcja jest wywoływana automatycznie dla Ciebie dla pasków w pętlę bezczynności aplikacji, ale trzeba wywołać ją bezpośrednio do normalnego okna dialogowe, które chcą mieć tę funkcję.

Gdy wywoływana jest ON_UPDATE_COMMAND_UI

Utrzymania zawsze włączone sprawdzane stanu programu wszystkie elementy menu mogą być obliczeniowo duży problem.Popularna technika stosowana jest włączanie edycji elementów menu tylko wtedy, gdy użytkownik wybierze z menu PODRĘCZNEGO.Wykonania MFC 2.0 CFrameWnd uchwyty WM_INITMENUPOPUP wiadomości i używa polecenia architekturę routingu w celu określenia Państwa menu poprzez ON_UPDATE_COMMAND_UI obsługi.

CFrameWnd obsługuje również WM_ENTERIDLE komunikat do opisu bieżącego menu elementu wybranego na status bar (znany również jako wiersz wiadomości).

Struktury menu aplikacji, edytowany przez Visual C++ jest używana do reprezentowania potencjalnych poleceń dostępnych w WM_INITMENUPOPUP czasu.ON_UPDATE_COMMAND_UI obsługi można zmodyfikować Państwa lub tekst menu lub do zaawansowanych zastosowań (takich jak plik listy lub menu podręcznego zleceń OLE), rzeczywiście Modyfikowanie struktury menu przed menu rysowania.

To samo sortowane ON_UPDATE_COMMAND_UI przetwarzania jest określany dla pasków narzędzi (i innych pasków) gdy aplikacja wprowadzi jego pętlę bezczynności.Zobacz Odwołanie do biblioteki klas i technicznej 31 Uwaga więcej informacji na temat sterowania paski.

Zagnieżdżone wyskakujące menu

Jeśli używasz struktury zagnieżdżone menu, można zauważyć że ON_UPDATE_COMMAND_UI obsługi dla pierwszego elementu menu wyskakującego menu nazywa się w dwóch różnych przypadków.

Po pierwsze jest nazywany menu wyskakującego, sam.Jest to konieczne, ponieważ wyskakujące menu nie mają identyfikatorów i używamy identyfikator pierwszego elementu menu wyskakującego menu do odwoływania się do całego menu wyskakującego.W przypadku m_pSubMenu zmienną z CCmdUI obiekt będzie NIEZEROWE i wskazać polecenie menu wyskakującego.

Po drugie jest ona wywoływana tuż przed elementów menu wyskakującego menu mają być określone.W tym przypadku identyfikator odnosi się tylko do pierwszego elementu menu i m_pSubMenu zmienną z CCmdUI obiekt będzie mieć wartość NULL.

Pozwala włączyć z jego elementów menu wyskakującego menu, ale wymaga się, że piszemy kod świadomość menu.Na przykład w menu zagnieżdżonych z następującą strukturę:

File>
    New>
        Sheet (ID_NEW_SHEET)
        Chart (ID_NEW_CHART)

Polecenia ID_NEW_SHEET i ID_NEW_CHART może być niezależnie włączona lub wyłączona.Nowy wyskakującego menu powinno być włączone, jeśli włączono albo dwóch.

Polecenia programu obsługi ID_NEW_SHEET (pierwsze polecenie wyskakujące) powinna wyglądać następująco:

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

Polecenia programu obsługi ID_NEW_CHART byłoby obsługi polecenia aktualizacji normalnych i wygląd coś w rodzaju:

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

ON_COMMAND i ON_BN_CLICKED

Makra mapę wiadomości dla ON_COMMAND i ON_BN_CLICKED są takie same.MFC dowodzenia i kontroli mechanizmu routingu powiadomienia używa tylko identyfikator polecenia zdecydować gdzie należy skierować do.Sterowanie powiadomienia z formantu Kod powiadomienia zero (BN_CLICKED) są interpretowane jako polecenia.

[!UWAGA]

W rzeczywistości wszystkie wiadomości powiadomień kontroli go za pośrednictwem łańcucha polecenia obsługi.Na przykład, jest technicznie możliwe do pisania obsługi powiadomień sterowania EN_CHANGE w klasie dokumentu.Nie jest ogólnie zalecane ponieważ niewielu praktycznych wniosków z tej funkcji, funkcja nie jest obsługiwana przez ClassWizard i użycia funkcji może spowodować delikatny kod.

Wyłączanie automatycznego wyłączania formantów przycisk

Umieść formant przycisku na pasku okna dialogowego lub w oknie dialogowym, stosując dzwonisz CWnd::UpdateDialogControls samodzielnie, można zauważyć, że przyciski, które nie mają ON_COMMAND lub ON_UPDATE_COMMAND_UI obsługi zostaną automatycznie wyłączone dla Ciebie w ramach.W niektórych przypadkach nie będzie trzeba mieć program obsługi, ale można przycisku pozostają włączone.Najprostszym sposobem osiągnięcia tego jest dodanie obsługi polecenia manekina (łatwe z ClassWizard) i nic w nim.

Routowanie wiadomości w oknie

Poniżej opisano niektóre tematy bardziej zaawansowane klas MFC i routingu wiadomości w systemie Windows i innych tematach wpływ ich.W tym miejscu informacje tylko opisano krótko.Odnoszą się do Odwołanie do biblioteki klas szczegółowe informacje na temat publicznych interfejsów API.Odnoszą się do kodu źródłowego biblioteki MFC więcej informacji na temat szczegółów implementacji.

Można znaleźć w technicznej 17 Uwaga szczegóły w oknie Oczyszczanie, bardzo ważny temat dla wszystkich CWnd-klasy pochodne.

Problemy z CWnd

Funkcja Członkowskie wykonania CWnd::OnChildNotify zapewnia wydajne i rozszerzalnej architekturze podrzędnych (znany również jako formanty) do systemu Windows hook lub w inny sposób informowany o wiadomości, poleceń i sterowania powiadomień, które go do ich nadrzędnego (lub "właściciel").Jeśli okno potomne (/ kontroli) C++ jest CWnd obiektu, funkcję wirtualną OnChildNotify jest wywoływana pierwszy z parametrów z oryginalnej wiadomości (oznacza to, że MSG struktury).Okna podrzędnego można samodzielnie wystawić wiadomości, to eat lub modyfikowanie wiadomości dla nadrzędnego (rzadko).

Domyślnie CWnd wykonania obsługuje następujące komunikaty o błędach i używa OnChildNotify hak, aby umożliwić podrzędnych systemu windows (kontrola) do pierwszego dostępu na wiadomość:

  • WM_MEASUREITEM i WM_DRAWITEM (self-draw)

  • WM_COMPAREITEM i WM_DELETEITEM (self-draw)

  • WM_HSCROLL i WM_VSCROLL

  • WM_CTLCOLOR

  • WM_PARENTNOTIFY

Można zauważyć OnChildNotify hak służy do zmieniania wiadomości rysowania przez właściciela do wiadomości self-draw.

Oprócz OnChildNotify hak, wiadomości przewijania mają dalsze routing zachowanie.Zobacz poniżej więcej szczegółów na temat pasków przewijania i źródeł WM_HSCROLL i WM_VSCROLL wiadomości.

Problemy z CFrameWnd

CFrameWnd klasy zawiera większość polecenia routingu i interfejsu użytkownika aktualizacji realizacji.Jest to przede wszystkim główna ramka okna aplikacji (CWinApp::m_pMainWnd), ale ma zastosowanie do wszystkich okien ramki.

Okno główne ramek jest okno z paskiem menu i jest nadrzędny pasek stanu lub komunikat wiersza.Można znaleźć w dyskusji powyższego polecenia routingu i WM_INITMENUPOPUP.

CFrameWnd klasy zapewnia zarządzanie aktywnego widoku.Następujące wiadomości są routowane przez widok aktywny:

  • Wszystkie wiadomości polecenia (Widok aktywny pobiera pierwszego dostępu do nich).

  • WM_HSCROLL i WM_VSCROLL wiadomości z tego samego poziomu przewiń paski (patrz poniżej).

  • WM_ACTIVATE (i WM_MDIACTIVATE dla MDI) Pobierz włączone do wywołania funkcji wirtualnych CView::OnActivateView.

Problemy z CMDIFrameWnd/CMDIChildWnd

Obie klasy okna ramki MDI pochodzić od CFrameWnd i dlatego są oba włączone sortowanie samego polecenia routingu i aktualizowanie interfejsu użytkownika w CFrameWnd.W typowych aplikacji MDI tylko okno główne ramki (czyli CMDIFrameWnd obiektu) posiada pasek menu i pasek stanu i dlatego jest głównym źródłem wykonania polecenia routingu.

Ogólny schemat routingu jest, że aktywnego okna podrzędnych MDI pobiera pierwszy dostęp do poleceń.Domyślnie PreTranslateMessage funkcje obsługi tabel accelerator dla obu okien podrzędnych MDI (pierwszy) i ramki MDI (drugi), jak również zazwyczaj obsługiwane przez standardowe akceleratory polecenia systemu MDI TranslateMDISysAccel (ostatni).

Problemy z paska przewijania

Podczas obsługi wiadomości przewijania (WM_HSCROLL/OnHScroll lub WM_VSCROLL/OnVScroll), należy spróbować napisać kod obsługi, więc nie polega na skąd pochodzą wiadomości paska przewijania.To nie tylko ogólne Windows problemu, ponieważ przewijania wiadomości mogą pochodzić z true scroll bar formantów lub z WS_HSCROLL/WS_VSCROLL przewiń paski, które nie są formanty paska przewijania.

Rozciąga się do umożliwienia kontroli paska przewijania za dziecko lub rodzeństwa okna są przewijane MFC (w rzeczywistości relacji nadrzędny i podrzędny między paska przewijania i okna są przewijane może być cokolwiek).Jest to szczególnie ważne dla pasków przewijania udostępnionych z rozdzielacza systemu windows.Można znaleźć w technicznej Uwaga 29 szczegółowe informacje na temat wdrażania CSplitterWnd tym więcej informacji na udostępnionych problemy paska przewijania.

Na stronie notatki, istnieją dwie CWnd schwytanych klas pochodnych, gdzie utworzenie Style pasków przewijania, określone w i nie są przekazywane do systemu Windows.Gdy dane są przekazywane do procedury tworzenia, WS_HSCROLL i WS_VSCROLL można samodzielnie ustawić, ale po utworzenia nie można zmienić.Oczywiście powinny bezpośrednio testowania lub ustaw WS_?Bity styl PRZEWIJANIA okna, które utworzyli.

Dla CMDIFrameWnd Style pasków przewijania można przekazać w Tworzenie lub LoadFrame są używane do tworzenia MDICLIENT.Jeśli chcesz mieć przewijaną obszaru MDICLIENT (takich jak Windows Menedżera programów) należy ustawić zarówno paska przewijania style (WS_HSCROLL | WS_VSCROLL) dla stylu, używane do tworzenia CMDIFrameWnd.

Dla CSplitterWnd stosować style pasków przewijania do pasków przewijania udostępnionego specjalne dla regionów rozdzielacza.Dla systemu windows rozdzielacza statycznego zwykle nie ustawi albo styl paska przewijania.Dla windows dynamiczne rozdzielacza będzie zazwyczaj mają scroll bar zestaw stylów w kierunku użytkownik zostanie podzielona, oznacza to, WS_HSCROLL jeżeli można podzielić wiersze, WS_VSCROLL , jeśli można podzielić kolumny.

Zobacz też

Inne zasoby

Uwagi techniczne przez liczbę

Uwagi techniczne według kategorii