TN021: routing poleceń i komunikatówTN021: Command and Message Routing

Uwaga

Następująca Uwaga techniczna nie została zaktualizowana, ponieważ została najpierw uwzględniona w dokumentacji online.The following technical note has not been updated since it was first included in the online documentation. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe.As a result, some procedures and topics might be out of date or incorrect. Aby uzyskać najnowsze informacje, zalecamy wyszukiwanie tematu zainteresowania w indeksie dokumentacji online.For the latest information, it is recommended that you search for the topic of interest in the online documentation index.

W tej uwadze opisano Routing i architekturę wysyłania poleceń oraz zaawansowane tematy w obszarze Ogólne Routing komunikatów okna.This note describes the command routing and dispatch architecture as well as advanced topics in general window message routing.

Zapoznaj się z Visual C++, aby uzyskać ogólne informacje dotyczące architektur opisanych w tym miejscu, szczególnie różnice między komunikatami systemu Windows, powiadomieniami kontroli i poleceniami.Please refer to Visual C++ for general details on the architectures described here, especially the distinction between Windows messages, control notifications, and commands. W tej uwadze założono, że wiesz już, jak rozwiązywać problemy opisane w wydrukowanej dokumentacji i dotyczy tylko bardzo zaawansowanych tematów.This note assumes you are very familiar with the issues described in the printed documentation and only addresses very advanced topics.

Funkcja routingu i wysyłania poleceń MFC 1,0 jest zmieniana na architekturę MFC 2,0Command Routing and Dispatch MFC 1.0 Functionality Evolves to MFC 2.0 Architecture

System Windows ma WM_COMMAND komunikat, który jest przeciążony do dostarczania powiadomień o poleceniach menu, klawiszy skrótów i powiadomieniach o kontrolkach okna dialogowego.Windows has the WM_COMMAND message that is overloaded to provide notifications of menu commands, accelerator keys and dialog-control notifications.

MFC 1,0 zostało utworzone na nieco przez umożliwienie procedury obsługi polecenia (na przykład "OnFileNew") w CWnd klasie pochodnej do wywołania w odpowiedzi na konkretne WM_COMMAND.MFC 1.0 built on that a little by allowing a command handler (for example, "OnFileNew") in a CWnd derived class to get called in response to a specific WM_COMMAND. Jest to przyklejane wraz ze strukturą danych o nazwie Mapa wiadomości i powoduje, że jest to bardzo wydajny mechanizm poleceń.This is glued together with a data structure called the message map, and results in a very space-efficient command mechanism.

MFC 1,0 udostępnia także dodatkowe funkcje oddzielające powiadomienia sterujące z komunikatów poleceń.MFC 1.0 also provided additional functionality for separating control notifications from command messages. Polecenia są reprezentowane przez 16-bitowy identyfikator, czasami znany jako identyfikator polecenia.Commands are represented by a 16-bit ID, sometimes known as a Command ID. Polecenia zwykle zaczynają się od CFrameWnd (czyli menu wybierają lub tłumaczy Akcelerator) i są kierowane do różnych innych okien.Commands normally start from a CFrameWnd (that is, a menu select or a translated accelerator) and get routed to a variety of other windows.

MFC 1,0 użycie polecenia routingu w ograniczonym sensie dla implementacji interfejsu wielu dokumentów (MDI).MFC 1.0 used command routing in a limited sense for the implementation of Multiple Document Interface (MDI). (W oknie ramka MDI polecenia są delegowane do aktywnego okna podrzędnego MDI).(An MDI frame window delegate commands to its active MDI Child window.)

Ta funkcja została uogólniona i rozszerzona w bibliotece MFC 2,0, aby umożliwić obsługę poleceń przez szerszy zakres obiektów (nie tylko obiektów okien).This functionality has been generalized and extended in MFC 2.0 to allow commands to be handled by a wider range of objects (not just window objects). Zapewnia bardziej formalną i rozszerzalną architekturę do routingu komunikatów i ponownie używa routingu docelowego polecenia dla nie tylko obsługi poleceń, ale również do aktualizowania obiektów interfejsu użytkownika (takich jak elementy menu i przyciski paska narzędzi), aby odzwierciedlić bieżącą dostępność polecenia.It provides a more formal and extensible architecture for routing messages and reuses the command target routing for not only handling of commands, but also for updating UI objects (like menu items and toolbar buttons) to reflect the current availability of a command.

