简体   繁体   中英

Hiding and showing container windows based on tab

I have created a tab control that contains two tabs. Inside each tab there will be a container window to hold other controls (in the code example, a static control for instance). The idea is that when a new tab is selected, it will hide/show the correct container window that holds a bunch of controls. However I am struggling to get the container windows holding the static controls to show. This is the code so far:

#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")

#define ID_TABCTRL 1
#define ID_STATIC0 2
#define ID_STATIC1 3
#define ID_TAB0 4
#define ID_TAB1 5

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND hTab, hTab0, hTab1;

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    MSG  msg;
    WNDCLASS wc = { 0 };
    wc.lpszClassName = TEXT("Tab control");
    wc.hInstance = hInstance;
    wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursor(0, IDC_ARROW);

    RegisterClass(&wc);
    CreateWindow(wc.lpszClassName, TEXT("Tab control"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 200, 0, 0, hInstance, 0);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    TCITEM tie;
    INITCOMMONCONTROLSEX icex;

    switch (msg)
    {
        case WM_CREATE:
            icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
            icex.dwICC = ICC_TAB_CLASSES;
            InitCommonControlsEx(&icex);

            tie.mask = TCIF_TEXT;

            ///// Create Tab Control /////
            hTab = CreateWindow(WC_TABCONTROL, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 200, 150, hwnd, (HMENU)ID_TABCTRL, NULL, NULL);

            ///// Create Individual Tabs /////
            tie.pszText = TEXT("First");
            SendMessage(hTab, TCM_INSERTITEM, 0, (LPARAM)(LPTCITEM)&tie);

            tie.pszText = TEXT("Second");
            SendMessage(hTab, TCM_INSERTITEM, 1, (LPARAM)(LPTCITEM)&tie);

            ///// Create Container windows for each tab /////
            hTab0 = CreateWindow(0, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 200, 150, hTab, (HMENU)ID_TAB0, NULL, NULL);
            hTab1 = CreateWindow(0, NULL, WS_CHILD, 0, 0, 200, 150, hTab, (HMENU)ID_TAB1, NULL, NULL);

            ///// Add example control to one of the tab container windows /////
            CreateWindow(TEXT("Static"), TEXT("Yay!"), WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 30, 50, 25, hTab0, (HMENU)ID_STATIC0, NULL, NULL);
            CreateWindow(TEXT("Static"), TEXT("It appears to be working"), WS_CHILD | WS_VISIBLE | SS_LEFT, 20, 30, 100, 50, hTab1, (HMENU)ID_STATIC1, NULL, NULL);

            break;

        case WM_NOTIFY:
            switch (((LPNMHDR)lParam)->code)
            {
                case TCN_SELCHANGE:
                    switch (TabCtrl_GetCurSel(hTab))
                    {
                        ///// Show or Hide the appropriate tabs /////
                        case 0:
                            ShowWindow(hTab1, SW_HIDE);
                            ShowWindow(hTab0, SW_SHOW);
                        case 1:
                            ShowWindow(hTab0, SW_HIDE);
                            ShowWindow(hTab1, SW_SHOW);
                    }
            }
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;
    }
    return(DefWindowProc(hwnd, msg, wParam, lParam));
}

Is it just a case of the container windows hTab0 and hTab1 being stuck behind the tab window ( hTab )?

First, you need to change the position of the tab and static form, otherwise it will block the generated content.

Then you can define the generated static text directly through CreateWindow , by using WC_STATIC .

#include <Windows.h>
#include <commctrl.h>
LRESULT CALLBACK WndProc(HWND, UINT,WPARAM,LPARAM);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("windows");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc; 
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    { 
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    }
    hwnd = CreateWindow(szAppName,
        TEXT("the hello program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hwnd,iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessageW(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
    static HINSTANCE hInstance;
    static HWND hwndTab = 0 , hwndStatic1,hwndStatic2;
    TCITEM tie;
    RECT rcClient;
    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_TAB_CLASSES;
    TCHAR tabLBL1[256];
    GetClientRect(hwnd, &rcClient);
    switch (message)
    {
    case WM_CREATE:
    {
        hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
        hwndTab = CreateWindow(WC_TABCONTROL, L"",
            WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
            0, 0, rcClient.right, rcClient.bottom,
            hwnd, NULL, hInstance, NULL);

         //Add tabs for each day of the week. 
        tie.mask = TCIF_TEXT | TCIF_IMAGE;
        tie.iImage = -1;
        wsprintf(tabLBL1, L"tab1");
        tie.pszText = tabLBL1;
        TabCtrl_InsertItem(hwndTab, 0, &tie);
        wsprintf(tabLBL1, L"tab2");
        TabCtrl_InsertItem(hwndTab, 1, &tie);


        hwndStatic1 = CreateWindow(WC_STATIC, L"123",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            200, 200, 100, 100,        // Position and dimensions; example only.
            hwndTab, NULL, hInstance,    // g_hInst is the global instance handle
            NULL);
        hwndStatic2 = CreateWindow(WC_STATIC, L"456",
            WS_CHILD | WS_VISIBLE | WS_BORDER,
            400, 200, 100, 100,        // Position and dimensions; example only.
            hwndTab, NULL, hInstance,    // g_hInst is the global instance handle
            NULL);
        ShowWindow(hwndStatic1, TRUE);
        ShowWindow(hwndStatic2, FALSE);
        return 0;
    }

    case WM_DESTROY:        
        PostQuitMessage(0);
        return 0;
    case WM_NOTIFY:
        if (((LPNMHDR)lParam)->code == TCN_SELCHANGE)
        {
            int tabID = TabCtrl_GetCurSel(hwndTab);
            switch (tabID)
            {
            case 0:
                ShowWindow(hwndStatic1, TRUE);
                ShowWindow(hwndStatic2, FALSE);
                break;
            case 1:
                ShowWindow(hwndStatic1, FALSE);
                ShowWindow(hwndStatic2, TRUE);
                break;
            default:
                break;
            }
        }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

Zhu Song's answer helped solved the problem (the container windows needing to be a static control, and needing to be positioned inside the tab control's space, below the clickable tabs).

Here is the result, swapping the two container window creation lines:

hTab0 = CreateWindow(TEXT("Static"), NULL, WS_CHILD | WS_VISIBLE, 1, 25, 197, 123, hTab, (HMENU)ID_TAB0, NULL, NULL);
hTab1 = CreateWindow(TEXT("Static"), NULL, WS_CHILD, 1, 25, 197, 123, hTab, (HMENU)ID_TAB1, NULL, NULL);

Note how the container window sizes and position are small enough to just fit inside the main tab control window (you can add WS_BORDER to the style to see where exactly it fits).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM