Реалізація стилю Office XP h2>
ToolBarXP h2>
Нещодавно я намагався знайти в мережі ToolBar-елемент в стилі
Office XP. Пошуки мої не увінчалися успіхом - всі елементи були або складні у
вбудовуванні в проект, або платні. Тоді я прийняв відчайдушних заходів - написав
сам ... А, як виявилося, у написанні тулбара не було оссобенних проблем. Ось
як я зробив. p>
Створив MFC SDI проект з ім'ям StyleXP. За допомогою
ClassWizard'а додав новий клас CToolBarXP, успадкованих від CToolBar (CToolBar
в списку немає, але я вибрав CToolBarCtrl і вручну змінив ім'я предка). Далі
постало питання: "Які функції перевантажувати?". Переглянувши весь
наданий список у ClassWizard'е, я вибрав WM_PAINT. Довго я з ним
провозився, але таки вийшло ось що: p>
void
CToolBarXP:: OnPaint () p>
( p>
CPaintDC dc (this);// device context for
painting p>
// TODO: Add your message handler code here p>
CRect rt, rItem; p>
COLORREF face, shdw, cbtn; p>
BYTE r, g, b; p>
WORD BtnLength; p>
// Беремо
клієнтську область ел-та p>
GetClientRect (rt); p>
// Вищітиваем
колір бек-Граунд (для більшої краси p>
// я вирішив
злегка відхилитися від стандартного кольору). p>
face =
GetSysColor (COLOR_3DFACE); p>
r = GetRValue (face) +10; p>
g = GetGValue (face) +10; p>
b = GetBValue (face) +10; p>
face = PALETTERGB (r, g, b); p>
// Таким
же чином вищітиваем колір виділеної кнопки ... p>
cbtn =
GetSysColor (COLOR_3DFACE); p>
r = GetRValue (cbtn) -10; p>
g = GetGValue (cbtn) -10; p>
b = GetBValue (cbtn) -10; p>
cbtn = PALETTERGB (r, g, b); p>
// і колір рамки p>
shdw = GetSysColor (COLOR_3DSHADOW); p>
r = GetRValue (shdw) +10; p>
g = GetGValue (shdw) +10; p>
b = GetBValue (shdw) +10; p>
shdw = PALETTERGB (r, g, b); p>
// Заповнюємо тол-бар бекграунд p>
dc.FillSolidRect (rt, face); p>
// Створюємо перо p>
CPen pen; p>
pen.CreatePen (0, 1, shdw); p>
dc.SelectObject (& pen); p>
TBBUTTON btn; p>
BtnLength =
LOWORD (GetToolBarCtrl (). GetButtonSize ());// Отримуємо ширину кнопки p>
// перебирати всі кнопки p>
for (int i = 0, x = 0, n = 0; i! =
GetToolBarCtrl (). GetButtonCount (); i ++) p>
( p>
GetToolBarCtrl (). GetButton (i, & btn);//
Отримуємо дані про кнопку p>
if (btn.fsStyle & TBSTYLE_SEP)// Сепаратор? p>
( p>
dc.MoveTo (x 2,
2);// Малюємо вертикальну лінію p>
dc.LineTo (x 2, 20); p>
x + = 6; p>
) p>
if (m_nSelected == i)// На кнопці мишка? p>
( p>
//
Створюємо пензель і перо p>
CPen
pn; p>
CBrush br; p>
pn.CreatePen (0, 1, shdw); p>
br.CreateSolidBrush (cbtn); p>
dc.SelectObject (& pn); p>
dc.SelectObject (& br); p>
//
Отримуємо ректи кнопки p>
GetItemRect (i,
rItem); p>
// Малюємо рамку p>
dc.Rectangle (rItem); p>
// Малюємо іконку кнопки p>
GetToolBarCtrl (). GetImageList () -> Draw (& dc, n, CPoint (x 2, 2), 0); p>
x + = BtnLenght; p>
n ++; p>
) p>
else if (! btn.fsStyle & TBSTYLE_SEP)// Кнопка в звичайному стані p>
( p>
GetToolBarCtrl (). GetImageList () -> Draw (& dc, n, CPoint (x 3, 3), 0); p>
x + = BtnLenght; p>
n ++; p>
) p>
) p>
// Do not call CToolBarCtrl:: OnPaint () for
painting messages p>
) p>
Так, відразу поки не забув - до класу треба додати
змінну: p>
class CToolBarXP:
public CToolBarCtrl p>
( p>
//********************************************* ** p>
protected: p>
int
m_nSelected;// Номер кнопки під пахвою :-) p>
// ((AFX_MSG (CToolBarXP) p>
afx_msg void OnPaint (); p>
//)) AFX_MSG p>
DECLARE_MESSAGE_MAP () p>
); p>
У конструкторі класу треба треба ініціалізувати оцю
змінну числом -1. p>
Тепер додаємо через КлассВізард обробку
переміщень мишкою: p>
void
CToolBarXP:: OnMouseMove (UINT nFlags, CPoint point) p>
( p>
CToolBar:: OnMouseMove (nFlags, point); p>
CRect rt; p>
TBBUTTON btn; p>
// перебираємо кнопки p>
for (int i = 0; i! =
GetToolBarCtrl (). GetButtonCount (); i ++) p>
( p>
GetToolBarCtrl (). GetButton (i, & btn);//
Отримуємо дані про кнопку p>
GetItemRect (i,
rt);// Отримуємо ректи кнопки p>
if (btn.fsStyle
& TBSTYLE_SEP) continue;// Сепаратори пропускаємо p>
if (rt.PtInRect (point)
& & M_nSelected! = I)// Мишка над цією? P>
( p>
m_nSelected = i;// Зберігаємо виділення p>
Invalidate ();// перемальовує p>
SetTimer (11, 100, NULL);// Пускаємо таймер p>
return; p>
) p>
) p>
) p>
Так ... Ну і, власне таймер: p>
void
CToolBarXP:: OnTimer (UINT nIDEvent) p>
( p>
if (nIDEvent ==
11)// Про всяк пожежний p>
( p>
// Так де
ж мишка ??? p>
CPoint
p (GetMessagePos ()); p>
ScreenToClient (& p); p>
// Беремо кордону кнопки p>
CRect rect; p>
GetClientRect (rect); p>
// Перевірка
на наявність усередині курсору p>
if
(! rect.PtInRect (p)) p>
( p>
// Якщо
миші немає то залишаємо спостереження p>
m_nSelected
= -1; P>
// И
вбиваємо таймер ( "А навіщо нам коваль? Нам коваль не потрібен ...");) p>
KillTimer (11); p>
// Не
забути перемалювати кнопку p>
Invalidate (); p>
) p>
) p>
) p>
Фу ... Начебто все. А! Тепер ліземо в MainFrame.h і
міняємо тип змінної m_wndToolBar з CToolBar на CToolBarXP, незабив перед цим
# include'ть файл з нашим панель інструментів. Тепер все! Тиснемо F7, чекаємо поки проект
скомпіліруется і F5. Спостерігаючи барвистий панель інструментів. P>
ReBarXP p>
Так, тулбар є. Далі - CReBarXP. Ну це взагалі
простіше пареної ріпи: створюємо MFC проект з позначкою галочкою Internet Explorer
ReBars. Додаємо нові клас CReBarXP, успадкованих від CReBar, перевантажує у
нього WM_PAINT і вписуємо туди ось що: p>
void
CReBarXP:: OnPaint () p>
( p>
CPaintDC dc (this);// device context for
painting p>
// TODO: Add your message handler code here p>
CRect rt, rBand; p>
COLORREF face, shdw; p>
BYTE r, g, b; p>
// Кольори (ідеінтічно CToolBarXP) p>
GetClientRect (rt); p>
face = GetSysColor (COLOR_3DFACE); p>
r = GetRValue (face) +10; p>
g = GetGValue (face) +10; p>
b = GetBValue (face) +10; p>
face = PALETTERGB (r, g, b); p>
shdw = GetSysColor (COLOR_3DSHADOW); p>
r = GetRValue (shdw) +10; p>
g = GetGValue (shdw) +10; p>
b = GetBValue (shdw) +10; p>
shdw = PALETTERGB (r, g, b); p>
CPen pen; p>
pen.CreatePen (0, 1, shdw); p>
//
Заливаємо область p>
dc.FillSolidRect (rt,
face); p>
dc.SelectObject (& pen); p>
// перебираємо
всі бари p>
for (UINT i = 0; i
! = GetReBarCtrl (). GetBandCount (); i ++) p>
( p>
GetReBarCtrl (). GetRect (i, rBand);// Отримуємо ректи p>
for (int y = 4; y! = rBand.Height () -4;
y + = 2)// Ресуем симпатичну зафарбовування p>
( p>
dc.MoveTo (rBand.left 3, rBand.top + y); p>
dc.LineTo (rBand.left 6, rBand.top + y); p>
) p>
) p>
// Do not call CReBar:: OnPaint () for painting
messages p>
) p>
Все! Тепер тільки змінюємо тип ReBar на
CReBarXP (обов'язково вставивши перед оголошенням класу include-команду). P>
StatusBarXP p>
Так, так ... ToolBarXP і ReBarXP є. Тепер
StatusBar'ом займемося. Проект як створювати я писати не буду, відразу переходимо до
справі. p>
Додаємо новий клас CStatusBarXP, успадкованих від
CStatusBar. У ньому перевизначають OnPaint і Пішим тудива: p>
void CStatusBarXP:: OnPaint () p>
( p>
CPaintDC dc (this);// device context for
painting p>
CRect rt, rPane; p>
COLORREF face, shdw; p>
CString Text; p>
CFont * Font; p>
BYTE r, g, b; p>
//
Обчислюємо кольору (більша частина коду :)) p>
GetClientRect (rt); p>
face = GetSysColor (COLOR_3DFACE); p>
r = GetRValue (face) -10; p>
g = GetGValue (face) -10; p>
b = GetBValue (face) -10; p>
face = PALETTERGB (r, g, b); p>
shdw = GetSysColor (COLOR_3DSHADOW); p>
r = GetRValue (shdw) +10; p>
g = GetGValue (shdw) +10; p>
b = GetBValue (shdw) +10; p>
shdw = PALETTERGB (r, g, b); p>
CPen pen; p>
CBrush br; p>
pen.CreatePen (0, 1, shdw); p>
br.CreateSolidBrush (face); p>
Font = GetFont (); p>
dc.SelectObject (Font); p>
dc.FillSolidRect (rt, face); p>
dc.SelectObject (& pen); p>
dc.SelectObject (& br); p>
// А ось
безпосередньо малювання: p>
for (int i = 0;
i! = GetCount ();
i ++) p>
(//перебирати всі індикатори p>
GetStatusBarCtrl (). GetRect (i, rPane); p>
GetPaneText (i, Text);// Отримуємо текст p>
rPane.bottom--; p>
dc.Rectangle (rPane);//
Малюємо рамку p>
// І текст,
якщо треба: p>
if (GetPaneStyle (i))
dc.TextOut (rPane.left 3, rPane.top 1, Text); p>
rPane.top + = 1; p>
rPane.left + = 3; p>
rPane.right -= 1; p>
if (GetPaneStyle (i)) dc.DrawText (Text,
rPane, 0); p>
) p>
) p>
Усе! Тепер тільки змінюємо тип змінної з CStatusBar
на CStatusBarXP і дивимось. Вид, звичайно, до перших двох класів не дотягує,
але ... "зійде для сільської місцевості". p>
Красивого вам програмування! p>
Список літератури h2>
Для підготовки даної роботи були використані
матеріали з сайту http://www.realcoding.net/
p>