Шаг 118 - Добавление событий

Теперь надо добавить события ClickIn и ClickOut к нашему элементу управления.

Событие ClickIn вызывается когда пользователь кликает мышью внутри многоугольника, ClickOut вызывается когда снаружи.

Когда мы создавали элемент управления мы выбрали флажок Support Connection Point. Это привело к созданию интерфейса IPolyCtlEvents в файле .idl. Обратите внимание, что имя интерфейса начинается с символов подчеркивания. Это правило существует для того, чтобы указать, что интерфейс внутренний. Таким образом программы, которые позволяют просматривать COM объекты, могут выбирать, какой интерфейс показывать пользователю. Также обратите внимание, что в .idl файле Support Connection Points добавил строку с указанием, что IPolyCtlEvents является заданным по умолчанию исходным интерфейсом.

Теперь Вы должны добавить методы ClickIn и ClickOut к интерфейсу IPolyCtlEvents:

  1. Щелкаем правой кнопкой на IPolyCtlEvents в ClassView и выбираем Add Method из меню.
  2. Выберите тип возврата void.
  3. Напечатайте ClickIn в поле Method Name.
  4. Введите [in] long x, [in] long y в поле параметров.
  5. Нажмите OK.

Проверьте .idl файл, чтобы там появился код добавленный к IPolyCtlEvents. Затем повторите туже самую процедуру, чтобы определить метод ClickOut с теми же самыми параметрами и типом возврата. IPolyCtlEvents dispinterface в вашем .idl файле должен теперь выглядеть следующим образом:

dispinterface _IPolyCtlEvents
{
	properties:
	methods:
	[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);
};

Методы ClickIn и ClickOut получают координаты x и у нажатой точки в качестве параметров.

Теперь нужно сгенерировать библиотеку типов. Чтобы сделать это можно или собрать проект или щелкнуть правой кнопкой мыши на .idl файле в FileView и выбрать Compile Polygon.idl. Это создаст файл Polygon.tlb, который будет являться вашей библиотекой типов.

Затем выполните интерфейс точки соединения и интерфейс контейнера точки соединения для вашего элемента управления. (В COM события выполнены через механизм точек соединения). Чтобы получать события от объекта COM контейнер устанавливает консультативное соединение с точкой соединения, которую объект COM использует. Так как объект COM может иметь много точек соединения, то объект COM также создает интерфейс контейнера точки соединения. Через этот интерфейс контейнер может определять, какие точки соединения работают. Интерфейс, который создает точку соединения называется IConnectionPoint, а интерфейс который создает контейнер точки соединения называется IConnectionPointContainer.

Чтобы применять IConnectionPoint используйте ClassView для обращения к мастеру точки соединения. Этот мастер генерирует интерфейс IConnectionPoint читая вашу библиотеку типов и выполняется для каждого события, которое может быть вызвано.

Чтобы запустить мастера выполните следующие действия:

  1. Идите в ClassView (в меню View нажмите Workspace, чтобы увидеть ClassView).
  2. Щелчок правой кнопкой на классе реализации вашего элемента управления, в данном случае CPolyCtl.
  3. В контекстном меню, выберите Implement Connection Point...
  4. Выберите _PolyEvents из списка Interfaces, затем нажмите OK и класс для точки соединения будет сгенерирован, в данном случае CProxy_IPolyCtlEvents.

    118_1.gif (4733 b)

    Если Вы посмотрите сгенерированный PolygonCP.h файл в FileView, Вы увидите, что этот класс с именем CProxy_PolyCtlEvents порожден от IConnectionPointImpl. PolygonCP.h также определяет два метода Fire_ClickIn и Fire_ClickOut, которые берут два параметра. Эти методы Вы вызываете когда хотите сгенерировать событие из вашего элемента управления.

    Мастер добавит CProxy_PolyEvents и IConnectionPointContainerImpl к множественному списку наследования вашего элемента управления и изменит IConnectionPointContainer, добавляя соответствующие входы к карте COM.

    Вы закончили создавать код для поддержки событий. Теперь нужно добавить код к вызову события в соответствующий момент. Не забудьте, Вы вызываете ClickIn или ClickOut событие когда пользователь нажимает левую кнопку мыши в элементе управления. Чтобы выяснять, когда пользователь нажимает кнопку, сначала добавляем обработчик для WM_LBUTTONDOWN сообщения. В ClassView правый щелчок на классе CPolyCtl и выбираем Add Windows Message Handler... из контекстного меню. Затем выберите WM_LBUTTONDOWN из списка слева и нажмите кнопку Add Handler. Нажмите OK.

    Далее добавьте новый код к функции OnLButtonDown в PolyCtl.h (удалите любой код помещенный мастером) так, чтобы OnLButtonDown теперь выглядела следующим образом:

    LRESULT CPolyCtl::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
    	HRGN hRgn;
    	WORD xPos = LOWORD(lParam);  // горизонтальная позиция курсора
    	WORD yPos = HIWORD(lParam);  // вертикальная позиция курсора
    
    	CalcPoints(m_rcPos);
    
    	// Создаем регион из списка точек
    	hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING);
    
    	// Если нажатая точка внутри полигона, то вызываем событие 
    	// ClickIn, иначе вызываем событие ClickOut
    	if (PtInRegion(hRgn, xPos, yPos))
    		Fire_ClickIn(xPos, yPos);
    	else
    		Fire_ClickOut(xPos, yPos);
    
    	// Удаляем созданный регион
    	DeleteObject(hRgn);
    	return 0;
    }
    

    Так как Вы уже вычислили точки многоугольника в функции OnDraw, используйте их в OnLButtonDown, чтобы создать область. Затем используйте функцию PtInRegion из API, чтобы определить, находится нажатая точка внутри многоугольника или нет.

    UMsg параметр - ID обрабатываемого сообщения Windows. Это позволяет иметь одну функцию, которая обрабатывает диапазон сообщений. wParam и lParam - стандартные значения для обрабатываемого сообщения. Параметр bHandled позволяет Вам определять, обрабатывала ли функция сообщение или нет. По умолчанию, значение установлено к TRUE, чтобы указать, что функция обработала сообщение, но Вы можете устанавливать ее и к FALSE. Установка в FALSE заставит ATL продолжать искать другую функцию обработчика сообщения, чтобы послать сообщение.

    Теперь проверьте ваши события. Формируйте элемент управления и запустите ActiveX Control Test Container снова. На сей раз просмотрите окно регистрации событий. Чтобы направлять события в окно вывода выберите Logging из меню Options и выберите Log to output window. Теперь вставьте элемент управления и пробуйте щелкать в окне. Обратите внимание, что ClickIn вызывается, если Вы нажимаете внутри заполненного многоугольника, а ClickOut вызывается когда Вы нажимаете вне его.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 16.09.2002