На этом шаге мы рассмотрим переопределение функции OnDraw().
Созданные средствами MFC ActiveX ControlWizard элементы управления реализуют пользовательский интерфейс, а это означает, что большая часть созданного нами кода выполняет их отображение на экране. Как и в случае MFC-приложения архитектуры "документ/вид", весь графический код элемента управления находится в одной функции OnDraw(). Ниже показана ее реализация, сгенерированная ControlWizard:
void COneArmedBanditCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // TODO: Replace the following code with your own drawing code. pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds); }
Функция COleControl::OnDraw() получает указатель на MFC-объект контекста устройства и координаты (в логических единицах) прямоугольника, представляющего область, занимаемую элементом ynpaвления на экране. Избегайте фиксированных значений в коде графических элементов, кроме того, масштабируйте все элементы в соответствии с размерами ограничивающего прямоугольника. Таким образом, Вы будете уверены, что элемент управления виден полностью, а пропорции его внутренних элементов не искажены. В функцию OnDraw() также передается прямоугольник, задающий координаты недействительной области элемента управления, что позволит системе оптимизировать код вывода графических элементов.
Замените код в Вашем проекте таким текстом:
void COneArmedBanditCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // Получаем значения цветов стандартных свойств COLORREF colorBack = TranslateColor( GetBackColor() ); COLORREF colorFore = TranslateColor( GetForeColor() ); // Получаем сведения о размерах элемента управления float ctrlWidth = float( rcBounds.Width() ); float ctrlHeight = float( rcBounds.Height() ); // Настройка контекста устройства CBrush brush( colorBack ); CBrush * pOldBrush = pdc->SelectObject( &brush ); CPen pen( PS_SOLID, 3, colorFore ); CPen *pOldPen = pdc->SelectObject( &pen ); CFont SymbolFont; CFont *pOldFont; if( SymbolFont. CreateFont( long(ctrlHeight / 1.1), long(ctrlWidth/6), 0, 0, 0, 0, 0, 0, SYMBOL_CHARSET, 0, 0, 0, 0,"WingDings" ) ) pOldFont = pdc->SelectObject( &SymbolFont ); else pOldFont = SelectStockFont( pdc ); // Рисуем ограничивающий прямоугольник pdc->Rectangle( rcBounds ); pdc->SetBkMode( TRANSPARENT ); // Выводим текст pdc->SetTextColor( colorFore ); RECT rect; ::CopyRect( &rect, rcBounds ); CString strDisplay; strDisplay.Format( "%c %c %c", m_symbols[ 0 ], m_symbols[ 1 ], m_symbols[ 2 ] ); pdc->DrawText( strDisplay, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER ); // Делает видимыми вертикальные панели long onethird = long(ctrlWidth / 3); CPoint ptTop( rcBounds.TopLeft() ); CPoint ptBtm( rcBounds.left, rcBounds.bottom ); ptTop.x += onethird; ptBtm.x += onethird; pdc->MoveTo( ptTop ); pdc->LineTo( ptBtm ); ptTop.x += onethird; ptBtm.x += onethird; pdc->MoveTo( ptTop ); pdc->LineTo( ptBtm ); // Восстанавливаем контекст устройства pdc->SelectObject( pOldFont ); pdc->SelectObject( pOldPen ); pdc->SelectObject( pOldBrush ); }
Эта функция имитирует экран игрового автомата, отображая в трех окошках три символа из шрифта Wingdings. Сами символы содержатся в строке фиксированной длины m_symbols - переменной-члене класса COneArmedBanditCtrl. Она должна быть создана до начала компиляции.
TCHAR m_symbols[3];
_tcscpy(m_symbols, _T("JJJ"));
Текст приложения можно взять здесь (36,3 Кб).
На следующем шаге мы рассмотрим реализацию метода элемента управления.