다음을 통해 공유


이벤트 추가(ATL 자습서, 5부)

이 단계에서는 ATL 컨트롤에 ClickOut a ClickIn 및 이벤트를 추가합니다. 사용자가 다각형 내에서 클릭하면 이벤트가 발생 ClickIn 하며 사용자가 외부를 클릭하면 발생 ClickOut 합니다. 이벤트를 추가하는 작업은 다음과 같습니다.

  • ClickIn ClickOut 메서드 추가

  • 형식 라이브러리 생성

  • 연결점 인터페이스 구현

ClickIn 및 ClickOut 메서드 추가

2단계에서 ATL 컨트롤을 만들 때 연결점 확인란을 선택했습니다. Polygon.idl 파일에서 인터페이스를 만들었습니다 _IPolyCtlEvents . 인터페이스 이름은 밑줄로 시작합니다. 인터페이스가 내부 인터페이스임을 나타내는 규칙입니다. 따라서 COM 개체를 찾아볼 수 있는 프로그램은 사용자에게 인터페이스를 표시하지 않도록 선택할 수 있습니다. 또한 연결점을 선택하면 Polygon.idl 파일에 다음 줄이 추가되어 기본 원본 인터페이스임을 _IPolyCtlEvents 나타냅니다.

[default, source] dispinterface _IPolyCtlEvents;

원본 특성은 컨트롤이 알림의 원본임을 나타내므로 컨테이너에서 이 인터페이스를 호출합니다.

이제 인터페이스에 ClickInClickOut 메서드를 추가합니다 _IPolyCtlEvents .

ClickIn 및 ClickOut 메서드를 추가하려면

  1. 솔루션 탐색기 Polygon.idl을 열고 PolygonLib 라이브러리 선언 아래에 methods: dispInterface_IPolyCtlEvents 다음 코드를 추가합니다.

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

ClickOut 메서드는 ClickIn 클릭한 점의 x 및 y 좌표를 매개 변수로 사용합니다.

형식 라이브러리 생성

이 시점에서 형식 라이브러리를 생성합니다. 프로젝트가 이를 사용하여 연결점 인터페이스 및 컨트롤에 대한 연결점 컨테이너 인터페이스를 생성하는 데 필요한 정보를 가져오기 때문입니다.

형식 라이브러리를 생성하려면

  1. 프로젝트를 다시 빌드합니다.

    또는

  2. 솔루션 탐색기 Polygon.idl 파일을 마우스 오른쪽 단추로 클릭하고 바로 가기 메뉴에서 컴파일을 클릭합니다.

이렇게 하면 형식 라이브러리인 Polygon.tlb 파일이 만들어집니다. Polygon.tlb 파일은 이진 파일이며 직접 보거나 편집할 수 없으므로 솔루션 탐색기 표시되지 않습니다.

연결점 인터페이스 구현

컨트롤에 대한 연결점 인터페이스 및 연결점 컨테이너 인터페이스를 구현합니다. COM에서 이벤트는 연결 지점의 메커니즘을 통해 구현됩니다. COM 개체에서 이벤트를 수신하기 위해 컨테이너는 COM 개체가 구현하는 연결 지점에 대한 권고 연결을 설정합니다. COM 개체에는 여러 연결점이 있을 수 있으므로 COM 개체는 연결점 컨테이너 인터페이스도 구현합니다. 이 인터페이스를 통해 컨테이너는 지원되는 연결점을 결정할 수 있습니다.

연결점을 구현하는 인터페이스를 호출 IConnectionPoint하고 연결점 컨테이너를 구현하는 인터페이스를 호출 IConnectionPointContainer합니다.

구현 IConnectionPoint을 돕기 위해 연결점 구현 마법사를 사용합니다. 이 마법사는 형식 라이브러리를 IConnectionPoint 읽고 실행할 수 있는 각 이벤트에 대한 함수를 구현하여 인터페이스를 생성합니다.

