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.
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:
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:
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:
Do dodawania zakładek używamy makra
TabCtrl_InsertItem.
Składnia:
int TabCtrl_InsertItem( HWND hwnd, int iItem, const LPTCITEM pitem );
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:
#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
Drzewo (TreeView).
Oto jak teraz wygląda nasz program:
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:
case WM_NOTIFY:
LPNMHDR n;
n =( LPNMHDR ) lParam;
if( n->code == TCN_SELCHANGE && n->hwndFrom == hTab )
{
int index = TabCtrl_GetCurSel( hTab );
switch( index )
{
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;
}
}
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.
Usuwanie zakładek
Aby usunąć wszystkie zakładki, można do kontrolki wysłać komunikat
TCM_DELETEALLITEMS.
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ć.