Creating a Tab Control

The example in this section creates a tab control and displays it in the client area of the application's main window. The application displays a third window (a static control) in the display area of the tab control. The parent window positions and sizes the tab control and static control when it processes the WM_SIZE message.

There are seven tabs, one for each day of the week. When the user selects a tab, the application displays the name of the corresponding day in the static control. The following global variables are used in this example.

// Global variables

HINSTANCE g_hinst; // handle of application instance

char g_achTemp[256]; // temporary buffer for strings

HWND g_hwndMain; // main application window

HWND g_hwndTab; // tab control

HWND g_hwndDisplay; // handle of static control in

// tab control's display area

The following function creates the tab control and adds a tab for each day of the week. The names of the days are defined as string resources, consecutively numbered starting with IDS_FIRSTDAY (defined in the application's header file). Both the parent window and the tab control must have the WS_CLIPSIBLINGS window style. The application's initialization function calls this function after creating the main window.

// DoCreateTabControl - creates a tab control, sized to fit the

// specified parent window's client area, and adds some tabs.

// Returns the handle of the tab control.

// hwndParent - parent window (the application's main window)

HWND WINAPI DoCreateTabControl(HWND hwndParent)

{

RECT rcClient;

HWND hwndTab;

TC_ITEM tie;

int i;

// Get the dimensions of the parent window's client area, and

// create a tab control child window of that size.

GetClientRect(hwndParent, &rcClient);

InitCommonControls();

hwndTab = CreateWindow(

WC_TABCONTROL, "",

WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,

0, 0, rcClient.right, rcClient.bottom,

hwndParent, NULL, g_hinst, NULL

);

if (hwndTab == NULL)

return NULL;

// Add tabs for each day of the week.

tie.mask = TCIF_TEXT | TCIF_IMAGE;

tie.iImage = -1;

tie.pszText = g_achTemp;

for (i = 0; i < 7; i++) {

LoadString(g_hinst, IDS_FIRSTDAY + i,

g_achTemp, sizeof(g_achTemp));

if (TabCtrl_InsertItem(hwndTab, i, &tie) == -1) {

DestroyWindow(hwndTab);

return NULL;

}

}

return hwndTab;

}

The following function creates the static control that occupies the tab control's display area. The application's initialization function calls this function after creating the main window and the tab control.

// DoCreateDisplayWindow - creates a child window (a static

// control) to occupy the tab control's display area.

// Returns the handle of the static control.

// hwndParent - parent window (the application's main window)

HWND WINAPI DoCreateDisplayWindow(HWND hwndParent)

{

HWND hwndStatic = CreateWindow("STATIC", "",

WS_CHILD | WS_VISIBLE | WS_BORDER,

0, 0, CW_USEDEFAULT, CW_USEDEFAULT,

hwndParent, NULL, g_hinst, NULL);

return hwndStatic;

}

Following are the relevant portions of the application's window procedure. The application processes the WM_SIZE message to position and size the tab control and the static control. To determine the appropriate position and size for the static control, this example sends the tab control a TCM_ADJUSTRECT message (by using the TabCtrl_AdjustRect macro).

When a tab is selected, the tab control sends a WM_NOTIFY message, specifying the TCN_SELCHANGE notification message. The application processes this notification message by setting the text of the static control.

// MainWindowProc - processes the message for the main window class.

// The return value depends on the message.

// hwnd - handle of the window

// uMsg - identifier for the message

// wParam - message-specific parameter

// lParam - message-specific parameter

LRESULT CALLBACK MainWindowProc(

HWND hwnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam

)

{

switch (uMsg) {

case WM_SIZE: {

HDWP hdwp;

RECT rc;

// Calculate the display rectangle, assuming the

// tab control is the size of the client area.

SetRect(&rc, 0, 0,

LOWORD(lParam), HIWORD(lParam));

TabCtrl_AdjustRect(g_hwndTab, FALSE, &rc);

// Size the tab control to fit the client area.

hdwp = BeginDeferWindowPos(2);

DeferWindowPos(hdwp, g_hwndTab, NULL, 0, 0,

LOWORD(lParam), HIWORD(lParam),

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.

DeferWindowPos(hdwp,

g_hwndDisplay, HWND_TOP, rc.left, rc.top,

rc.right - rc.left, rc.bottom - rc.top, 0

);

EndDeferWindowPos(hdwp);

}

break;

case WM_NOTIFY:

switch (HIWORD(wParam)) {

case 0:

.

. // menu command processing

.

case TCN_SELCHANGE: {

int iPage = TabCtrl_GetCurSel(g_hwndTab);

LoadString(g_hinst, IDS_FIRSTDAY + iPage,

g_achTemp, sizeof(g_achTemp));

SendMessage(g_hwndDisplay, WM_SETTEXT, 0

(LPARAM) g_achTemp);

}

break;

}

break;

.

. // additional message processing

.

default:

return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

return 0;

}

Software for developers
Delphi Components
.Net Components
Software for Android Developers
More information resources
MegaDetailed.Net
Unix Manual Pages
Delphi Examples