Identyfikatory poleceńCommand IDs

Aby uzyskać wyjaśnienie procesu routingu i powiązania poleceń, zobacz Visual C++.See Visual C++ for an explanation of the command routing and binding process. Uwaga techniczna 20 zawiera informacje na temat nazewnictwa identyfikatorów.Technical Note 20 contains information on ID naming.

Do identyfikatorów poleceń używamy prefiksu ogólnego "ID_".We use the generic prefix "ID_" for command IDs. Identyfikatory poleceń są >= 0x8000.Command IDs are >= 0x8000. W wierszu komunikatu lub pasku stanu będzie wyświetlany ciąg opisu polecenia, jeśli istnieje zasób typu STRING z tymi samymi identyfikatorami, które są identyfikatora polecenia.The message line or status bar will show the command description string if there is a STRINGTABLE resource with the same IDs as the command ID.

W zasobach aplikacji identyfikator polecenia może pojawić się w kilku miejscach:In the resources of your application, a command ID can appears in several places:

  • W jednym z zasobów CIĄGÓW, który ma taki sam identyfikator jak monit wiersza wiadomości.In one STRINGTABLE resource that has the same ID as the message-line prompt.

  • W prawdopodobnie wielu zasobach MENU, które są dołączone do elementów menu, które wywołują to samo polecenie.In possibly many MENU resources that are attached to menu items that invoke the same command.

  • (Zaawansowane) w przycisku okna dialogowego dla polecenia GOSUB.(ADVANCED) in a dialog button for a GOSUB command.

W kodzie źródłowym aplikacji identyfikator polecenia może pojawić się w kilku miejscach:In the source code of your application, a command ID can appears in several places:

  • W zasobie. H (lub inny główny plik nagłówka symboli) do definiowania identyfikatorów poleceń specyficznych dla aplikacji.In your RESOURCE.H (or other main symbol header file) to define application-specific command IDs.

  • BYĆ może w tablicy identyfikatorów używanej do tworzenia paska narzędzi.PERHAPS In an ID array used to create a toolbar.

  • W ON_COMMAND makro.In an ON_COMMAND macro.

  • BYĆ może w ON_UPDATE_COMMAND_UI makro.PERHAPS In an ON_UPDATE_COMMAND_UI macro.

Obecnie jedyną implementacją w MFC wymagającą identyfikatorów poleceń jest >= 0x8000 jest implementacją okien dialogowych/poleceń GOSUB.Currently, the only implementation in MFC that requires command IDs be >= 0x8000 is the implementation of GOSUB dialogs/commands.

Polecenia GOSUB, używanie architektury poleceń w oknach dialogowychGOSUB Commands, Using Command Architecture in Dialogs

Architektura poleceń routingu i włączania poleceń działa dobrze w przypadku okien ramowych, elementów menu, przycisków paska narzędzi, przycisków paska dialogowego, innych pasków sterowania i innych elementów interfejsu użytkownika przeznaczonych do aktualizacji poleceń na żądanie i trasy oraz do sterowania identyfikatorami do głównego obiektu docelowego polecenia (zazwyczaj okno ramki głównej).The command architecture of routing and enabling commands works well with frame windows, menu items, toolbar buttons, dialog bar buttons, other control bars and other user-interface elements designed to update on demand and route commands or control IDs to a main command target (usually the main frame window). Ten obiekt docelowy polecenia głównego może skierować polecenie lub powiadomienia kontroli do innych obiektów docelowych poleceń stosownie do potrzeb.That main command target may route the command or control notifications to other command target objects as appropriate.

Okno dialogowe (modalne lub niemodalne) może korzystać z niektórych funkcji architektury poleceń, Jeśli przypiszesz identyfikator kontrolki okna dialogowego do odpowiedniego identyfikatora polecenia.A dialog (modal or modeless) can benefit from some of the features of the command architecture if you assign the control ID of the dialog control to the appropriate command ID. Obsługa okien dialogowych nie jest automatyczna, dlatego może być konieczne napisanie dodatkowego kodu.Support for dialogs is not automatic, so you may have to write some additional code.

Należy pamiętać, że aby wszystkie te funkcje działały prawidłowo, identyfikatory poleceń powinny być >= 0x8000.Note that for all these features to work properly, your command IDs should be >= 0x8000. Ze względu na to, że wiele okien dialogowych może być kierowanych do tej samej ramki, udostępnione polecenia powinny być >= 0x8000, a nieudostępnione IDCs w określonym oknie dialogowym powinny być <= 0x7FFF.Since many dialogs could get routed to the same frame, shared commands should be >= 0x8000, while the nonshared IDCs in a specific dialog should be <= 0x7FFF.

Możesz umieścić normalny przycisk w normalnym modalnym oknie dialogowym z IDC zestawu przycisków ustawionym na odpowiedni identyfikator polecenia.You can place a normal button in a normal modal dialog with the IDC of the button set to the appropriate command ID. Gdy użytkownik wybierze przycisk, właściciel okna dialogowego (zwykle okno głównej ramki) pobiera polecenie podobnie jak każde inne polecenie.When the user selects the button, the owner of the dialog (usually the main frame window) gets the command just like any other command. Jest to nazywane GOSUB poleceniem, ponieważ jest zwykle używane do wyłączenia kolejnego okna dialogowego (GOSUB pierwszego okna dialogowego).This is called a GOSUB command since it usually is used to bring up another dialog (a GOSUB of the first dialog).

Możesz również wywołać funkcję CWnd::UpdateDialogControls w oknie dialogowym i przekazać ją do adresu głównego okna ramki.You can also call the function CWnd::UpdateDialogControls on your dialog and pass it the address of your main frame window. Ta funkcja włącza lub wyłącza kontrolki okna dialogowego w zależności od tego, czy zawierają one programy obsługi poleceń w ramce.This function will enable or disable your dialog controls based on whether they have command handlers in the frame. Ta funkcja jest wywoływana automatycznie w przypadku pasków sterowania w pętli bezczynności aplikacji, ale należy wywołać ją bezpośrednio dla zwykłych okien dialogowych, które mają mieć tę funkcję.This function is called automatically for you for control bars in your application's idle loop, but you must call it directly for normal dialogs that you wish to have this feature.

Gdy ON_UPDATE_COMMAND_UI jest wywoływanaWhen ON_UPDATE_COMMAND_UI is Called

Utrzymywanie stanu włączenia/zaznaczenia wszystkich elementów menu programu przez cały czas może być niedrogim kosztownym problemem.Maintaining the enabled/checked state of all a program's menu items all the time can be a computationally expensive problem. Typową techniką jest włączenie/sprawdzenie elementów menu tylko wtedy, gdy użytkownik wybierze menu podręczne.A common technique is to enable/check menu items only when the user selects the POPUP. Implementacja MFC 2,0 CFrameWnd obsługuje komunikat WM_INITMENUPOPUP i używa architektury routingu poleceń do określenia stanu menu za pośrednictwem programów obsługi ON_UPDATE_COMMAND_UI.The MFC 2.0 implementation of CFrameWnd handles the WM_INITMENUPOPUP message and uses the command routing architecture to determine the states of menus through ON_UPDATE_COMMAND_UI handlers.

CFrameWnd obsługuje również komunikat WM_ENTERIDLE, aby opisać bieżący element menu wybrany na pasku stanu (znany również jako wiersz wiadomości).CFrameWnd also handles the WM_ENTERIDLE message to describe the current menu item selected on the status bar (also known as the message line).

Struktura menu aplikacji edytowana przez Visual C++ jest używana do reprezentowania potencjalnych poleceń dostępnych w czasie WM_INITMENUPOPUP.An application's menu structure, edited by Visual C++, is used to represent the potential commands available at WM_INITMENUPOPUP time. Programy obsługi ON_UPDATE_COMMAND_UI mogą modyfikować stan lub tekst menu lub w przypadku zaawansowanych zastosowanych (takich jak lista MRU plików lub menu podręczne zleceń OLE), a w rzeczywistości modyfikować strukturę menu przed narysowaniem menu.ON_UPDATE_COMMAND_UI handlers can modify the state or text of a menu, or for advanced uses (like the File MRU list or the OLE Verbs pop-up menu), actually modify the menu structure before the menu is drawn.

