Lekcja
13 - Kurs Visual C++ by SLASH
Dziś przed
nami już 13 lekcja VC++ - mam nadzieję, że nie pechowa ! Zajmiemy się dziś
ListBox-ami czyli listami wyboru. Nie będę dużo ględził - od razu bierzemy
się do roboty:
Utwórz
nową aplikację - nazwij ją Lista. Przejdź do formy i ułóż na niej lisbox
(zaraz obok combo). Wygląda to na razie jak pusty biały prostokąt... no fakt -
ale zaraz to zapełnimy :). Zmień jeszcze identyfikator ListBox-a na IDC_LISTA
Stwórz
jeszcze przycisk - nadaj mu etykietę: Zapełnij. Teraz musimy stworzyć dla
listy zmienną - w tym celu otwórz ClassWizard-a i pod zakładką members
variables dodaj zmienną dla ListBox-a o nazwie m_ctlLista, ale zmień kategorię
z Value na Control ! Jest to bardzo ważne gdyż nasza lista nie zwraca jednego
wyniku który mógłby zostać zapisany do zmiennej - my go sam będziemy
musieli wydobyć podając odpowiednie parametry - a to już jest kategoria
kontrolna !
Teraz już
możemy dodać kod do przycisku:
CStringArray tablica;
tablica.SetSize(5);
tablica[0] = "SLASH";
tablica[1] = "PTiK";
tablica[2] = "Strona";
tablica[3] = "Serwis";
tablica[4] = "Kurs VC++";
for (int x=0; x<= tablica.GetUpperBound(); x++)
{
m_ctlLista.AddString(tablica[x]);
}
Mam nadzieję, że zauważyłeś dokąd będzie działała funkcja for. Zakończy
się jeśli wykona WSZYSTKIE elementy tablicy... Ważne jest to wszystkie - bo
jeśli byś zadeklarował tablicę 20 elementową to wszystkie nie nadpisane
zmienne mają wartość pustą, ale istnieją ! W powyższym przykładzie do
list dodane by zostały puste elementy co jest niedopuszczalne ! Ale jak się
przed tym chronić to w kolejnym programiku....
Skompiluj swój program - powinieneś zauważyć, że lista została
posortowana ! I wszystko ładniej wygląda.
UWAGA! Jeśli lista jest nie posortowana, oznacza to, że musisz zmienić właściwość
listy - w tym celu kliknij prawym klawisze myszki na listę z menu wybierz
properties - przejdź do zakładki styles i zaznacz sort.
Teraz jeszcze napiszę jak
wcisnąć jakiś string na inną pozycję. Pamiętaj, że pierwsza pozycja (podobnie jak w tablicach) ma wartość 0 - i tak
np:
m_ctlLista.InsertString(2,"Wspaniały");
spowoduje wpisanie słowa Wspaniały na 3 pozycję. trzecią bo pierwsza jest
0 - druga 1, trzecia 2, a czwarta to właśnie 3 !
Możemy sprawić aby program sam zaznaczył np. 3 pozycję :
m_ctlLista.SetCurSel(2);
a ilość elementów listy można sprawdzić tak:
int ilosc = m_ctlLista.GetCount( );
A teraz dowiemy się jak sprawdzić co zostało zaznaczone (kliknięte) - np.
chcemy aby wyświetliło nam się okienko z klikniętym na liście stringiem.
Jak się pewnie domyślasz musimy stworzyć nowe zdarzenie - program ma
zareagować wtedy, gdy klikniemy gdzieś na listę - a więc kliknij dwukrotnie
na niej - wyskoczy okienko - po lewej widzisz zdarzenia. Domyślnie jest
zaznaczone podwójne kliknięcie - my musimy znaleźć pojedyncze - no niestety
nie ma, ale za to jest zaznaczenie - i ot to chodzi - to jest LBN_SELCHANGE.
Zaznacz go więc i naciśnij Add and Edit. Teraz dopisz następujący kod:
CString zwrot;
int index;
index = m_ctlLista.GetCurSel(); //
Sprawdzenie która pozycja jest zaznaczona
m_ctlLista.GetText(index, zwrot); // Pobranie tekstu do
zmiennej zwrot z pozycji index
MessageBox(zwrot);
// No i wyświetlenie komunikatu
Skompiluj swój program, zapełnij listę i kliknij na jedną z pozycji. Jak
widzisz program działa jak potrzeba.
Ale listę będziemy wykorzystywać raczej do innych celów - będzie
reprezentant i opis. Czyli np. programik który w liście wyboru umieszcza
nazwisko osoby, a po kliknięciu na nim dostajemy inne informacje o jego osobie.
Napiszemy taki programik.
Musimy stworzyć nowy projekt - nazwijmy go Nazwiska - porozmieszczaj obiekty
jak na rysunku:
A oto ich właściwości:
Nazwa
obiektu
Identyfikator
Inne
opcje:
ListBox
IDC_LISTA
Sort: zaznaczone (powinno być zaznaczone domyślnie)
Static
IDC_STATIC
Caption: Imię
Static
IDC_IMIE
Caption: <brak>, Styles\ Sunken: Aktywne
Static
IDC_STATIC
Caption: Wiek
Static
IDC_WIEK
Caption: <brak>, Styles\ Sunken: Aktywne
Frames (Ramka)
IDC_STATIC
Caption: Nowe dane
Static
IDC_STATIC
Caption: Nazwisko
EditBox
IDC_NOWENAZWISKO
Static
IDC_STATIC
Caption: Imię
EditBox
IDC_NOWEIMIE
Static
IDC_STATIC
Caption: Wiek
EditBox
IDC_NOWYWIEK
Button (Przycisk)
IDC_DOPISZ
Caption: Dopisz
Teraz czeka nas żmudne dodawanie zmiennych... Tak więc otwieramy
ClassWizard-a i tworzymy takie zmienne:
ID Obiektu
Nazwa zmiennej
Kategoria
Typ
IDC_IMIE
m_imie
Value
CString
IDC_LISTA
m_ctlLista
Control
CListBox
IDC_NOWEIMIE
m_noweimie
Value
CString
IDC_NOWENAZWISKO
m_nowenazwisko
Value
CString
IDC_NOWYWIEK
m_nowywiek
Value
CString
IDC_WIEK
m_wiek
Value
CString
Powinno
Cię zastanowić to, że wiek będziemy podawać jako stringa a nie
liczbę. Otóż wiek nie posłuży nam do żadnych obliczeń, a jedynie
informacji - a takie informacje najlepiej jest zapisać jako string.
Jeśli wszystko gotowe powinniśmy jeszcze dodać kilka danych do list na
dobry początek - następne będziemy już dopisywać w programie...
Do trzymania
informacji będziemy wykorzystywać 3 tablice - nazwisko, imię i wiek. Jak
pewnie sądzisz dane powinny być dostępne zkażdego miejsca w aplikacji - a więc
będą one globalne. Czy pamiętasz jeszcze jak dodawaliśmy zmienne globalne do
projektu ? W obszarze roboczym przechodzimy do zakładki ClassView - rozwijamy
listę i klikamy prawym klawiszem myszki na CListaDlg - teraz wybieramy Add
member variable. Jako typ podajemy CStringArray, a jako nazwę tNazwisko.
Podobnie postępujemy z kolejnymi tablicami - wszystkie są typu CStringArray -
a nazwy to jeszcze tImie oraz tWiek.
Teraz w
OnInitDialog dopisujemy:
// TODO: Add extra initialization here
tWiek.SetSize(100);
tNazwisko.SetSize(100);
tImie.SetSize(100);
tNazwisko[0] = "Kowalski";
tImie[0] = "Jan";
tWiek[0] = "40";
tNazwisko[1] = "Kowalska";
tImie[1] = "Genowefa";
tWiek[1] = "45";
tNazwisko[2] = "Antczak";
tImie[2] = "Antek";
tWiek[2] = "12";
for (int x=0; x<= 100; x++)
{
if (tImie[x] = = "")
{
break;
}
else
{
m_ctlLista.SetItemData(m_ctlLista.AddString(tNazwisko[x]),x);
}
}
Na początku
ustalany jest rozmiar tablic - potem dodajemy do nich dane 3 osób. Następnie
wykonywana jest pętla - zauważ jak ona działa:
Najpierw sprawdzane jest czy dana wartość tablicy nie jest pusta co by oznaczało,
że przekroczyliśmy indeks z danymi - w tym przypadku wykonywana jest
instrukcja break;
Pamiętasz może ją ? Używaliśmy ją w wyrażeniu case - a służyła ona do
przerywania dalszych sprawdzeń. Tak naprawdę służy ona do wyjścia z funkcji
złożonych (bez if-a), czyli takiej po której nie dajemy średnika. A jaka
funkcja u nas nie ma średnika ? for ! I ta funkcja powoduje zatrzymanie pętli
- a w następstwie koniec dodawania danych do listy. W przeciwnym przypadku
wykonywana jest instrukcja:
m_ctlLista.SetItemData(m_ctlLista.AddString(tNazwisko[x]),x);
Jak może zauważysz są to dwie funkcje w jednej linii - SetItemData służy do
nadania specjalnego identyfikatora dzięki któremu będziemy mogli odnaleźć
nasz rekord po posortowaniu listy. Jeśli nasza lista nie sortowałaby się moglibyśmy
ominąć nadawanie identyfikatorów bo dany element zawsze byłby na tym samym
miejscu. A po posortowaniu wszystkie dane się wymieszają i nie moglibyśmy
sprawdzić jakiemu nazwisku przypada jaki wiek i imię.
A w środku funkcji SetItemData mamy jeszcze dodanie do listy obecnego elementu
co jest chyba zrozumiałe. Budowa funkcji SetItemData:
m_ctlLista.SetItemData(m_ctlLista.AddString("string"),
nowy_id);
Funkcja
for sprawia, że kolejne elementy dostają o 1 większy identyfikator.
Dobra -
skompiluj swój program i sprawdź czy dodane zostały te nazwiska. Jak na razie
kliknięcie na nich nic nie powoduje, ale zaraz się tym zajmiemy- musimy wywołać
zdarzenie zaznaczenie (robiliśmy to w poprzednim przykładzie) i dodajemy kod:
int id;
id = m_ctlLista.GetItemData(m_ctlLista.GetCurSel());
m_imie = tImie[id];
m_wiek = tWiek[id];
UpdateData(FALSE);
Tym razem
odczytujemy identyfikator zaznaczonego obiektu i odczytujemy w ten sposób
tablicę. Skompiluj swój program i zobacz czy wszystko działa jak trzeba.
Przynajmniej powinno !
Ale
oczywiście nie mamy jeszcze możliwości dopisania sobie własnych danych - a
więc do przycisku dodajemy następujący kod:
UpdateData(TRUE);
int kolejny_id;
if (m_nowenazwisko == "")
{
MessageBox("Wpisz nazwisko","Błąd",MB_ICONERROR);
goto koniec;
}
if (m_noweimie == "")
{
MessageBox("Wpisz imię","Błąd",MB_ICONERROR);
goto koniec;
}
kolejny_id = m_ctlLista.GetCount();
tNazwisko[kolejny_id] = m_nowenazwisko;
tImie[kolejny_id] = m_noweimie;
tWiek[kolejny_id] = m_nowywiek;
m_ctlLista.SetItemData(m_ctlLista.AddString(tNazwisko[kolejny_id]), kolejny_id);
m_nowenazwisko = "";
m_noweimie = "";
m_nowywiek = "";
UpdateData(FALSE);
koniec:
;
Ale tego
się zrobiło ! Ale nie przestraszyłeś się chyba ? :)
Na początku sprawdzamy czy zostało coś wpisane w pola Imię i Nazwisko.
Uruchom
teraz swój program i wszystko powinno działać jak trzeba. Twoim zadaniem
jest przeanalizować cały program krok po kroku, tak abyś wszystko zrozumiał.
Pamiętaj
! Jeśli masz jakikolwiek problem ze zrozumieniem tego kursu to napisz do mnie -
na każdego maila odpisuję chętnie. Także wszelkie opinie, zażalenia itp.
kieruj na mój adres - chcę wiedzieć czy ten kurs Wam się podoba czy też nie
Adres -
zanotowane.pldoc.pisz.plpdf.pisz.plteen-mushing.xlx.pl