Udostępnij za pośrednictwem


Dodawanie zdarzenia (ALT — Samouczek, część 5)

W tym kroku dodasz ClickIn zdarzenie i ClickOut do kontrolki ATL. Zdarzenie zostanie wyzwolony ClickIn , jeśli użytkownik kliknie w obrębie wielokąta i zostanie wyzwolony ClickOut , jeśli użytkownik kliknie poza. Zadania dodawania zdarzenia są następujące:

  • ClickIn Dodawanie metod i ClickOut

  • Generowanie biblioteki typów

  • Implementowanie interfejsów punktu połączenia

Dodawanie metod ClickIn i ClickOut

Po utworzeniu kontrolki ATL w kroku 2 zaznaczono pole wyboru Punkty połączenia. Spowodowało to utworzenie interfejsu _IPolyCtlEvents w pliku Polygon.idl. Pamiętaj, że nazwa interfejsu zaczyna się od podkreślenia. Jest to konwencja wskazująca, że interfejs jest interfejsem wewnętrznym. W związku z tym programy, które umożliwiają przeglądanie obiektów COM, mogą nie wyświetlać interfejsu użytkownikowi. Należy również pamiętać, że wybranie pozycji Punkty połączenia dodało następujący wiersz w pliku Polygon.idl, aby wskazać, że _IPolyCtlEvents jest to domyślny interfejs źródłowy:

[default, source] dispinterface _IPolyCtlEvents;

Atrybut źródłowy wskazuje, że kontrolka jest źródłem powiadomień, więc wywoła ten interfejs w kontenerze.

Teraz dodaj ClickIn metody i ClickOut do interfejsu _IPolyCtlEvents .

Aby dodać metody ClickIn i ClickOut

  1. W Eksplorator rozwiązań otwórz plik Polygon.idl i dodaj następujący kod w methods: obszarze w dispInterface_IPolyCtlEvents deklaracji biblioteki PolygonLib:

    [id(1), helpstring("method ClickIn")] void ClickIn([in] LONG x,[in] LONG y);
    [id(2), helpstring("method ClickOut")] void ClickOut([in] LONG x,[in] LONG y);
    

Metody ClickIn i ClickOut przyjmują współrzędne x i y klikniętego punktu jako parametry.

Generowanie biblioteki typów

W tym momencie wygeneruj bibliotekę typów, ponieważ projekt użyje jej do uzyskania informacji potrzebnych do utworzenia interfejsu punktu połączenia i interfejsu kontenera punktu połączenia dla kontrolki.

Aby wygenerować bibliotekę typów

  1. Ponownie skompiluj projekt.

    — lub —

  2. Kliknij prawym przyciskiem myszy plik Polygon.idl w Eksplorator rozwiązań i kliknij polecenie Skompiluj w menu skrótów.

Spowoduje to utworzenie pliku Polygon.tlb, który jest biblioteką typów. Plik Polygon.tlb nie jest widoczny z Eksplorator rozwiązań, ponieważ jest to plik binarny i nie można go wyświetlić ani edytować bezpośrednio.

Implementowanie interfejsów punktu połączenia

Zaimplementuj interfejs punktu połączenia i interfejs kontenera punktu połączenia dla kontrolki. W modelu COM zdarzenia są implementowane za pośrednictwem mechanizmu punktów połączenia. Aby odbierać zdarzenia z obiektu COM, kontener ustanawia połączenie doradcze z punktem połączenia, który implementuje obiekt COM. Ponieważ obiekt COM może mieć wiele punktów połączenia, obiekt COM implementuje również interfejs kontenera punktu połączenia. Za pomocą tego interfejsu kontener może określić, które punkty połączenia są obsługiwane.

Interfejs implementujący punkt połączenia nosi nazwę IConnectionPoint, a interfejs implementujący kontener punktu połączenia nosi nazwę IConnectionPointContainer.

Aby ułatwić implementację IConnectionPointprogramu , należy użyć Kreatora implementowania punktu połączenia. Ten kreator generuje IConnectionPoint interfejs, odczytując bibliotekę typów i wdrażając funkcję dla każdego zdarzenia, które można wyzwolić.