Ta sama kolejność przetwarzania ON_UPDATE_COMMAND_UI jest wykonywana dla pasków narzędzi (i innych pasków sterowania), gdy aplikacja przejdzie do jej pętli bezczynności.The same sort of ON_UPDATE_COMMAND_UI processing is done for toolbars (and other control bars) when the application enters its idle loop. Aby uzyskać więcej informacji na temat pasków sterowania, zobacz Dokumentacja biblioteki klas i Uwaga techniczna 31 .See the Class Library Reference and Technical Note 31 for more information on control bars.

Zagnieżdżone menu wyskakująceNested Pop-up Menus

Jeśli używasz zagnieżdżonej struktury menu, Zauważ, że program obsługi ON_UPDATE_COMMAND_UI dla pierwszego elementu menu w menu podręcznym jest wywoływany w dwóch różnych przypadkach.If you are using a nested menu structure, you will notice that the ON_UPDATE_COMMAND_UI handler for the first menu item in the pop-up menu is called in two different cases.

Po pierwsze jest wywoływana dla samego menu podręcznego.First, it is called for the pop-up menu itself. Jest to konieczne, ponieważ menu podręczne nie mają identyfikatorów i używamy identyfikatora pierwszego elementu menu menu podręcznego, aby odwołać się do całego menu podręcznego.This is necessary because pop-up menus do not have IDs and we use the ID of the first menu item of the pop-up menu to refer to the entire pop-up menu. W takim przypadku m_pSubMenu zmienna członkowska CCmdUI obiektu będzie mieć wartość różną od null i będzie wskazywała menu podręczne.In this case, the m_pSubMenu member variable of the CCmdUI object will be non-NULL and will point to the pop-up menu.

Po drugie, jest wywoływana tuż przed narysowaniem elementów menu w menu podręcznym.Second, it is called just before the menu items in the pop-up menu are to be drawn. W tym przypadku identyfikator odwołuje się tylko do pierwszego elementu menu, a zmienna członkowska m_pSubMenu CCmdUI obiektu będzie równa null.In this case, the ID refers just to the first menu item and the m_pSubMenu member variable of the CCmdUI object will be NULL.

Pozwala to na włączenie menu podręcznego w odróżnieniu od elementów menu, ale wymaga napisania kodu z obsługą menu.This allows you to enable the pop-up menu distinct from its menu items, but requires that you write some menu aware code. Na przykład w menu zagnieżdżonym o następującej strukturze:For example, in a nested menu with the following structure:

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

Polecenia ID_NEW_SHEET i ID_NEW_CHART mogą być niezależnie włączone lub wyłączone.The ID_NEW_SHEET and ID_NEW_CHART commands can be independently enabled or disabled. Nowe menu podręczne powinno być włączone, jeśli jest włączona jedna z dwóch.The New pop-up menu should be enabled if either of the two is enabled.

Procedura obsługi poleceń dla ID_NEW_SHEET (pierwsze polecenie w wyskakującym okienku) będzie wyglądać następująco:The command handler for ID_NEW_SHEET (the first command in the pop-up) would look something like:

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

Procedura obsługi poleceń dla ID_NEW_CHART będzie normalną procedurą obsługi poleceń aktualizacji i wygląda następująco:The command handler for ID_NEW_CHART would be a normal update command handler and look something like:

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

ON_COMMAND i ON_BN_CLICKEDON_COMMAND and ON_BN_CLICKED

Makra mapy komunikatów dla ON_COMMAND i ON_BN_CLICKED są takie same.The message map macros for ON_COMMAND and ON_BN_CLICKED are the same. Mechanizm routingu powiadomień polecenia MFC i kontroli używa tylko identyfikatora polecenia, aby określić, gdzie ma być kierowany.The MFC command and control notification routing mechanism only uses the command ID to decide where to route to. Powiadomienia sterujące z kodem powiadomień o wartości zero (BN_CLICKED) są interpretowane jako polecenia.Control notifications with control notification code of zero (BN_CLICKED) are interpreted as commands.

Uwaga

W rzeczywistości wszystkie komunikaty powiadomień sterowania przechodzą przez łańcuch obsługi poleceń.In fact, all control notification messages go through the command handler chain. Na przykład jest technicznie możliwe, aby można było napisać procedurę obsługi powiadomień kontrolki dla EN_CHANGE w klasie dokumentu.For example, it is technically possible for you to write a control notification handler for EN_CHANGE in your document class. Nie jest to ogólnie zalecane, ponieważ praktyczne aplikacje tej funkcji są nieobsługiwane przez ClassWizard, a korzystanie z funkcji może spowodować delikatny kod.This is not generally advisable because the practical applications of this feature are few, the feature is not supported by ClassWizard, and use of the feature can result in fragile code.

Wyłączanie automatycznego wyłączania kontrolek przyciskówDisabling the Automatic Disabling of Button Controls

Jeśli umieścisz kontrolkę przycisku na pasku dialogowym lub w oknie dialogowym, przy użyciu którego wywołujesz CWnd:: UpdateDialogControls , zobaczysz, że przyciski, które nie mają programów ON_COMMAND lub ON_UPDATE_COMMAND_UI , zostaną automatycznie wyłączone przez platformę.If you place a button control on a dialog bar, or in a dialog using where you are calling CWnd::UpdateDialogControls on your own, you will notice that buttons which do not have ON_COMMAND or ON_UPDATE_COMMAND_UI handlers will be automatically disabled for you by the framework. W niektórych przypadkach nie trzeba mieć programu obsługi, ale przycisk ma pozostać włączony.In some cases, you will not need to have a handler, but you will want the button to remain enabled. Najprostszym sposobem osiągnięcia tego celu jest dodanie fikcyjnej procedury obsługi polecenia (łatwy do wykonania z ClassWizard) i nic nie rób.The easiest way to achieve this is to add a dummy command handler (easy to do with ClassWizard) and do nothing in it.

Routing komunikatów oknaWindow Message Routing

Poniżej opisano niektóre bardziej zaawansowane tematy dotyczące klas MFC oraz sposób ich działania w ramach routingu komunikatów systemu Windows i innych tematów.The following describes some more advanced topics on the MFC classes and how Windows message routing and other topics impact them. Informacje w tym miejscu są opisane tylko krótko.The information here is only described briefly. Szczegółowe informacje na temat publicznych interfejsów API można znaleźć w dokumentacji biblioteki klas .Refer to the Class Library Reference for details about public APIs. Aby uzyskać więcej informacji na temat szczegółów implementacji, zapoznaj się z kodem źródłowym biblioteki MFC.Please refer to the MFC library source code for more information on implementation details.

Aby uzyskać szczegółowe informacje na temat oczyszczania okna, należy zapoznać się z uwagami technicznymi dotyczącymi wszystkich klas pochodnych CWnd.Please refer to Technical Note 17 for details on Window cleanup, a very important topic for all CWnd-derived classes.

CWnd problemyCWnd Issues

Implementacja funkcji składowej CWnd:: OnChildNotify zapewnia zaawansowaną i rozszerzalną architekturę okien podrzędnych (nazywanych również kontrolkami) do haka lub w inny sposób informowanie o komunikatach, poleceniach i powiadomieniach o kontrolkach, które przechodzą do ich rodzica (lub "właściciel").The implementation member function CWnd::OnChildNotify provides a powerful and extensible architecture for child windows (also known as controls) to hook or otherwise be informed of messages, commands, and control notifications that go to their parent (or "owner"). Jeśli okno podrzędne (/Control) jest obiektem języka C++ CWnd , funkcja wirtualna OnChildNotify jest wywoływana najpierw z parametrami z oryginalnej wiadomości (czyli strukturą komunikatów ).If the child window (/control) is a C++ CWnd object itself, the virtual function OnChildNotify is called first with the parameters from the original message (that is, a MSG structure). Okno podrzędne może opuścić komunikat, Eat lub zmodyfikować komunikat dla elementu nadrzędnego (rzadki).The child window can leave the message alone, eat it, or modify the message for the parent (rare).

Domyślna implementacja CWnd obsługuje następujące komunikaty i używa punktu zaczepienia OnChildNotify , aby zezwolić podrzędnym systemom Windows (kontrolki) na pierwszy dostęp w komunikacie:The default CWnd implementation handles the following messages and uses the OnChildNotify hook to allow child windows (controls) to first access at the message:

  • WM_MEASUREITEM i WM_DRAWITEM (dla samorysowania)WM_MEASUREITEM and WM_DRAWITEM (for self-draw)

  • WM_COMPAREITEM i WM_DELETEITEM (dla samorysowania)WM_COMPAREITEM and WM_DELETEITEM (for self-draw)

  • WM_HSCROLL i WM_VSCROLLWM_HSCROLL and WM_VSCROLL

  • WM_CTLCOLORWM_CTLCOLOR

  • WM_PARENTNOTIFYWM_PARENTNOTIFY

