Часть полного текста документа:Реализация стиля Office XP ToolBarXP Недавно я пытался найти в сети ToolBar-элемент в стиле Office XP. Поиски мои не увенчались успехом - все элементы были либо сложны в встраивании в проект, либо платны. Тогда я принял отчаянные меры - написал сам... А, как оказалось, в написании тулбара не было оссобенных проблем. Вот как я сделал. Создал MFC SDI проект с именем StyleXP. С помощью ClassWizard'а добавил новый класс CToolBarXP, наследованный от CToolBar (CToolBar в списке нет, но я выбрал CToolBarCtrl и вручную изменил имя предка). Дальше встал вопрос: "Какие функции перегружать?". Просмотрев весь предоставленный список в ClassWizard'е, я выбрал WM_PAINT. Долго я с ним провозился, но таки вышло вот что: void CToolBarXP::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here CRect rt, rItem; COLORREF face, shdw, cbtn; BYTE r,g,b; WORD BtnLength; // Берём клиентскую область эл-та GetClientRect(rt); // Выщитываем цвет бэк-граунда(для пущей красоты // я решил слегка отклониться от стандартного цвета). face = GetSysColor(COLOR_3DFACE); r = GetRValue(face)+10; g = GetGValue(face)+10; b = GetBValue(face)+10; face = PALETTERGB(r,g,b); // Таким же образом выщитываем цвет выделенной кнопки... cbtn = GetSysColor(COLOR_3DFACE); r = GetRValue(cbtn)-10; g = GetGValue(cbtn)-10; b = GetBValue(cbtn)-10; cbtn = PALETTERGB(r,g,b); // и цвет рамки shdw = GetSysColor(COLOR_3DSHADOW); r = GetRValue(shdw)+10; g = GetGValue(shdw)+10; b = GetBValue(shdw)+10; shdw = PALETTERGB(r,g,b); // Заполняем тол-бар бэкграундом dc.FillSolidRect(rt, face); // Создаём перо CPen pen; pen.CreatePen(0, 1, shdw); dc.SelectObject(&pen); TBBUTTON btn; BtnLength = LOWORD(GetToolBarCtrl().GetButtonSize());// Получаем ширину кнопки // Перебираем все кнопки for(int i = 0, x = 0, n = 0; i != GetToolBarCtrl().GetButtonCount(); i++) { GetToolBarCtrl().GetButton(i, &btn);// Получаем данные о кнопке if(btn.fsStyle & TBSTYLE_SEP)// Сепаратор ? { dc.MoveTo(x+2, 2);// Рисуем вертикальную линию dc.LineTo(x+2, 20); x += 6; } if(m_nSelected == i)// На кнопке мышка? { // Создаём кисть и перо CPen pn; CBrush br; pn.CreatePen(0, 1, shdw); br.CreateSolidBrush(cbtn); dc.SelectObject(&pn); dc.SelectObject(&br); // Получаем рект кнопки GetItemRect(i, rItem); // Рисуем рамку dc.Rectangle(rItem); // Рисуем иконку кнопки GetToolBarCtrl().GetImageList()->Draw(&dc, n, CPoint(x+2, 2), 0); x += BtnLenght; n++; } else if(!btn.fsStyle & TBSTYLE_SEP)// Кнопка в обычном состоянии { GetToolBarCtrl().GetImageList()->Draw(&dc, n, CPoint(x+3, 3), 0); x += BtnLenght; n++; } } // Do not call CToolBarCtrl::OnPaint() for painting messages } Так, сразу пока не отвлёкся - в класс надо добавить переменную: class CToolBarXP : public CToolBarCtrl { //*********************************************** protected: int m_nSelected;// Номер кнопки под мышкой :-) //{{AFX_MSG(CToolBarXP) afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; В конструкторе класса надо надо инициализировать сию переменную числом -1. Теперь добавляем через КлассВизард обработку перемещений мышкой: void CToolBarXP::OnMouseMove(UINT nFlags, CPoint point) { CToolBar::OnMouseMove(nFlags, point); CRect rt; TBBUTTON btn; // Перебираем кнопки for(int i = 0; i != GetToolBarCtrl().GetButtonCount(); i++) { GetToolBarCtrl().GetButton(i, &btn);// Получаем данные о кнопке GetItemRect(i, rt);// Получаем рект кнопки if(btn.fsStyle & TBSTYLE_SEP) continue;// Сепараторы пропускаем if(rt.PtInRect(point) && m_nSelected != i)// Мышка над этой? { m_nSelected = i;// Сохраняем выделение Invalidate();// Перерисовываем SetTimer(11, 100, NULL);// Пускаем таймер return; } } } Так... ............ |