windows_programming_notes.nbk: Home | Index | Next Page: Using Buttons in a Window | Previous Page: User Code


 Using a tab control in a window

#Create the tab control (it's a window, like everything else):
    GetClientRect(hwnd, &client_rect);
    tab_control_handle = CreateWindow(
                    WC_TABCONTROL,
                    "",
                    WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
                    0, 0, client_rect.right, client_rect.bottom,
                    hwnd,
                    (HMENU)0x47,
                    instance_handle,
                    NULL);
                    
    if (tab_control_handle == NULL) {
        MessageBox(hwnd, "failed to create tab control", "main_window_on_create", 0);
        return 0;
    }

Create tabs:

    TCITEM tie;
    char text_work[256];
    
    tie.mask = TCIF_TEXT | TCIF_IMAGE;
    tie.iImage = -1;
    tie.pszText = text_work;

    strcpy(text_work, "Header");
    TabCtrl_InsertItem(tab_control_handle, 0, &tie);
    strcpy(text_work, "Inputs");
    TabCtrl_InsertItem(tab_control_handle, 1, &tie);
    strcpy(text_work, "Datapoints");
    TabCtrl_InsertItem(tab_control_handle, 2, &tie);
    strcpy(text_work, "Outputs");
    TabCtrl_InsertItem(tab_control_handle, 3, &tie);
    strcpy(text_work, "Parameters");
    TabCtrl_InsertItem(tab_control_handle, 4, &tie);
    strcpy(text_work, "RACL");
    TabCtrl_InsertItem(tab_control_handle, 5, &tie);

When the tab window's parent gets re-sized, you might want to do this:

int main_window_on_size(HWND hwnd, UINT size_type, int width, int height)
{
    RECT rect;
    SetRect(&rect, 0, 0, width, height); 
    TabCtrl_AdjustRect(tab_control_handle, FALSE, &rect); 
    
    HDWP hdwp= BeginDeferWindowPos(2);
    if (hdwp) hdwp = DeferWindowPos(hdwp, tab_control_handle, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER); 

    // Position and size the static control to fit the 
    // tab control's display area, and make sure the 
    // static control is in front of the tab control. 
    if (hdwp) hdwp = DeferWindowPos(hdwp, tw->get_handle(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); 
    if (hdwp) hdwp = DeferWindowPos(hdwp, inputs_window->get_handle(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); 
    if (hdwp) hdwp = DeferWindowPos(hdwp, datapoints_window->get_handle(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); 
    if (hdwp) hdwp = DeferWindowPos(hdwp, outputs_window->get_handle(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); 
    if (hdwp) hdwp = DeferWindowPos(hdwp, parameters_window->get_handle(), HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); 
    if (hdwp) hdwp = EndDeferWindowPos(hdwp); 
}

When tabs are selected, the parent window will get WM_NOTIFY messages. Cast the LPARAM to a LPNMHDR. If the hwndFrom member is the handle of the table control, this notification is from the tab control. In this case, the code member of the LPNMHDR is the notification from the tab control.

LPNMHDR     pnmh = (LPNMHDR) lparam;

if (pnmh->hwndFrom == tab_control_handle) {
    switch(pnmh->code){
    case TCN_SELCHANGING:
        which = TabCtrl_GetCurSel(tab_control_handle); 
        dbgprintf("TCN_SELCHANGING %d\n", which);
        return 0;
    case TCN_SELCHANGE:
        // this is the one we want
        which = TabCtrl_GetCurSel(tab_control_handle); 
        dbgprintf("TCN_SELCHANGE says %d\n", which);
        switch (which) {
        case 1:
            dbgprintf("change to input window\n");
            tw->show(SW_HIDE);
            inputs_window->show(SW_SHOW);
            datapoints_window->show(SW_HIDE);
            outputs_window->show(SW_HIDE);
            parameters_window->show(SW_HIDE);
            break;
        case 2:
            dbgprintf("change to datapoints window\n");
            tw->show(SW_HIDE);
            inputs_window->show(SW_HIDE);
            datapoints_window->show(SW_SHOW);
            outputs_window->show(SW_HIDE);
            parameters_window->show(SW_HIDE);
            break;
        case 3:
            dbgprintf("change to output window\n");
            tw->show(SW_HIDE);
            inputs_window->show(SW_HIDE);
            datapoints_window->show(SW_HIDE);
            outputs_window->show(SW_SHOW);
            parameters_window->show(SW_HIDE);
            break;
        case 4:
            dbgprintf("change to parameters window\n");
            tw->show(SW_HIDE);
            inputs_window->show(SW_HIDE);
            datapoints_window->show(SW_HIDE);
            outputs_window->show(SW_HIDE);
            parameters_window->show(SW_SHOW);
            break;
        default:
            dbgprintf("change to text window\n");
            inputs_window->show(SW_HIDE);
            outputs_window->show(SW_HIDE);
            tw->show(SW_SHOW);
        };
        return 0;
    case NM_CLICK:
        which = TabCtrl_GetCurSel(tab_control_handle); 
        dbgprintf("NM_CLICK %d\n", which);
        return 0;
    default:
        which = TabCtrl_GetCurSel(tab_control_handle); 
        dbgprintf("selected you %d\n", which);
        return 0;
    }
}

windows_programming_notes.nbk: Home | Index | Next Page: Using Buttons in a Window | Previous Page: User Code


Notebook exported on Monday, 7 July 2008, 18:56:50 PM Eastern Daylight Time