Zauważysz, że hak OnChildNotify służy do zmiany komunikatów rysowanych przez właściciela w wiadomościach samodzielnych.You will notice the OnChildNotify hook is used for changing owner-draw messages into self-draw messages.

Oprócz punktu zaczepienia OnChildNotify komunikaty przewijania mają dalsze zachowanie routingu.In addition to the OnChildNotify hook, scroll messages have further routing behavior. Więcej informacji na temat pasków przewijania i źródeł WM_HSCROLL i komunikatów WM_VSCROLL można znaleźć poniżej.Please see below for more details on scroll bars and sources of WM_HSCROLL and WM_VSCROLL messages.

Obiektu CFrameWnd problemyCFrameWnd Issues

Klasa obiektu CFrameWnd zawiera większość poleceń routingu i interfejsu użytkownika.The CFrameWnd class provides most of the command routing and user-interface updating implementation. Jest to używane głównie dla głównego okna ramowego aplikacji (CWinApp:: m_pMainWnd), ale ma zastosowanie do wszystkich okien ramowych.This is primarily used for the main frame window of the application (CWinApp::m_pMainWnd) but applies to all frame windows.

Okno głównej ramki jest oknem z paskiem menu i jest elementem nadrzędnym paska stanu lub wiersza wiadomości.The main frame window is the window with the menu bar and is the parent of the status bar or message line. Zapoznaj się z powyższą dyskusją dotyczącą routingu poleceń i WM_INITMENUPOPUP.Please refer to the above discussion on command routing and WM_INITMENUPOPUP.

Klasa obiektu CFrameWnd umożliwia zarządzanie aktywnym widokiem.The CFrameWnd class provides management of the active view. Następujące komunikaty są kierowane przez aktywny widok:The following messages are routed through the active view:

  • Wszystkie komunikaty poleceń (aktywny widok uzyskują pierwszy dostęp do nich).All command messages (the active view gets first access to them).

  • WM_HSCROLL i WM_VSCROLL komunikatów z pasków przewijania elementów równorzędnych (patrz poniżej).WM_HSCROLL and WM_VSCROLL messages from sibling scroll bars (see below).

  • WM_ACTIVATE (i WM_MDIACTIVATE dla MDI) są włączone wywołania funkcji wirtualnej CView:: OnActivateView.WM_ACTIVATE (and WM_MDIACTIVATE for MDI) get turned into calls to the virtual function CView::OnActivateView.

Problemy z CMDIFrameWnd/CMDIChildWndCMDIFrameWnd/CMDIChildWnd Issues

Obie klasy okna ramki MDI pochodzą z obiektu CFrameWnd i w związku z tym są włączone dla tego samego sortowania poleceń i aktualizacji interfejsu użytkownika, które są dostępne w obiektu CFrameWnd.Both MDI frame window classes derive from CFrameWnd and therefore are both enabled for the same sort of command routing and user-interface updating provided in CFrameWnd. W typowej aplikacji MDI tylko główne okno ramek (czyli obiekt CMDIFrameWnd ) utrzymuje pasek menu i pasek stanu, dlatego jest głównym źródłem implementacji poleceń routingu.In a typical MDI application, only the main frame window (that is, the CMDIFrameWnd object) holds the menu bar and the status bar and therefore is the main source of the command routing implementation.

Ogólnym schematem routingu jest to, że aktywne okno podrzędne MDI uzyskuje pierwszy dostęp do poleceń.The general routing scheme is that the active MDI child window gets first access to commands. Domyślne funkcje PreTranslateMessage obsługują tabele akceleratorów dla okien podrzędnych MDI (pierwszy) i ramki MDI (sekundę), a także standardowe akceleratory poleceń systemu MDI zwykle obsługiwane przez TranslateMDISysAccel (Last).The default PreTranslateMessage functions handle accelerator tables for both MDI child windows (first) and the MDI frame (second) as well as the standard MDI system-command accelerators normally handled by TranslateMDISysAccel (last).

Problemy z paskiem przewijaniaScroll Bar Issues

