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

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

Придание функциональности добавленным свойствам

Напишем код, который делает свойства BackColor и ForeColor функциональными. Это позволит после задания новых значений свойствам сразу повлиять на элемент управления.

  • Откройте файл MyClockCtrl.cpp и найдите функцию OnDraw()
  • Отредактируйте ее, чтобы она приняла вид
    Функция OnDraw() в файле MyClockCtrl.cpp
    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);
    }
  • Установите начальные размеры элемента управления, добавив в конструктор класса CMyClockCtrl следующий код
    Добавления в конструктор CMyClockCtrl в файле MyClockCtrl.cpp
    CMyClockCtrl::CMyClockCtrl()
    {
      InitializeIIDs(&IID_DMyClock, &IID_DMyClockEvents);
      // TODO: Initialize your control's instance data here.
      
      // Установить начальные размеры
      SetInitialSize(300, 15);
    }
Включение специального свойства в элемент управления MyClock

Базовые свойства предусмотрены оболочкой при создании каркаса. Но во многих случаях может понадибиться включение своих собственных свойств в элемент управления, со своим названием и кодом, который делает свойство функционирующим. Эти свойства называются специальными ( Custom ). Включим в элемент управления MyClock дополнительное свойство с именем UpdateInterval, которое будем использовать для хранения чисел, устанавливающих период обновления таймера.

Добавление свойства UpdateInterval
  • Откройте панель Class View и раскройте узел MyClockLib

  • Через контекстное меню элемента _DMyClock выполните команду

  • Появится мастер, в котором установите переключатель в положение Member variable, а в поле Property name введите текст UpdateInterval. Установите поле Property type в значение LONG. Остальные поля при этом автоматически заполнятся и мастер должен выглядеть так

  • Нажмите кнопку Finish для завершения процесса. Убедитесь, что в панели Class View появилось новое свойство

Таким образом мы определили, что новое свойство будет иметь имя UpdateInterval и что это свойство будет использоваться для хранения чисел в переменной m_UpdateInterval типа long. В поле Notification function (функция уведомления) установлено имя обработчика OnUpdateIntervalChanged(), который будет срабатывать всякий раз, когда значение свойства UpdateInterval изменяется.

Инициализация свойства UpdateInterval

Необходимо инициализировать свойство UpdateInterval начальным значением. Для этого

  • Откройте файл MyClockCtrl.cpp и найдите функцию DoPropExchange()
  • Дополните код этой функции так
    Добавления кода в функцию DoPropExchange()
    void CMyClockCtrl::DoPropExchange(CPropExchange* pPX)
    {
      ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
      COleControl::DoPropExchange(pPX);
      
      // TODO: Call PX_ functions for each persistent custom property.
      
      // Инициализировать свойство UpdateInterval
      // значением 1000
      PX_Long(pPX, _T("UpdateInterval"), m_UpdateInterval, 1000);
    }

Для инициализации свойства UpdateInterval в приведенном коде используется функция PX_Long(), поскольку свойство имеет тип long. Для инициализации свойств других типов можно использовать другие PX -функции, например, PX_Bool(), PX_Short(), PX_String().

Придание функциональности свойству UpdateInterval

Свойство UpdateInterval должно устанавливать частоту срабатывания системного таймера. В настоящий момент это происходит каждые 1000 миллисекунд, поскольку мы установили ранее такой интервал в функции OnCreate() класса CMyClockCtrl. Сейчас нам нужно модифицировать код элемента управления так, чтобы он свое состояние каждые X миллисекунд, где X - текущее значение свойства UpdateInterval.

  • Откройте файл MyClockCtrl.cpp и найдите функцию OnUpdateIntervalChanged(), которую создал мастер при добавлении нового свойства
  • Введите следующий код в функцию OnUpdateIntervalChanged()
    Добавления кода в функцию OnUpdateIntervalChanged()
    void CMyClockCtrl::OnUpdateIntervalChanged(void)
    {
      AFX_MANAGE_STATE(AfxGetStaticModuleState());
      
      // TODO: Add your property handler code here
      
      // Заново установить таймер с периодом,
      // заданным значением свойства UpdateInterval
      SetTimer(ID_CLOCK_TIMER, (UINT)m_UpdateInterval, NULL);
      
      SetModifiedFlag();
    }

Оператор UINT - это переопределенный тип unsigned int. Он обеспечивает явное приведение типа long свойства к ожидаемому функцией SetTimer () значению.

  • Поскольку у нас появилось свойство, где при создании элемента управления хранится значение периода срабатывания таймера, то в код функции OnCreate() также внесите следующие коррективы
    Корректирование кода в функции OnCreate()
    int CMyClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
      if (COleControl::OnCreate(lpCreateStruct) == -1)
        return -1;
      
      // TODO:  Add your specialized creation code here
      
      // Установить таймер
      SetTimer(ID_CLOCK_TIMER, (UINT)m_UpdateInterval, NULL);
      
      return 0;
    }
Проверка допустимости значения свойства UpdateInterval

Напишем код, который защитит элемент управления от некорректного ввода значения в свойство UpdateInterval (например, отрицательного). Для этого скорректируем функцию OnUpdateIntervalChanged().

  • Откройте файл MyClockCtrl.cpp и найдите функцию OnUpdateIntervalChanged(), которую создал мастер при добавлении нового свойства и которую мы уже корректировали
  • Введите следующий код в функцию OnUpdateIntervalChanged()
    Повторное корректирование функции OnUpdateIntervalChanged()
    void CMyClockCtrl::OnUpdateIntervalChanged(void)
    {
      AFX_MANAGE_STATE(AfxGetStaticModuleState());
      
      // TODO: Add your property handler code here
      
      // Проверка того, что введенное пользователем
      // значение свойства неотрицательно
      if(m_UpdateInterval < 0){
        MessageBox("Недопустимое значение!!!"
                 "\nУстанавливаю 1000!!!");
        m_UpdateInterval = 1000;
      }
      
      // Заново установить таймер с периодом,
      // заданным значением свойства UpdateInterval
      SetTimer(ID_CLOCK_TIMER, (UINT)m_UpdateInterval, NULL);
      
      SetModifiedFlag();
    }
Александр Даниленко
Александр Даниленко
Стоит Windows 8 Pro, Visual Studio 2010 Express Edition .