연결점을 구현하려면

  1. 솔루션 탐색기 _IPolyCtlEvents_CP.h를 열고 클래스의 public:CProxy_IPolyCtlEvents 아래에 다음 코드를 추가합니다.

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

이 파일에는 파생되는 클래스 CProxy_IPolyCtlEvents 가 있습니다 IConnectionPointImpl. 이제 _IPolyCtlEvents_CP.h는 두 개의 메서드 Fire_ClickIn 를 정의하고 Fire_ClickOut두 개의 좌표 매개 변수를 사용합니다. 컨트롤에서 이벤트를 실행하려는 경우 이러한 메서드를 호출합니다.

연결점 옵션이 선택된 컨트롤을 만들어 _IPolyCtlEvents_CP.h 파일이 생성되었습니다. 또한 COM 맵에 적절한 항목을 추가하여 컨트롤의 여러 상속 목록에 추가하고 CProxy_PolyEvents IConnectionPointContainerImpl 노출 IConnectionPointContainer 합니다.

이벤트를 지원하는 코드 구현이 완료되었습니다. 이제 적절한 순간에 이벤트를 발생하도록 몇 가지 코드를 추가합니다. 사용자가 컨트롤의 ClickIn 왼쪽 마우스 단추를 클릭하면 이벤트나 ClickOut 이벤트가 발생합니다. 사용자가 단추를 클릭하는 시기를 확인하려면 메시지에 대한 처리기를 추가합니다 WM_LBUTTONDOWN .

WM_LBUTTONDOWN 메시지에 대한 처리기를 추가하려면

  1. 클래스 뷰에서 클래스를 마우스 오른쪽 단추로 CPolyCtl 클릭하고 바로 가기 메뉴에서 속성을 클릭합니다.

  2. 속성 창에서 메시지 아이콘을 클릭한 다음 왼쪽의 목록에서 클릭합니다WM_LBUTTONDOWN.

  3. 표시되는 드롭다운 목록에서 OnLButtonDown 추가를 클릭합니다<.> 처리기 선언이 OnLButtonDown PolyCtl.h에 추가되고 처리기 구현이 PolyCtl.cpp 추가됩니다.

다음으로 처리기를 수정합니다.

OnLButtonDown 메서드를 수정하려면

  1. 다음과 같이 표시되도록 PolyCtl.cpp 메서드를 구성하는 OnLButtonDown 코드를 변경합니다(마법사에서 배치한 모든 코드 삭제).

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

이 코드는 함수에서 계산된 OnDraw 점을 사용하여 호출 PtInRegion을 통해 사용자의 마우스 클릭을 감지하는 영역을 만듭니다.

uMsg 매개 변수는 처리 중인 Windows 메시지의 ID입니다. 이렇게 하면 메시지 범위를 처리하는 하나의 함수를 사용할 수 있습니다. wParamlParam 매개 변수는 처리 중인 메시지에 대한 표준 값입니다. 매개 변수 bHandled 를 사용하면 함수가 메시지를 처리했는지 여부를 지정할 수 있습니다. 기본적으로 값은 함수가 메시지를 처리했음을 나타내기 위해 TRUE로 설정되지만 FALSE로 설정할 수 있습니다. 이로 인해 ATL은 메시지를 보낼 다른 메시지 처리기 함수를 계속 찾습니다.

컨트롤 빌드 및 테스트

이제 이벤트를 사용해 보세요. 컨트롤을 빌드하고 ActiveX 컨트롤 테스트 컨테이너를 다시 시작합니다. 이번에는 이벤트 로그 창을 봅니다. 이벤트를 출력 창으로 라우팅하려면 옵션 메뉴에서 로깅클릭하고 출력 창에 로그를 선택합니다. 컨트롤을 삽입하고 창에서 클릭해 봅니다. ClickIn 채워진 다각형 내에서 클릭하면 발생하며 ClickOut 외부를 클릭하면 발생합니다.

다음으로 속성 페이지를 추가합니다.

4 | 단계에서 6단계로 돌아가기

참고 항목

자습서