Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: 'Programmer'
Biblioteki C++

Zakładki (TabCtrl)

[lekcja]

Zakładki

Kiedy tworzymy "profesjonalny" program, używamy w nim nieskończonej liczby przycisków, pól tekstowych, itp. Jednak wiadomo, że każde okno ma swoje granice. Można oczywiście je rozszerzyć, albo dodać scrollbary. Jednak czasem po prostu lepszym rozwiązaniem jest użycie zakładek.

Oto są zakładki :) (Windows XP)
Oto są zakładki :) (Windows XP)
 

Tworzenie kontrolki

Stała oznaczająca kontrolkę pozwalającą utworzyć zakładki to WC_TABCONTROL. Przed jej użyciem należy oczywiście wywołać InitCommonControlsEx(). Przykład tworzenia kontrolki TAB:
C/C++
HWND hTab = CreateWindowEx( 0, WC_TABCONTROL, 0, WS_CHILD | WS_VISIBLE | TCS_FIXEDWIDTH,
0, 0, 544, 375, hwnd, 0, hInstance, NULL );
Stylu TCS_FIXEDWIDTH używamy po to, aby szerokość zakładek była stała.

Dodawanie zakładek

OK, kontrolka utworzona, ale co dalej? Pasowałoby dodać te zakładki, no nie? ;-) Aby dodać zakładkę, należy użyć... struktury (podziękowania kierować do Microsoftu ;-)). W tym wypadku jest to TCITEM. Oto jak jest zadeklarowana:
C/C++
typedef struct {
    UINT mask;
    #if (_WIN32_IE >= 0x0300)
    DWORD dwState;
    DWORD dwStateMask;
    #else
    UINT lpReserved1;
    UINT lpReserved2;
    #endif
    LPTSTR pszText;
    int cchTextMax;
    int iImage;
    LPARAM lParam;
} TCITEM, * LPTCITEM;
Tak naprawdę do poprawnego funkcjonowania zakładki wymagane są tylko trzy pola:
ArgumentZnaczenie
maskRóżne flagi. Najczęściej używane to TCIF_TEXT oraz TCIF_IMAGE (zgadnij, do czego służą ;-)).
pszTextTekst, który pojawi się na zakładce.
cchTextMaxDługość pola pszText.
Do dodawania zakładek używamy makra TabCtrl_InsertItem.

Składnia:
C/C++
int TabCtrl_InsertItem( HWND hwnd, int iItem, const LPTCITEM pitem );

ArgumentZnaczenie
hwndUchwyt do kontrolki TAB.
iItemIndeks nowej zakładki.
pitemWskaźnik do struktury TCITEM, którą właśnie wypełniliśmy.
Jeśli wstawianie zakładki powiedzie się, makro zwróci indeks właśnie utworzonej zakładki. Jeśli nie, zwróci -1. Oto przykład:
C/C++
#define ID_TAB_ZW 1
#define ID_TAB_ST 0

hTab = CreateWindowEx( 0, WC_TABCONTROL, 0, WS_CHILD | WS_VISIBLE | TCS_FIXEDWIDTH, 0, 0, 544, 375,
hwnd,( HMENU ) 10, hInstance, NULL );
TabCtrl_SetItemSize( hTab, 150, 20 );
TCITEM tci1, tci2;
tci1.mask = TCIF_TEXT;
tci2.mask = TCIF_TEXT;
tci1.pszText = "Zaawansowane";
tci2.pszText = "Standardowe";
tci1.cchTextMax = sizeof( "Zaawansowane" );
tci2.cchTextMax = sizeof( "Standardowe" );
TabCtrl_InsertItem( hTab, ID_TAB_ZW, & tci1 );
TabCtrl_InsertItem( hTab, ID_TAB_ST, & tci2 );
Tak dla wyjaśnienia: makro TabCtrl_SetItemSize służy do ustalania rozmiaru zakładek.

Jeśli dodatkowo chciałbyś na zakładkę wstawić obrazek, powinieneś użyć pola iImage. Możesz też zapoznać się z artykułem o » Kurs WinAPI, C++ » KontrolkiDrzewo (TreeView) lekcja.
Oto jak teraz wygląda nasz program:

Zakładki są, ale nic nie robią :/ (Windows XP)
Zakładki są, ale nic nie robią :/ (Windows XP)

Odróżnianie zakładek

Jeśli teraz umieścimy na kontrolce pole tekstowe i wpiszemy do niego tekst, to kiedy przełączymy na inną zakładkę, tekst po prostu zniknie. Nic dziwnego, zakładki są po to, aby na każdej z nich wyświetlać co innego. Musimy zatem nauczyć się odróżniać zakładki w komunikatach. Kontrolka TAB wysyła powiadomienia o zmianie zakładki w komunikacie WM_NOTIFY. Zakładka nie posiada uchwytu HWND, więc najczęściej stosowanym trikiem jest tworzenie osobno wszystkich kontrolek i na końcu wyłączenie tych, które nie są potrzebne na aktualnej zakładce, używając ShowWindow(hKontrolka, SW_HIDE). Oto jak określić aktualną zakładkę i włączyć odpowiednie kontrolki:
C/C++
case WM_NOTIFY:
LPNMHDR n;
n =( LPNMHDR ) lParam;
if( n->code == TCN_SELCHANGE && n->hwndFrom == hTab ) // Sprawdza, czy uchwyt pochodzi od hTab
{
    int index = TabCtrl_GetCurSel( hTab );
    switch( index ) // indeks aktualnej kontrolki
    {
    case ID_TAB_ST:
        ShowWindow( hEdit, SW_SHOW );
        ShowWindow( hRadioButton, SW_HIDE );
        break;
    case ID_TAB_ZW:
        ShowWindow( hEdit, SW_HIDE );
        ShowWindow( hRadioButton, SW_SHOW );
        break;
        //itd.
    }
}
break;
O ile do hEdit przypiszemy pole tekstowe, a do hRadioButton przycisk typu radio, to na zakładce Standardowe widoczne będzie tylko pole tekstowe, a na
zakładce Zaawansowane – przycisk radio.

Na zakładce Standardowe widoczne jest tylko pole tekstowe... (Windows XP)
Na zakładce Standardowe widoczne jest tylko pole tekstowe... (Windows XP)
 
...A na zakładce Zaawansowane widać tylko RadioButtona (Windows XP)
...A na zakładce Zaawansowane widać tylko RadioButtona (Windows XP)
 

Usuwanie zakładek

Aby usunąć wszystkie zakładki, można do kontrolki wysłać komunikat TCM_DELETEALLITEMS.

C/C++
SendMessage( hTab, TCM_DELETEALLITEMS, 0, 0 );
I to by było na tyle, jeśli chodzi o zakładki. Oczywiście są to tylko podstawy, ale jeśli ktoś uważnie przeczytał ten kurs, to z resztą powinien sobie już poradzić.
Poprzedni dokument Następny dokument
ProgressBar Różności