Опубликован: 17.08.2010 | Доступ: свободный | Студентов: 1000 / 59 | Оценка: 4.11 / 3.89 | Длительность: 29:38:00
Самостоятельная работа 18:

Создание собственного элемента управления ActiveX

Включение специального события

События, которые разрабатывает программист элемента управления (пользователь оболочки), называются пользовательскими ( Custom ) или специальными. Специальные события добавляют к элементу управления тогда, когда базовых событий не хватает.

На данном этапе мы включим в наш элемент управления MyClock специальное событие NewMinute (новая минута), а позже напишем для него обработчик.

  • В панели Class View выберите CMyClockCtrl
  • Щелкните на нем правой кнопкой мыши и выберите из контекстного меню пункты Add/Add Event

Появится мастер добавления событий

  • Заполните мастер, как показано на рисунке

  • Нажмите кнопку Finish и мастер добавит соответствующий код так, как это было при добавлении событий Click и DblClick

    Карта событий файла MyClockCtrl.cpp
    // Event map
      
    BEGIN_EVENT_MAP(CMyClockCtrl, COleControl)
      EVENT_STOCK_CLICK()
      EVENT_STOCK_DBLCLICK()
      EVENT_CUSTOM_ID("NewMinute", eventidNewMinute, NewMinute, VTS_NONE)
    END_EVENT_MAP()
    Объявление обработчиков событий файла MyClock.idl
    ....................................
      //  Event dispatch interface for CMyClockCtrl
      
      [ uuid(1E47AE17-F799-44FC-9C13-9E3DD23D5540),
        helpstring("Event interface for MyClock Control") ]
      dispinterface _DMyClockEvents
      {
        properties:
          //  Event interface has no properties
      
        methods:
        [id(DISPID_CLICK)] void Click(void);
        [id(DISPID_DBLCLICK)] void DblClick(void);
        [id(1)] void NewMinute(void);
      };
    ....................................

    Кроме того, в класс CMyClockCtrl была добавлена функция генерации события

    Функция NewMinute() генерации события в файле MyClockCtrl.h
    class CMyClockCtrl : public COleControl
    {
    ........................................................
      void NewMinute(void)
      {
        FireEvent(eventidNewMinute, EVENT_PARAM(VTS_NONE));
      }
    };
  • Постройте проект и проверьте в тестовой утилите ActiveX Control Test Container наличие добавленного события, как мы это делали раньше

    Результат будет таким


Как мы видим, в списке присутствуют все три события, которые мы добавляли в элемент управления.

Генерация события NewMinute

Когда мы включаем в элемент управления базовое событие, такое, например, как Click или DblClick, то оно уже содержит встроенный код, который генерирует это событие и делать дополнительно ничего не надо, чтобы оно происходило. Например, событие Click происходит автоматически каждый раз, когда выполняется щелчок на элементе управления.

Когда включается в элемент управления специальное событие, то нужно написать код, который генерирует это событие в ответ на выполнение некоторых условий, для регистрации возникновения которых событие собственно и создается. Этот код должен распознать, что условия возникновения события выполнены, после чего код должен обратиться к функции FireEvent() данного события, которая и сгенерирует само событие.

Функция FireEvent() нашего события NewMinute вызывается одноименной функцией NewMinute(). Таким образом, чтобы событие NewMinute произошло, нужно составить код, который должен зарегистрировать выполнение условий генерации этого события и вызвать функцию FireEvent() генерации события через функцию NewMinute().

Определим, что событие NewMinute должно происходить всякий раз, когда начинается отсчет каждой новой минуты системного таймера. Чтобы написать код, генерирующий событие NewMinute, выполните следующее

  • В панели Solution Explorer оболочки откройте файл MyClockCtrl.cpp нашего проекта
  • В файле MyClockCtrl.cpp через верхний раскрывающийся список найдите функцию OnDraw()
  • В конец функции OnDraw() вставьте следующий код
    Добавление генератора события NewMinute
    void CMyClockCtrl::OnDraw(
          CDC* pdc, 
          const CRect& rcBounds, 
          const CRect& rcInvalid)
    {
      if (!pdc)
        return;
      
      // TODO: Replace the following code with your own drawing code.
      
      // Задать цвет переднего плана (т.е. цвет текста)
      // согласно значения свойства ForeColor
       pdc->SetTextColor(TranslateColor(GetForeColor()));
      
      // Установить режим прозрачного фона
      pdc->SetBkMode(TRANSPARENT);
      
      // Создать кисть на основе значения свойства BackColor
       CBrush bkBrush(TranslateColor(GetBackColor()));
      
      // Залить элемент управления, используя значение BackColor
      pdc->FillRect(rcBounds, &bkBrush);
      
      // Получить и вывести текст текущей даты и времени
      GetCurDate();
      m_str = m_strDate;
      GetCurTime();
      m_str += m_strTime;
      pdc->ExtTextOut(rcBounds.left,
        rcBounds.top,
        ETO_CLIPPED,
        rcBounds,
        m_str,
        m_str.GetLength(),
        NULL);
      
      // Получить текущее время и сгенерировать событие NewMinute
      CTime curTime = CTime::GetCurrentTime();
      if(curTime.Format("%S") == CString("00"))
        NewMinute();
    }
  • Постройте проект и проверьте в тестовой утилите ActiveX Control Test Container, что элемент управления действительно генерирует событие NewMinute всякий раз, когда обнуляется количество секунд

Результат будет примерно таким


Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .