Windows Tab Control Example

When a tab control is activated by a user, a WM_NOTIFY message is sent to the parent window. TCN_SELCHANGE is sent after a new tab is selected and TCN_SELCHANGING is sent when a tab is about to change. The lParam contains a pointer to an NMHDR structure that contains the notification code and additional information.

To create a Tab control specify WC_TABCONTROL as the window class and register the class by specifying the ICC_TAB_CLASSES bit flag in the accompanying INITCOMMONCONTROLSEX structure.

//tab control demo
#include <windows.h>
#include <commctrl.h>
#include <wchar.h>
#pragma comment(lib, "comctl32.lib")
#define ID_TABCTRL 1
#define ID_EDIT 2
#define BTN_ADD 3
#define BTN_DEL 4
#define BTN_CLR 5
#define MAX_TAB_LEN 15
#define MAX_TEXT_LEN 15
#define WC_BUTTONW 17

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND hTab, hEdit;
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, 380, 230, 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)
{
NMHDR *lpTabselect;
TCITEM tbinfo;
TCHAR text[9];
LRESULT count, id;
INITCOMMONCONTROLSEX icex;

switch(msg) {

case WM_CREATE:
// load common control class ICC_TAB_CLASSES from the dynamic-link library (DLL).
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_TAB_CLASSES;
InitCommonControlsEx(&icex);
//create tab
hTab = CreateWindow(WC_TABCONTROL, NULL, WS_CHILD | WS_VISIBLE,10, 10, 200, 150, hwnd,(HMENU) ID_TABCTRL, NULL, NULL);

hEdit = CreateWindow(TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER,250, 20, 100, 25, hwnd, (HMENU) ID_EDIT, NULL, NULL);
SendMessage(hEdit, EM_SETLIMITTEXT, MAX_TAB_LEN, 0);
CreateWindow(TEXT("button"), TEXT("Add"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,250, 50, 100, 25, hwnd, (HMENU) BTN_ADD, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("Delete"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,250, 80, 100, 25, hwnd, (HMENU) BTN_DEL, NULL, NULL);
CreateWindow(TEXT("button"), TEXT("Clear"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,250, 110, 100, 25, hwnd, (HMENU) BTN_CLR, NULL, NULL);
break;

case WM_COMMAND:

switch(LOWORD(wParam))
{

case BTN_ADD:
GetWindowText(hEdit,text, MAX_TEXT_LEN);
if (lstrlen(text) != 0 )
{
tbinfo.mask = TCIF_TEXT;
tbinfo.pszText = text;
count = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
SendMessage(hTab, TCM_INSERTITEM, count, (LPARAM) (LPTCITEM) &tbinfo);
}
break;

case BTN_DEL:
id = SendMessageW(hTab, TCM_GETCURSEL, 0, 0);
if (id != -1)
{
SendMessageW(hTab, TCM_DELETEITEM, 0, id);
}
break;

case BTN_CLR:
SendMessageW(hTab, TCM_DELETEALLITEMS, 0, 0);
break;
}
break;
case WM_NOTIFY:
//detects change in data time control
lpTabselect = (LPNMHDR) lParam;
if (lpTabselect->code == TCN_SELCHANGE)
{
// Notifies a tab control's parent window that the currently selected tab has changed.
}
if (lpTabselect->code == TCN_SELCHANGING)
{
// Notifies a tab control's parent window that the currently selected tab is about to change
}
break;

case WM_DESTROY:

PostQuitMessage(0);
break;
}

return(DefWindowProc(hwnd, msg, wParam, lParam));
}