Owner-Drawn Tabs

Windows allows TabControl and PageControl tabs to be owner-drawn, just like items in a ComboBox or ListBox.  You first need to set the tab control style to TCS_OWNERDRAWFIXED, then implement a WM_DRAWITEM message handler.  Like all API owner-drawn window controls, the DRAWITEMSTRUCT is sent (Msg.LParam) with useful information including device context to draw on, bounding rectangle, and tab index.  In Builder 4, this is encapsulated, and you can simply use the OnDrawTab event.

KEYWORDS: TCS_OWNERDRAWFIXED, WM_DRAWITEM, DRAWITEMSTRUCT
 



 

//in header...
//---------------------------------------------------------------------------

    void __fastcall WMDrawItem(TMessage &Msg);

BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_DRAWITEM, TMessage, WMDrawItem)
END_MESSAGE_MAP(TForm)
 

 


 
 

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TabControl1->TabWidth = 75;
    TabControl1->TabHeight = 25;

    DWORD dwStyle = GetWindowLong(TabControl1->Handle, GWL_STYLE);
    SetWindowLong(TabControl1->Handle, GWL_STYLE,
                  dwStyle | TCS_OWNERDRAWFIXED);
}

// This is the function that the WM_DRAWITEM
// message maps to. The LParam member is in the
// form of a DRAWITEMSTRUCT structure.  This is
// where you change the color of the Tabs
void __fastcall TForm1::WMDrawItem(TMessage &Msg)
{
    LPDRAWITEMSTRUCT lpdis = (DRAWITEMSTRUCT *)Msg.LParam;

   /* the WM_DRAWITEM may be shared (for example, BitBtns) */
    /* handle the drawing if the message corresponds */
    /* the target ListView */
   if (lpdis->hwndItem != TabControl1->Handle)
    {
        TForm::Dispatch(&Msg);
       return;
    }

   // index of tab being drawn
   int Index = lpdis->itemID;

   // device context to draw on
    HDC HTabDC = lpdis->hDC;

   // bounding rectangle of current tab
    RECT TabRect = lpdis->rcItem;

    HFONT HPrevFont = SelectObject(HTabDC, TabControl1->Font->Handle);

   // fill the rectangle with the Form's brush (color)
    ::FillRect(HTabDC, &TabRect, Brush->Handle);

   int PrevMode = SetBkMode(HTabDC, TRANSPARENT);

    ::DrawText(HTabDC,
               TabControl1->Tabs->Strings[Index].c_str(),
               TabControl1->Tabs->Strings[Index].Length(),
               &TabRect,
               DT_CENTER | DT_VCENTER | DT_SINGLELINE);

    SetBkMode(HTabDC, PrevMode);
    SelectObject(HTabDC, HPrevFont);
    Msg.Result = true;

}