Как изменить цвета вкладки CTabCtrl?

Привет и с новым годом, (это приемлемо сказать до четверга)

Я пытаюсь изменить цвет вкладок в классе CTabCtrl. Я пытаюсь создать свой собственный ReskinCTablCtrl, чтобы я мог просто вызывать его в отдельных классах и легко использовать в своей программе.

В настоящее время я могу изменить цвет фона CTabCtrl, но не могу изменить сами вкладки.

я использовал ON_WM_ERASEBKGND() для покраски фона и все работало без проблем:

BOOL ReskinCTabCtrl::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
CBrush myBrush(RGB(51, 51, 51));    // dialog background color
BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
pDC->SetBkColor(RGB(51, 51, 51));
pDC->FillRect(&rect, &myBrush);
return bRes;
}

Однако я не смог изменить сами цвета вкладок. Они по-прежнему являются цветами MFC по умолчанию. Я пытался реализовать ON_WM_PAINT() а также ON_WM_DRAWITEM() без успеха. Я думаю, что могу добраться до конкретной вкладки с помощью OnDraw и DrawItem, аналогично второму примеру ссылки, который я опубликовал в конце этого вопроса.

void ReskinCTabCtrl::OnPaint() {

...

// paint the tabs first and then the borders
int nTab = GetItemCount();
int nSel = GetCurSel();

if (!nTab) // no pages added
return;

while (nTab--)
{
if (nTab != nSel)
{
dis.itemID = nTab;
dis.itemState = 0;

VERIFY(GetItemRect(nTab, &dis.rcItem));

dis.rcItem.bottom -= 2;
DrawItem(&dis);
DrawItemBorder(&dis);
}
}

...

}

Я был бы очень признателен, по крайней мере, за какое-то направление для решения этой проблемы, может быть, еще несколько примеров или какие методы я должен сосредоточиться на использовании. Мне не нужны вкладки разных цветов, может быть, есть простой способ сделать это?

Я пытался следовать некоторым примерам, таким как следующие ссылки, но я все еще не мог найти правильный способ сделать это.

https://support.microsoft.com/en-us/help/179909/how-to-change-the-background-color-of-a-tab-control

https://www.codeproject.com/Articles/1786/Ownerdraw-Tab-Controls-Borders-and-All

4

Решение

Включите OwnerDraw для управления вкладками, либо в редакторе ресурсов, либо установите TCS_OWNERDRAWFIXED в OnInitDialog

CTabCtrl имеет отражение сообщения для WM_DRAWITEM поэтому мы не хотим переопределять WM_DRAWITEM/OnDrawItem из родительского класса. Вместо этого переопределите в CTabCtrl::DrawItem(LPDRAWITEMSTRUCT),

К сожалению, результат довольно некрасивый. Это как переопределение DrawItem в кнопке.

Если визуальный стиль доступен и включен, вы можете переопределить CTabCtrl::OnPaint и нарисовать все вручную. Пример:

void CMyTabCtrl::OnPaint()
{
CPaintDC dc(this);

dc.SelectObject(GetFont());

CPen pen, pen_active;
COLORREF color_off = RGB(240, 240, 240);
COLORREF color_active = RGB(200, 240, 240);
CBrush brush_off, brush_active;
brush_off.CreateSolidBrush(color_off);
brush_active.CreateSolidBrush(color_active);
pen.CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
pen_active.CreatePen(PS_SOLID, 1, color_active);

CRect rcitem;
GetItemRect(0, &rcitem);

CRect rc;
GetClientRect(&rc);
rc.bottom = rcitem.bottom;
dc.FillSolidRect(&rc, GetSysColor(COLOR_3DFACE));

GetClientRect(&rc);
rc.top = rcitem.bottom - 1;
dc.SelectObject(&pen);
dc.SelectObject(&brush_active);
dc.Rectangle(&rc);

for(int i = 0; i < GetItemCount(); i++)
{
dc.SelectObject(&pen);
if(i == GetCurSel())
{
dc.SelectObject(&brush_active);
dc.SetBkColor(color_active);
}
else
{
dc.SelectObject(&brush_off);
dc.SetBkColor(color_off);
}

GetItemRect(i, &rcitem);
rcitem.right++;
dc.Rectangle(&rcitem);

if(i == GetCurSel())
{
dc.SelectObject(pen_active);
dc.MoveTo(rcitem.left+1, rcitem.bottom - 1);
dc.LineTo(rcitem.right, rcitem.bottom - 1);
}

TCITEM item = { 0 };
wchar_t buf[32];
item.pszText = buf;
item.cchTextMax = 32;
item.mask = TCIF_TEXT;
GetItem(i, &item);
dc.DrawText(buf, &rcitem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
}

BOOL CMyTabCtrl::OnEraseBkgnd(CDC*)
{
return TRUE;
}

введите описание изображения здесь

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]