Поделиться через


Добавление события (учебник ATL, часть 5)

На этом шаге вы добавите ClickIn событие и ClickOut событие в элемент управления ATL. Событие будет срабатывает ClickIn , если пользователь щелкает в многоугольнике и срабатывает ClickOut , если пользователь щелкает за пределами. Задачи для добавления события приведены следующим образом:

  • ClickIn Добавление и ClickOut методы

  • Создание библиотеки типов

  • Реализация интерфейсов точки подключения

Добавление методов ClickIn и ClickOut

При создании элемента управления ATL на шаге 2 установлен флажок "Точки подключения". Он создал _IPolyCtlEvents интерфейс в файле Polygon.idl. Обратите внимание, что имя интерфейса начинается с подчеркивания. Это соглашение, указывающее, что интерфейс является внутренним интерфейсом. Таким образом, программы, позволяющие просматривать COM-объекты, могут не отображать интерфейс пользователю. Кроме того, обратите внимание, что при выборе точек подключения в файле Polygon.idl добавлена следующая строка, указывающая, что _IPolyCtlEvents это исходный интерфейс по умолчанию:

[default, source] dispinterface _IPolyCtlEvents;

Исходный атрибут указывает, что элемент управления является источником уведомлений, поэтому он вызовет этот интерфейс в контейнере.

Теперь добавьте ClickIn методы и ClickOut методы в _IPolyCtlEvents интерфейс.

Добавление методов ClickIn и ClickOut

  1. В Обозреватель решений откройте Polygon.idl и добавьте следующий код methods: в dispInterface_IPolyCtlEvents объявлении библиотеки 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);
    

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. Он также добавил CProxy_PolyEvents и IConnectionPointContainerImpl в список наследования элемента управления несколько и предоставляется IConnectionPointContainer для вас путем добавления соответствующих записей на карту COM.

Вы завершите реализацию кода для поддержки событий. Теперь добавьте код, чтобы запустить события в соответствующий момент. Помните, что вы собираетесь запустить ClickIn или ClickOut событие, когда пользователь нажимает левую кнопку мыши в элементе управления. Чтобы узнать, когда пользователь нажимает кнопку, добавьте обработчик сообщения WM_LBUTTONDOWN .

Добавление обработчика для сообщения WM_LBUTTONDOWN

  1. В представлении классов щелкните правой кнопкой мыши класс и выберите пункт "Свойства" CPolyCtl в контекстном меню.

  2. В окне "Свойства" щелкните значок "Сообщения", а затем в WM_LBUTTONDOWN списке слева.

  3. В появившемся раскрывающемся списке нажмите кнопку <"Добавить> OnLButtonDown". OnLButtonDown Объявление обработчика будет добавлено в PolyCtl.h, а реализация обработчика будет добавлена в PolyCtl.cpp.

Затем измените обработчик.

Изменение метода OnLButtonDown

  1. Измените код, который состоит из OnLButtonDown метода в PolyCtl.cpp (удаление любого кода, размещенного мастером), чтобы он выглядел следующим образом:

    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. Это позволяет использовать одну функцию, которая обрабатывает диапазон сообщений. Параметры wParam и lParam — это стандартные значения для обрабатываемого сообщения. Параметр bHandled позволяет указать, обрабатывает ли функция сообщение или нет. По умолчанию значение имеет значение TRUE, чтобы указать, что функция обрабатывает сообщение, но ее можно задать значение FALSE. Это приведет к тому, что ATL продолжит поиск другой функции обработчика сообщений для отправки сообщения.

Сборка и тестирование элемента управления

Теперь попробуйте события. Создайте элемент управления и снова запустите контейнер тестов activeX. На этот раз просмотрите окно журнала событий. Чтобы перенаправить события в выходное окно, щелкните "Ведение журнала " в меню "Параметры " и выберите "Журнал" в окне вывода. Вставьте элемент управления и попробуйте щелкнуть в окне. Обратите внимание, что ClickIn при щелчке внутри заполненного многоугольника и ClickOut при щелчке за его пределами.

Затем вы добавите страницу свойств.

Вернуться к шагу 4 | Вкл. Шаг 6

См. также

Руководство