Двойственные интерфейсы
Тестирование объекта
Вновь запустите приложение и убедитесь в том, что нам удалось слегка подкрасить объект. Теперь исследуем функциональность, которую получили бесплатно при оформлении заказа у мастера.
- Поместите курсор мыши внутрь рамки объекта, вызовите контекстное меню и дайте команду OpenGL Class Object. При этом появится диалоговое окно страниц свойств, состоящее из двух станиц (Property Pages).
- Сдвиньте окно диалога в сторону, чтобы оно не заслоняло внедренный объект. На первой странице диалога с заголовком Color выберите из списка другой цвет и нажмите кнопку Apply. Цвет должен измениться.
- В выпадающем списке Set of colours выберите строку System colours Windows и вновь попытайтесь изменить цвет объекта. На сей раз произойдет осечка.
Попробуем это исправить. Событие, заключающееся в том, что пользователь объекта изменил одно из его стандартных свойств, поддерживаемых страницами не менее стандартного диалога, будет обработано каркасом СОМ-сервера и при этом вызвана функция copenGL::OnFillColorChanged, код которой мы не трогали. Сейчас там есть только одна строка:
ATLTRACE(_T ("OnFillColorChanged\n"));
Которая в режиме отладки (F5) выводит в окно Debug Studio .NET текстовое сообщение. Внесите в тело этой функции изменения:
void OnFillColorChanged() { //====== Если выбран системный цвет, if (m_clrFillColor & 0x80000000) //====== то выбираем его по индексу m_clrFillColor=::GetSysColor(m_clrFillColor & Oxlf); ATLTRACE(_T("OnFillColorChanged\n")); }
Признаком выбора системного цвета является единица в старшем разряде m_clrFillColor. В этом случае цвет задан не тремя байтами (red, green, blue), a индексом в таблице системных цветов (см. справку по GetSysColor). Выделяя этот случай, мы выбираем системный цвет с помощью API-функции GetSysColor. Заодно подправим функцию перерисовки, чтобы убедиться, что объект нам подчиняется и мы умеем убирать лишний код:
HRESULT OnDraw(ATL_DRAWINFO& di) { //====== Не будем преобразовывать в RECT LPCRECTL р = di.prcBounds; //====== Цвет подложки текста ::SetBkColor(di.hdcDraw,m_clrFillColor); //====== Инвертируем цвет текста ::SetTextColor(di.hdcDraw, ~m_clrFillColor & Oxffffff); //====== Цвет фона ::SelectObject(di.hdcDraw, ::CreateSolidBrush(m_clrFillColor)); Rectangle(di.hdcDraw, p › left, p › top, p › right, p › bottom); SetTextAlign(di.hdcDraw, TA_CENTER | TA_BASELINE); LPCTSTR pszText = _T("ATL 4.0: OpenGL"); TextOut(di.hdcDraw, (p › left + p › right)/2, (p › top + p › bottom)/2, pszText, Istrlen(pszText) }; return S_OK; }
Запустите и убедитесь, что системные цвета выбираются корректно, а перерисовка при изменении размеров объекта не нарушает заданных границ. Некоторые проблемы возникают при инвертировании цвета фона, если он близок к нейтральному (128, 128, 128). В качестве упражнения решите эту проблему самостоятельно.