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

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

Редактирование заготовок реализации методов

Для реализации методов StartClock() и StopClock() введем внутреннюю ( private ) логическую переменную flagClock типа bool в класс CMyClockCtrl. Инициализируем ее в конструкторе класса значением true, чтобы часы после создания объекта-экземпляра элемента управления MyClock сразу шли. В функцию OnDraw() введем условие обновления выходного текста в зависимости от значения переменной flagClock. В реализациях методов StartClock() и StopClock() будем устанавливать соответствующее значение флага.

  • Откройте файл MyClockCtrl.h и добавьте в конец объявления класса CMyClockCtrl код
    Добавление флага остановки часов в класс CMyClockCtrl
    class CMyClockCtrl : public COleControl
    {
    .........................................................
    private:
      // Переменная-член текущей даты
      CString m_strDate;
      // Переменная-член текущего времени
      CString m_strTime;
      // Заполняет переменную-член  m_strDate текущей датой
      void GetCurDate(void);
      // Заполняет переменную m_strTime текущим временем
      void GetCurTime(void);
      CString m_str;
    public:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnTimer(UINT nIDEvent);
      afx_msg void OnDestroy();
    protected:
      void OnUpdateIntervalChanged(void);
      LONG m_UpdateInterval;
    
      void NewMinute(void)
      {
        FireEvent(eventidNewMinute, EVENT_PARAM(VTS_NONE));
      }
      void StartClock(void);
      void StopClock(void);
      void BeepClock(BYTE beep);
    private:
      bool flagClock;
    };
  • Откройте файл MyClockCtrl.cpp и добавьте в конструктор класса CMyClockCtrl код
    Добавление кода инициализации флага остановки часов в конструкторе класса CMyClockCtrl
    CMyClockCtrl::CMyClockCtrl()
    {
      InitializeIIDs(&IID_DMyClock, &IID_DMyClockEvents);
      // TODO: Initialize your control's instance data here.
      
      // Установить начальные размеры
      SetInitialSize(300, 15);
      // Установить начальный ход часов
      flagClock = true;
    }
  • В функцию OnDraw() класса CMyClockCtrl добавьте условие перерисовки времени
    Добавление кода в функцию OnDraw() класса CMyClockCtrl
    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);
      
      // Получить и вывести текст текущей даты и времени
      if(flagClock){ // Заморозить время
        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();
    }
  • Отредактируйте реализации методов StartClock() и StopClock() в файле MyClockCtrl.cpp так
    Реализации методов StartClock() и StopClock()
    void CMyClockCtrl::StartClock(void)
    {
      AFX_MANAGE_STATE(AfxGetStaticModuleState());
      
      // TODO: Add your dispatch handler code here
      flagClock = true; // Запустить часы
    }
      
    void CMyClockCtrl::StopClock(void)
    {
      AFX_MANAGE_STATE(AfxGetStaticModuleState());
      
      // TODO: Add your dispatch handler code here
      flagClock = false; // Остановить часы
    }
  • Проверьте работу методов на тестовой утилите ActiveX Control Test Container

    Теперь осталось реализовать добавленный пользовательский метод BeepClock(). Для простоты построим его таким же образом, что и реализацию предыдущих методов, только флаг введем с именем flagBeep. Функция просто будет устанавливать или сбрасывать флаг, а подачу звукового сигнала организуем в функции-обработчике NewMinute. Таким образом, при включенном методом BeepClock() флаге flagBeep в начале каждой минуты компьютер будет выдавать звуковой сигнал.

  • Откройте файл MyClockCtrl.h и добавьте в конец объявления класса CMyClockCtrl код
    Добавление флага flagBeep в класс CMyClockCtrl
    class CMyClockCtrl : public COleControl
    {
    .........................................................
    private:
      bool flagClock;
      bool flagBeep;
    };
  • Откройте файл MyClockCtrl.cpp и добавьте в конструктор класса CMyClockCtrl код
    Добавление кода инициализации флага flagBeep в конструкторе класса CMyClockCtrl
    CMyClockCtrl::CMyClockCtrl()
    {
      InitializeIIDs(&IID_DMyClock, &IID_DMyClockEvents);
      // TODO: Initialize your control's instance data here.
      
      // Установить начальные размеры
      SetInitialSize(300, 15);
      // Установить начальный ход часов
      flagClock = true;
      flagBeep = false;
    }
  • В функцию NewMinute() файла MyClockCtrl.h добавьте условие подачи сигнала
    Добавление кода в функцию NewMinute() класса CMyClockCtrl
    class CMyClockCtrl : public COleControl
    {
    ...........................................
      void NewMinute(void)
      {
        FireEvent(eventidNewMinute, EVENT_PARAM(VTS_NONE));
        if(flagBeep)
          MessageBeep((WORD) - 1);
      }
      void StartClock(void);
      void StopClock(void);
      void BeepClock(BYTE beep);
    private:
      bool flagClock;
      bool flagBeep;
    };
  • Отредактируйте реализации метода BeepClock() в файле MyClockCtrl.cpp так
    Реализации метода BeepClock()
    void CMyClockCtrl::BeepClock(BYTE beep)
    {
      AFX_MANAGE_STATE(AfxGetStaticModuleState());
      
      // TODO: Add your dispatch handler code here
      flagBeep = beep ? true : false;
    }
  • Проверьте работу метода на тестовой утилите ActiveX Control Test Container

Изменение системного имени компонента и включение его в панель Toolbox оболочки

При создании заготовки проекта элемента управления оболочка автоматически присвоила ему имя MyClock Control. Изменим это имя на Часы.

  • Откройте тестовую утилиту и командой меню File/Register Controls..., вызовите окно регистрации

  • Найдите элемент MyClock Control и снимите его с регистрации в системе, выполнив кнопку Unregister
  • Откройте ресурс String Table в панели Resource View оболочки проекта
  • Найдите идентификатор IDS_MYCLOCK и измените его значение с MyClock Control на новое значение Часы
  • Постройте проект и через тестовую утилиту вновь зарегистрируйте его в системе под новым название Часы. Проверьте через команду утилиты Edit/Insert New Control..., что элемент в системе зарегистрирован

Теперь подключим наш элемент к оболочке VS.NET 2003.

  • Откройте ресурс диалогового окна IDD_PROPPAGE_MYCLOCK или IDD_ABOUTBOX_MYCLOCK, чтобы активизировать панель Toolbox оболочки
  • Раскройте одну из вкладок панели Toolbox, например, General (можно открыть и Dialog Editor, но для пробы General практически пустая)
  • Щелкните на ней правой кнопкой мыши и из контекстного меню выберите команду Add/Remove Items...
  • В появившемся диалоговом окне установите вкладку COM Components и отметьте наш компонент часы

  • После щелчка по кнопке OK компонент часы появится во вкладке General панели Toolbox оболочки

Перейдите к разработке тестового приложения, где будет использован наш компонент Часы.

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