Стоит Windows 8 Pro, Visual Studio 2010 Express Edition . |
Создание собственного элемента управления ActiveX
Отображение текущего времени
Заменим нашу текстовую заглушку на строку, содержащую текущую дату и время. Подобную информацию мы уже получали в Lab6, поэтому повторим эти шаги
-
Добавьте объявление двух переменных m_strDate и m_strTime в объявление класса CMyClockCtrl файла MyClockCtrl.h для хранения текущих даты и времени. Выполните это без применения мастера - вручную
Изменение в файле MyClockCtrl.h class CMyClockCtrl : public COleControl { ............................................ private: // Переменная-член текущей даты CString m_strDate; // Переменная-член текущего времени CString m_strTime; };
- В панели Class View выделите класс CMyClockCtrl и через контекстное меню Add/Add Function вызовите мастер добавления функций. Настройте его так, как приведено на рисунке
- Вновь в панели Class View выделите класс CMyClockCtrl и через контекстное меню Add/Add Function вызовите мастер добавления функций. Настройте его так, как приведено на рисунке
-
Заготовку функции GetCurDate() в файле MyClockCtrl.cpp наполните следующим кодом
Функция GetCurDate() в файле MyClockCtrl.cpp // Заполняет переменную-член m_strDate текущей датой void CMyClockCtrl::GetCurDate(void) { // массив месяцев char *month[] = {"января" ,"февраля" ,"марта" ,"апреля" ,"мая" ,"июня" ,"июля" ,"августа" ,"сентября" ,"октября" ,"ноября" ,"декабря"}; // массив дней недели char *week[] = { "воскресенье" ,"понедельник" ,"вторник" ,"среда" ,"четверг" ,"пятница" ,"суббота" }; int m_day, m_month, m_week, m_year; // Получить текущее время CTime curTime = CTime::GetCurrentTime(); m_day = curTime.GetDay(); // Число месяца m_month = curTime.GetMonth(); // 1 - Январь m_week = curTime.GetDayOfWeek(); // 1 - Воскресенье m_year = curTime.GetYear(); // Год char tmp[5]; // Для размещения числа месяца, года и нуль-символа itoa(m_day, tmp, 10);// Преобразуем целое в строку в десятичном формате m_strDate = ""; // Заполнить пустой строкой m_strDate += tmp; m_strDate += " "; m_strDate += month[m_month - 1]; m_strDate += " ("; m_strDate += week[m_week - 1]; m_strDate += ") - "; itoa(m_year, tmp, 10); // Преобразуем число-год в строку-год m_strDate += tmp; m_strDate += " г."; }
-
Заготовку функции GetCurTime() в файле MyClockCtrl.cpp наполните следующим кодом
Функция GetCurTime() в файле MyClockCtrl.cpp // Заполняет переменную m_strTime текущим временем void CMyClockCtrl::GetCurTime(void) { // Получить текущее время CTime curTime = CTime::GetCurrentTime(); // Сохранить текущее время в нужном формате m_strTime = " "; // Два пробела m_strTime += curTime.Format("%H:%M:%S"); }
-
Добавьте объявление суммарной переменной m_str в объявление класса CMyClockCtrl файла MyClockCtrl.h для хранения текущих даты и времени. Выполните это без применения мастера - вручную
Изменение в файле MyClockCtrl.h class CMyClockCtrl : public COleControl { ............................................ // Переменная-член текущей даты CString m_strDate; // Переменная-член текущего времени CString m_strTime; // Заполняет переменную-член m_strDate текущей датой void GetCurDate(void); // Заполняет переменную m_strTime текущим временем void GetCurTime(void); CString m_str; };
-
Отредактируйте функцию 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. // Залить элемент управления pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); // pdc->Ellipse(rcBounds); // Построить эллипс // Получить и вывести текст текущей даты и времени 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); }
- Постройте проект и проверьте его в утилите ActiveX Control Test Container
Должен получиться такой результат
Вывод текущего времени в непрерывном режиме
Код вывода текстовой информации о текущей дате и времени обновляется только при разрушении окна. Поэтому нужно создать таймер с ежесекундным интервалом срабатывания и разместить код обновления вывода текста управляющего элемента в обработчик таймера. Поскольку дата в обозримый промежуток времени остается неизменной и нет смысла обновлять ее постоянно, ежесекундно вычисляя достаточно объемный код, поместим в обработчик только вызов функции обновления времени.
Чтобы однозначно определить таймер, ему нужно присвоить уникальный идентификатор. Для этого:
- Выделите в панели ресурсов Resource View узел MyClock.rc, затем либо через меню Edit оболочки, либо через контекстное меню узла выполните опцию Resource Symbols (символы резурсов)
- В диалоговом окне Resource Symbols щелкните на New (создать)
- В диалоговом окне New Symbol (создание символа) заполните поля как на рисунке
- Значение поля Value окна New Symbol можно изменить или оставить по умолчанию
Таймер необходимо установить сразу после создания элемента управления, так что нам нужно связать код, устанавливающий таймер, с событием WM_CREATE элемента управления.
- В панели Class View выделите класс CMyClockCtrl, а в панели Properties установите режим Messages
-
Создайте обработчик OnCreate(), который заполните так
Обработчик OnCreate() в файле MyClockCtrl.cpp int CMyClockCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here // Установить таймер SetTimer(ID_CLOCK_TIMER, 1000, NULL); return 0; }
Введенный код создает и запускает таймер с 1000-миллисекундным периодом срабатывания. Начиная с этого момента, каждую секунду Windows будет посылать нашему элементу управления сообщение WM_TIMER, которое мы и будем перехватывать и обрабатывать, обновляя строку времени.
- В панели Class View выделите класс CMyClockCtrl, а в панели Properties установите режим Messages
-
Найдите сообщение WM_TIMER, создайте для него обработчик, который заполните так
Обработчик OnTimer() в файле MyClockCtrl.cpp void CMyClockCtrl::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default // Переключить вызов на функцию OnDraw() InvalidateControl(); COleControl::OnTimer(nIDEvent); }
Предусмотрим остановку системного таймера при разрушении элемента управления.
- В панели Class View выделите класс CMyClockCtrl, а в панели Properties установите режим Messages
-
Найдите сообщение WM_DESTROY, создайте для него обработчик, который заполните так
Обработчик OnDestroy() в файле MyClockCtrl.cpp void CMyClockCtrl::OnDestroy() { COleControl::OnDestroy(); // TODO: Add your message handler code here // Остановить таймер KillTimer(ID_CLOCK_TIMER); }
- Постройте проект и проверьте его в утилите ActiveX Control Test Container. Время должно меняться ежесекундно
- Сохраните в своем каталоге сессию тестирования утилиты ActiveX Control Test Container под именем TestMyClock, чтобы при следующем тестировании можно было бы просто открыть нужную сессию, а не искать элемент управления MyClock