Aby zaimplementować punkty połączenia

  1. W Eksplorator rozwiązań otwórz plik _IPolyCtlEvents_CP.h i dodaj następujący kod w ramach public: instrukcji w CProxy_IPolyCtlEvents klasie :

    VOID Fire_ClickIn(LONG x, LONG y)
    {
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        CComVariant* pvars = new CComVariant[2];
        int nConnections = m_vec.GetSize();
    
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                pvars[1].vt = VT_I4;
                pvars[1].lVal = x;
                pvars[0].vt = VT_I4;
                pvars[0].lVal = y;
                DISPPARAMS disp = { pvars, NULL, 2, 0 };
                pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
            }
        }
        delete[] pvars;
    
    }
    VOID Fire_ClickOut(LONG x, LONG y)
    {
        T* pT = static_cast<T*>(this);
        int nConnectionIndex;
        CComVariant* pvars = new CComVariant[2];
        int nConnections = m_vec.GetSize();
    
        for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
        {
            pT->Lock();
            CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
            pT->Unlock();
            IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
            if (pDispatch != NULL)
            {
                pvars[1].vt = VT_I4;
                pvars[1].lVal = x;
                pvars[0].vt = VT_I4;
                pvars[0].lVal = y;
                DISPPARAMS disp = { pvars, NULL, 2, 0 };
                pDispatch->Invoke(0x2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
            }
        }
        delete[] pvars;
    
    }
    

Zobaczysz, że ten plik ma klasę o nazwie CProxy_IPolyCtlEvents , która pochodzi z klasy IConnectionPointImpl. _IPolyCtlEvents_CP.h definiuje teraz dwie metody Fire_ClickIn i Fire_ClickOut, które przyjmują dwa parametry współrzędnych. Te metody są wywoływane, gdy chcesz uruchomić zdarzenie z kontrolki.

Tworząc kontrolkę z wybraną opcją Punkty połączenia, plik _IPolyCtlEvents_CP.h został wygenerowany. Dodano ją również CProxy_PolyEvents do IConnectionPointContainerImpl wielu list dziedziczenia kontrolki i uwidoczniliśmy IConnectionPointContainer , dodając odpowiednie wpisy do mapy MODELU COM.

Zakończono implementowanie kodu w celu obsługi zdarzeń. Teraz dodaj kod w celu wyzwolenia zdarzeń w odpowiednim momencie. Pamiętaj, że uruchamiasz ClickIn zdarzenie lub ClickOut , gdy użytkownik kliknie lewy przycisk myszy w kontrolce. Aby dowiedzieć się, kiedy użytkownik kliknie przycisk, dodaj procedurę obsługi komunikatu WM_LBUTTONDOWN .

Aby dodać procedurę obsługi komunikatu WM_LBUTTONDOWN

  1. W widoku klasy kliknij prawym przyciskiem myszy klasę CPolyCtl i kliknij polecenie Właściwości w menu skrótów.

  2. W oknie Właściwości kliknij ikonę Komunikaty, a następnie kliknij WM_LBUTTONDOWN pozycję z listy po lewej stronie.

  3. Z wyświetlonej listy rozwijanej kliknij pozycję <Dodaj> przycisk OnLButtonDown. Deklaracja OnLButtonDown programu obsługi zostanie dodana do biblioteki PolyCtl.h, a implementacja programu obsługi zostanie dodana do PolyCtl.cpp.

Następnie zmodyfikuj procedurę obsługi.

Aby zmodyfikować metodę OnLButtonDown

  1. Zmień kod, który składa się z OnLButtonDown metody w PolyCtl.cpp (usunięcie dowolnego kodu umieszczonego przez kreatora), tak aby wyglądało to następująco:

    LRESULT CPolyCtl::OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, 
       BOOL& /*bHandled*/)
    {
       HRGN hRgn;
       WORD xPos = LOWORD(lParam);  // horizontal position of cursor
       WORD yPos = HIWORD(lParam);  // vertical position of cursor
    
       CalcPoints(m_rcPos);
    
       // Create a region from our list of points
       hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING);
    
       // If the clicked point is in our polygon then fire the ClickIn
       //  event otherwise we fire the ClickOut event
       if (PtInRegion(hRgn, xPos, yPos))
          Fire_ClickIn(xPos, yPos);
       else
          Fire_ClickOut(xPos, yPos);
    
       // Delete the region that we created
       DeleteObject(hRgn);
       return 0;
    }
    

Ten kod korzysta z punktów obliczanych w funkcji w OnDraw celu utworzenia regionu, który wykrywa kliknięcia myszy użytkownika za pomocą wywołania metody PtInRegion.

Parametr uMsg jest identyfikatorem obsługiwanego komunikatu systemu Windows. Dzięki temu można mieć jedną funkcję, która obsługuje szereg komunikatów. Parametry wParam i lParam to standardowe wartości obsługiwanego komunikatu. Parametr bHandled umożliwia określenie, czy funkcja obsłużyła komunikat. Domyślnie wartość jest ustawiona na WARTOŚĆ TRUE, aby wskazać, że funkcja obsłużyła komunikat, ale można ustawić ją na FALSE. Spowoduje to, że usługa ATL będzie nadal szukać innej funkcji obsługi komunikatów w celu wysłania komunikatu do.

Kompilowanie i testowanie kontrolki

Teraz wypróbuj swoje zdarzenia. Skompiluj kontrolkę i ponownie uruchom kontener testów kontrolek ActiveX. Tym razem wyświetl okno dziennika zdarzeń. Aby skierować zdarzenia do okna danych wyjściowych, kliknij pozycję Rejestrowanie w menu Opcje i wybierz pozycję Dziennik do okna danych wyjściowych. Wstaw kontrolkę i spróbuj kliknąć w oknie. Pamiętaj, że ClickIn jest uruchamiany, jeśli klikniesz w wypełnionym wielokącie i ClickOut zostanie wyzwolony po kliknięciu poza nim.

Następnie dodasz stronę właściwości.

Powrót do kroku 4 | w kroku 6

Zobacz też

Samouczek