Podczas obsługi funkcji Scroll-Message (WM_HSCROLL / OnHScroll i/lub WM_VSCROLL / OnVScroll) należy spróbować napisać kod programu obsługi, aby nie zależeć od lokalizacji, z której pochodzi komunikat paska przewijania.When handling scroll-message (WM_HSCROLL/OnHScroll and/or WM_VSCROLL/OnVScroll), you should try to write the handler code so it does not rely on where the scroll bar message came from. Jest to nie tylko ogólny problem z systemem Windows, ponieważ komunikaty przewijania mogą pochodzić z rzeczywistych kontrolek paska przewijania lub z WS_HSCROLL / WS_VSCROLL paski przewijania, które nie są kontrolkami paska przewijania.This is not only a general Windows issue, since scroll messages can come from true scroll bar controls or from WS_HSCROLL/WS_VSCROLL scroll bars which are not scroll bar controls.

MFC rozszerza, że aby kontrolki paska przewijania były elementami podrzędnymi lub równorzędnymi przewinięcie okna (w rzeczywistości relacja nadrzędny/podrzędny między paskiem przewijania i przewijanym oknem może mieć dowolną wartość).MFC extends that to allow for scroll bar controls to be either child or siblings of the window being scrolled (in fact, the parent/child relationship between the scroll bar and window being scrolled can be anything). Jest to szczególnie ważne w przypadku współużytkowanych pasków przewijania z oknami rozdzielacza.This is especially important for shared scroll bars with splitter windows. Zapoznaj się z uwagą techniczną 29 , aby zapoznać się ze szczegółami dotyczącymi implementacji CSplitterWnd , w tym więcej informacji na temat udostępnionych problemów z paskiem przewijania.Please refer to Technical Note 29 for details on the implementation of CSplitterWnd including more information on shared scroll bar issues.

Na notatce bocznej istnieją dwie klasy pochodne CWnd , w których style paska przewijania określone w czasie tworzenia są zalewkowane i nie są przesyłane do systemu Windows.On a side note, there are two CWnd derived classes where the scroll bar styles specified at create time are trapped and not passed to Windows. Po przekazaniu do procedury tworzenia WS_HSCROLL i WS_VSCROLL można niezależnie ustawić, ale po utworzeniu nie można zmienić.When passed to a creation routine, WS_HSCROLL and WS_VSCROLL can be independently set, but after creation cannot be changed. Oczywiście nie należy bezpośrednio testować ani ustawiać WS_SCROLLych bitów stylu utworzonego okna.Of course, you should not directly test or set the WS_SCROLL style bits of the window that they created.

Dla CMDIFrameWnd style paska przewijania, które są przekazywane do tworzenia lub LOADFRAME są używane do tworzenia MDICLIENT.For CMDIFrameWnd the scroll bar styles you pass in to Create or LoadFrame are used to create the MDICLIENT. Jeśli chcesz mieć przewijany obszar MDICLIENT (taki jak Menedżer programu Windows), upewnij się, że ustawisz oba style paska przewijania (WS_HSCROLL | WS_VSCROLL) dla stylu używanego do tworzenia CMDIFrameWnd.If you wish to have a scrollable MDICLIENT area (like the Windows Program Manager) be sure to set both scroll bar styles (WS_HSCROLL | WS_VSCROLL) for the style used to create the CMDIFrameWnd.

Dla CSplitterWnd style paska przewijania mają zastosowanie do specjalnych udostępnionych pasków przewijania dla regionów rozdzielacza.For CSplitterWnd the scroll bar styles apply to the special shared scroll bars for the splitter regions. W przypadku statycznych okien rozdzielacza zwykle nie ustawisz stylu paska przewijania.For static splitter windows, you will normally not set either scroll bar style. W przypadku dynamicznych okien rozdzielacza zwykle jest ustawiony styl paska przewijania dla kierunku, który będzie dzielony, czyli WS_HSCROLL , jeśli można podzielić wiersze, WS_VSCROLL , jeśli można podzielić kolumny.For dynamic splitter windows, you will usually have the scroll bar style set for the direction you will split, That is, WS_HSCROLL if you can split rows, WS_VSCROLL if you can split columns.

Zobacz teżSee also

Uwagi techniczne według numeruTechnical Notes by Number
Uwagi techniczne według kategoriiTechnical Notes by Category