Krzysztof Mossakowski
Materiały dla studentów
 

Komunikaty
(klasa CCmdTarget)

MFC
Spis treści

Komunikaty
klasa CCmdTarget
Informacje ogólne
Klasa CCmdTarget
Mapa komunikatów
Wysyłanie i otrzymywanie komunikatów
Message Reflection
Hierarchia klas

  •  Informacje ogólne

    • MFC znacznie upraszcza obsługę komunikatów Windows w tworzonych aplikacjach

      • funkcja obsługi komunikatów znana z aplikacji API jest ukryta przed programistą

      • poszczególne komunikaty są obsługiwane w oddzielnych funkcjach deklarowanych w specjalnych mapach komunikatów (message maps)

    • Trzy grupy komunikatów obsługiwanych w aplikacjach pisanych przy użyciu MFC:

      • komunikaty systemu Windows (windows messages)
        - z wyjątkiem WM_COMMAND, który traktowany jako zawiadomienie z kontrolki lub polecenie
        - obsługiwane są przez klasę CWnd i wszystkie klasy pochodne, także widoki z klasy CView

      • zawiadomienia z kontrolek (control notifications)
        - zawiadomienia wysyłane jako WM_COMMAND z kontrolek i innych okien potomnych do okna rodzica
        - z wyjątkiem BN_CLICKED (czyli komunikatu wysyłanego przez przycisk w przypadku jego naciśnięcia), który jest traktowany jako polecenie
        - obsługiwane są przez klasę CWnd i potomne

      • polecenia (command messages)
        - polecenia wysyłane jako WM_COMMAND z interfejsu (menu, toolbar, akceleratory)
        - obsługiwane są przez aplikację, okna, dokumenty i wzorce dokumetów (czyli niekonieczne jest powiązanie z klasą CWnd lub oknem w systemie Windows)

    • Podstawową klasą obsługującą komunikaty jest CCmdTarget

[początek strony]

  •  Klasa CCmdTarget

    • Podstawowa klasa MFC w mechaniźmie obsługi komunikatów

    • Ma wbudowany mechanizm map komunikatów (message maps)
    • Ma metody umożliwiające zmianę kursora, na kursor oczekiwania (klepsydrę)
      • CCmdTarget::BeginWaitCursor włącza kursor oczekiwania
      • CCmdTarget::EndWaitCursor wyłącza kursor oczekiwania (przywracany jest ostatni kursor sprzed zmiany na oczekiwania)
      • CCmdTarget::RestoreWaitCursor przywraca kursor oczekiwania
    • Podstawową metodą jest CCmdTarget::OnCmdMsg
      • funkcja ta jest automatycznie wywoływana
      • jest używana do przekazywania i odsyłania poleceń (command messages) oraz uaktualnienia stanu poleceń
      • standardowa implementacja tej metody odsyła polecenia do obiektów, które powinny je obsłużyć lub obsługuje je samemu przeszukując mapę komunikatów
      • jest to metoda wirtualna, jej nadpisanie daje możliwość wprowadzenia różnej od standardowej drogi obsługi poleceń

[początek strony]

  •  Mapa komunikatów (message map)

    • Mapa komunikatów jest podstawowym mechanizmem obsługi komunikatów w aplikacjach MFC dającym klasie CCmdTarget (i wszystkim klasom pochodnym) możliwość obsługi komunikatów w przypisanych im funkcjom

    • Mapy komunikatów są automatycznie generowane przez AppWizard lub ClassWizard dla każdej klasy dziedziczącej z CCmdTarget

    • Przykład mapy komunkatów:

      BEGIN_MESSAGE_MAP(CMyView, CView)
        //{{AFX_MSG_MAP(CMyView)
        ON_WM_MOUSEACTIVATE()
        ON_COMMAND(ID_EDIT_CLEAR_ALL, OnEditClearAll)
        ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR_ALL, OnUpdateEditClearAll)
        ON_BN_CLICKED(ID_MY_BUTTON, OnMyButton)
        //}}AFX_MSG_MAP
        ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, OnDoSomething)
      END_MESSAGE_MAP()
    • Na początku mapy komunikatów jest wyszczególniona klasa bazowa, w której będzie szukana funkcja obsługi komunikatu, jeśli w danej klasie taka funkcja nie zostanie odnaleziona

    • Zapisy pomiędzy nawiasami {{AFX_MSG_MAP i }}AFX_MSG_MAP są obsługiwane przez ClassWizard i nie powinny być ręcznie modyfikowane

      • po dodaniu obsługi komunikatu (komunikatu Windows, polecenia lub zawiadomienia z kontrolki) przy pomocy ClassWizard zostaną dokonane następujące zmiany w plikach zawierających modyfikowaną klasę:
        - w .H zostanie dodana deklaracja nowej metody obsługi danego komunikatu
        - w .CPP zostanie dodana definicja tej nowej metody (standardowo pusta lub wywołująca tę funkcję dla klasy bazowej)
        - w .CPP w mapie komunikatów zostanie dodany wpis wiążący nową metodę z komunikatem

[początek strony]

  •  Wysyłanie i otrzymywanie komunikatów

    • Komunikaty wysyłane są w następujących przypadkach:

      • komunikaty Windows - reakcja systemu na działania użytkownika (np. przenoszenie okna lub zmiana rozmiaru) lub na zdarzenia systemowe (np. timer)

      • polecenia (command messages) - akcje z interfejsu użytkownika (menu, toolbar, akceleratory) lub uaktualnienie stanu poleceń (np. dostępności) wywoływane automatycznie przez aplikację MFC

      • zawiadomienia z kontrolek - reakcja na działania użytkownika na kontrolkach

    • Komunikaty otrzymuje CWinApp::Run, w której znajduje się pętla obsługi komunikatów

      • większość komunikatów Windows przesyłana jest do okna nadrzędnego aplikacji

      • komunikaty Windows kierowane bezpośrednio do danego okna są zwykle natychmiast przesyłane do niego (bez przejścia przez ścieżkę szukania funkcji obsługi)

      • polecenia są przesyłane do obiektów według kolejności na ścieżce szukania funkcji obsługi polecenia

[początek strony]

  •  Message Reflection

    • Daje możliwość obsługiwania komunikatów kontrolki w tej kontrolce (np. WM_COMMAND, WM_NOTIFY, WM_CTLCOLOR)

      • umożliwia to zawarcie całej obsługi w jednej kontrolce, bez potrzeby zmiany okna rodzica
        - standardowo okno dialogowe jest rodzicem wszystkich swoich kontrolek, do niego trafiają zawiadomienia (notifications) i w nim zawarty jest kod ich obsługi
        - zastosowanie message reflection daje większą możliwość przenoszenia kontrolki

    • Może być stosowane w kontrolkach Windows i ActiveX

    • Metody obsługi reflected messages mogą być dodawane do klasy kontrolki za pośrednictwem ClassWizard

      • w ClassWizard takie komunikaty są oznaczane znakiem równości dla odróżnienia od zwykłych komunikatów

[początek strony]

[początek strony]