Paint on a Tabcontrol
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Paint on a Tabcontrol

Hybrid View

  1. #1
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Paint on a Tabcontrol

    Hi,

    How to paint on a tabcontrol?
    I tried to take the window handle or the tab handle but none of them works.

    Code:
    #include <windows.h>
    #include <commctrl.h>
    #include <iostream>
    using namespace std;
    
    #include <gdiplus.h>
    using namespace Gdiplus;
    
    VOID OnPaint(HDC hdc)
    {
        Graphics graphics(hdc);
        Pen      pen(Color(255, 0, 0, 255));
        graphics.DrawLine(&pen, 20, 20, 150, 550);
    }
    
    char className[]="TabControl";
    HWND hTab;
    HINSTANCE hInst;
    
    LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
    {
        MSG messages;
        WNDCLASSEX wincl;
        hInst = hInstance;
    
        wincl.hInstance=hInstance;
        wincl.lpszClassName=className;
        wincl.lpfnWndProc=WindowProcedure;
        wincl.style=0;
        wincl.cbSize=sizeof(WNDCLASSEX);
        wincl.hIcon=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hCursor=LoadCursor(NULL,IDC_ARROW);
        wincl.lpszMenuName=NULL;
        wincl.cbClsExtra=0;
        wincl.cbWndExtra=0;
        wincl.hbrBackground=HBRUSH(COLOR_3DFACE+1);
    
        if(!RegisterClassEx(&wincl))return 0;
    
        HWND windowHandle=CreateWindow(className,"TabControl",
                                       WS_OVERLAPPEDWINDOW,
                                       200,325,480,320,
                                       NULL,NULL,hInstance,NULL);
        ShowWindow(windowHandle,SW_SHOW);
    
        while(GetMessage(&messages,NULL,0,0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        };
        return messages.wParam;
    }
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
        HDC hdc;
        PAINTSTRUCT ps;
        switch(message)
        {
        case WM_CREATE:
            INITCOMMONCONTROLSEX icce;
            icce.dwSize=sizeof(INITCOMMONCONTROLSEX);
            icce.dwICC=ICC_TAB_CLASSES;
            InitCommonControlsEx(&icce);
    
            hTab=CreateWindow(WC_TABCONTROL,"",
                                   WS_CHILD |WS_VISIBLE,
                                   6,0,474,320,
                                   hwnd,
                                   NULL,hInst,NULL);
            TCITEM tab1Data;
            tab1Data.mask=TCIF_TEXT;
            tab1Data.pszText="Tab1";
            TabCtrl_InsertItem(hTab,0,&tab1Data);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hTab, &ps);
            OnPaint(hdc);
            cout << "paint"<< endl;
            EndPaint(hTab, &ps);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd,message,wParam,lParam);
        };
        return 0;
    }

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,605

    Re: Paint on a Tabcontrol

    What exactly does not work?
    About Owner-Drawn Tabs you could read in MSDN
    Victor Nijegorodov

  3. #3
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Re: Paint on a Tabcontrol

    Thanks for the guidance.
    So as I understand I have to use WM_DRAWITEM and not WM_PAINT.
    I set up a DRAWITEMSTRUCT structure and try to paint in WM_DRAWITEM but it still won't work.

    Code:
    #include <windows.h>
    #include <commctrl.h>
    #include <iostream>
    using namespace std;
    #pragma comment(linker, "/subsystem:\"console\" /entry:\"WinMainCRTStartup\"")
    
    #include <gdiplus.h>
    using namespace Gdiplus;
    
    #define ID_TAB  113
    
    VOID OnPaint(HDC hdc)
    {
        Graphics graphics(hdc);
        Pen      pen(Color(255, 0, 0, 255));
        graphics.DrawLine(&pen, 20, 20, 150, 550);
    }
    
    char className[]="TabControl";
    HWND hTab;
    HINSTANCE hInst;
    // The struct that WM_DRAWITEM needs:
    static DRAWITEMSTRUCT * it;
    
    
    LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
    {
        MSG messages;
        WNDCLASSEX wincl;
        hInst = hInstance;
    
        wincl.hInstance=hInstance;
        wincl.lpszClassName=className;
        wincl.lpfnWndProc=WindowProcedure;
        wincl.style=0;
        wincl.cbSize=sizeof(WNDCLASSEX);
        wincl.hIcon=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hCursor=LoadCursor(NULL,IDC_ARROW);
        wincl.lpszMenuName=NULL;
        wincl.cbClsExtra=0;
        wincl.cbWndExtra=0;
        wincl.hbrBackground=HBRUSH(COLOR_3DFACE+1);
    
        if(!RegisterClassEx(&wincl))return 0;
    
        HWND windowHandle=CreateWindow(className,"TabControl",
                                       WS_OVERLAPPEDWINDOW,
                                       200,325,480,320,
                                       NULL,NULL,hInstance,NULL);
        ShowWindow(windowHandle,SW_SHOW);
    
        while(GetMessage(&messages,NULL,0,0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        };
        return messages.wParam;
    }
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
        HDC hdc;
        PAINTSTRUCT ps;
    
        switch(message)
        {
        case WM_CREATE:
            INITCOMMONCONTROLSEX icce;
            icce.dwSize=sizeof(INITCOMMONCONTROLSEX);
            icce.dwICC=ICC_TAB_CLASSES;
            InitCommonControlsEx(&icce);
    
            hTab=CreateWindow(WC_TABCONTROL,"",
                              WS_CHILD|WS_VISIBLE|TCS_OWNERDRAWFIXED,
                              6,0,474,320,
                              hwnd,
                              (HMENU)ID_TAB,hInst,NULL);
            TCITEM tab1Data;
            tab1Data.mask=TCIF_TEXT;
            tab1Data.pszText="Tab1";
            TabCtrl_InsertItem(hTab,0,&tab1Data);
    
            // DRAWITEMSTRUCT
            ZeroMemory(&it, sizeof(DRAWITEMSTRUCT));
            it->CtlType = ODT_TAB;
            it->CtlID = ID_TAB; 
            it->itemID = 0; // Item to be drawn
            it->itemAction = ODA_FOCUS|ODA_DRAWENTIRE; 
            it->itemState = ODS_FOCUS; // More flags > look at MSDN
            it->hwndItem = hTab; //GetDlgItem(hwnd, ID_TAB);
            it->hDC = GetDC(it->hwndItem);
            GetWindowRect(hTab, &it->rcItem); // Rectangle of your listbox
            it->itemData = 0; // If you want to associate some data with the item
    
            return 0;
        case WM_DRAWITEM:
            it = (DRAWITEMSTRUCT*) lParam;
            switch(it->CtlType == ODT_TAB)
            {
            case ID_TAB:
                OnPaint(it->hDC);
                ReleaseDC(hTab, it->hDC);
                break;
            default:
                break;
            }
            return TRUE;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd,message,wParam,lParam);
        };
        return 0;
    }
    Last edited by MasterDucky; November 26th, 2012 at 04:53 AM.

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,605

    Re: Paint on a Tabcontrol

    Define "won't work"
    BTW, what is the purpose of this code case WM_CREATE:
    Code:
           // DRAWITEMSTRUCT
            ZeroMemory(&it, sizeof(DRAWITEMSTRUCT));
            it.CtlType = ODT_TAB;
            it.CtlID = IDL_1; 
            it.itemID = 0; 
            it.itemAction = ODA_DRAWENTIRE; 
            it.itemState = ODS_FOCUS; //
            it.hwndItem = hTab;
            it.hDC = GetDC(it.hwndItem);
            GetWindowRect(hwnd, &it.rcItem); 
            it.itemData = 0;
    Note also that the variable it is not declared!
    Victor Nijegorodov

  5. #5
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Re: Paint on a Tabcontrol

    "Won't work" means that it won't paint, won't draw a line.

    I admit that I'm completely lost and I thought that you needed to declare this struct in order to paint on a tabcontrol.

    "it" is declared globally only I didn't pasted the right code, sorry for that. I updated it now.

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,605

    Re: Paint on a Tabcontrol

    I do NOT need to declare this struct. And you do not need it either! The DRAWITEMSTRUCT structure is already declared by Microfoft somether in Win32 SDK headers.

    Why and what do you want to paint on a tabcontrol?
    Can you use MFC framework or only raw Win32 APIs? If the latter then you should have better posted your question in C++ and WinAPI Forum.
    And in any case what you need is to search for some sample code used owner drawiing in tabcontrol.
    Victor Nijegorodov

  7. #7
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Re: Paint on a Tabcontrol

    I want to paint with GDI+ on it.
    Code:
        Graphics graphics(hdc);
        Pen      pen(Color(255, 0, 0, 255));
        graphics.DrawLine(&pen, 20, 20, 150, 550);
    I want to use only raw Win32 APIs and I couldn't find any examples of WinAPI only MFC.

    Can you move my thread to the C++ and WinAPI Forum or should I repost it?
    Last edited by MasterDucky; November 26th, 2012 at 07:59 AM.

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,605

    Re: Paint on a Tabcontrol

    No, I can't. Only moderators can.
    Try to ask some of them.

    As for an example - try to begin with HOWTO: Change the Background Color of a Tab Control
    Victor Nijegorodov

  9. #9
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Re: Paint on a Tabcontrol

    Thanks for the help.
    I tried to apply the code but I'm doing something wrong, the tabs won't even show up.

    Code:
    #include <windows.h>
    #include <commctrl.h>
    #include <iostream>
    using namespace std;
    #pragma comment(linker, "/subsystem:\"console\" /entry:\"WinMainCRTStartup\"")
    
    #include <gdiplus.h>
    using namespace Gdiplus;
    
    #define ID_TAB  113
    #define RED     RGB(255,0,0)
    #define YELLOW  RGB(255,255,0)
    #define MAGENTA RGB(255,0,255)
    #define WHITE   RGB(255,255,255)
    #define BLUE    RGB(0,0,255)
    
    char className[]="TabControl";
    HWND hTab;
    HINSTANCE hInst;
    
    static DRAWITEMSTRUCT * lpdis;
    
    
    LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
    {
        MSG messages;
        WNDCLASSEX wincl;
        hInst = hInstance;
    
        wincl.hInstance=hInstance;
        wincl.lpszClassName=className;
        wincl.lpfnWndProc=WindowProcedure;
        wincl.style=0;
        wincl.cbSize=sizeof(WNDCLASSEX);
        wincl.hIcon=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
        wincl.hCursor=LoadCursor(NULL,IDC_ARROW);
        wincl.lpszMenuName=NULL;
        wincl.cbClsExtra=0;
        wincl.cbWndExtra=0;
        wincl.hbrBackground=HBRUSH(COLOR_3DFACE+1);
    
        if(!RegisterClassEx(&wincl))return 0;
    
        HWND windowHandle=CreateWindow(className,"TabControl",
                                       WS_OVERLAPPEDWINDOW,
                                       200,325,480,320,
                                       NULL,NULL,hInstance,NULL);
        ShowWindow(windowHandle,SW_SHOW);
    
        while(GetMessage(&messages,NULL,0,0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        };
        return messages.wParam;
    }
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
        HDC hdc;
        PAINTSTRUCT ps;
        HBRUSH hbr;
        COLORREF bkColor;
        TCITEM tci;
    
        switch(message)
        {
        case WM_CREATE:
            INITCOMMONCONTROLSEX icce;
            icce.dwSize=sizeof(INITCOMMONCONTROLSEX);
            icce.dwICC=ICC_TAB_CLASSES;
            InitCommonControlsEx(&icce);
    
            hTab=CreateWindow(WC_TABCONTROL,"",
                              WS_CHILD|WS_VISIBLE|TCS_OWNERDRAWFIXED,
                              6,0,474,320,
                              hwnd,
                              (HMENU)ID_TAB,hInst,NULL);
    
            TCITEM Tab0;
            Tab0.mask=TCIF_TEXT;
            Tab0.pszText="Tab0";
            TabCtrl_InsertItem(hTab,0,&Tab0);
            TCITEM Tab1;
            Tab1.mask=TCIF_TEXT;
            Tab1.pszText="Tab1";
            TabCtrl_InsertItem(hTab,1,&Tab1);
            TCITEM Tab2;
            Tab2.mask=TCIF_TEXT;
            Tab2.pszText="Tab2";
            TabCtrl_InsertItem(hTab,2,&Tab2);
            TCITEM Tab3;
            Tab3.mask=TCIF_TEXT;
            Tab3.pszText="Tab3";
            TabCtrl_InsertItem(hTab,3,&Tab3);
            TCITEM Tab4;
            Tab4.mask=TCIF_TEXT;
            Tab4.pszText="Tab4";
            TabCtrl_InsertItem(hTab,4,&Tab4);
            return 0;
        case WM_DRAWITEM:
            lpdis = (LPDRAWITEMSTRUCT) lParam;
    
            if(hTab == lpdis->hwndItem)   // is this the tab control?
            {
                // which tab? first, second...fifth
                switch (lpdis->itemID)
                {
                case 0:
                    hbr = CreateSolidBrush (RGB(255,0,0)) ;
                    bkColor = RED;
                    break;
                case 1:
                    hbr = CreateSolidBrush (RGB(255,0,0)) ;
                    bkColor = YELLOW;
                    break;
                case 2:
                    hbr = CreateSolidBrush (RGB(255,0,0)) ;
                    bkColor = MAGENTA;
                    break;
                case 3:
                    hbr = CreateSolidBrush (RGB(255,0,0)) ;
                    bkColor = WHITE;
                    break;
                case 4:
                    hbr = CreateSolidBrush (RGB(255,0,255)) ;
                    bkColor = BLUE;
                    break;
                }
    
                tci.mask = TCIF_TEXT;
                tci.pszText = "Hello";
                tci.cchTextMax = 5;
    
                TabCtrl_GetItem(hTab, lpdis->itemID, &tci);
    
                FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
                SetBkColor(lpdis->hDC, bkColor);
    
                TextOut(lpdis->hDC,
                        lpdis->rcItem.left,
                        lpdis->rcItem.top,
                        tci.pszText,
                        lstrlen(tci.pszText));
            }
            return TRUE;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd,message,wParam,lParam);
        };
        return 0;
    }

  10. #10
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,605

    Re: Paint on a Tabcontrol

    Did you debug your code?
    What does
    Code:
    CreateWindow(WC_TABCONTROL,"",
                              WS_CHILD|WS_VISIBLE|TCS_OWNERDRAWFIXED,
                              6,0,474,320,
                              hwnd,
                              (HMENU)ID_TAB,hInst,NULL);
    return?
    What do all these
    Code:
    TabCtrl_InsertItem(hTab, i, &Tabi);
    return?
    Victor Nijegorodov

  11. #11
    Join Date
    Dec 2007
    Location
    France
    Posts
    271

    Re: Paint on a Tabcontrol

    They are ok, returning the indexes of the tabs.
    Actually it not only breaks out of the switch() but it breaks out of the WM_DRAWITEM and never goes to the rest of the code, that is the problem.

    Edit. The tabs won't get created because of the TCS_OWNERDRAWFIXED style. But I need this style to repaint the background.
    Last edited by MasterDucky; November 26th, 2012 at 12:20 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center