Biblioteki klas i komponenty " biblioteka klas (ang. class library) zbiór klas implementujących wybrane elementy i operacje wykonywane w danym środowisku " popularne biblioteki klas przeznaczone dla Windows Object Windows Library (Borland), Microsoft Foundation Class Library, Visual Component Library (Borland), biblioteka .NET Framework Class Library (Microsoft) " implementują praktycznie wszystkie typowe elementy interfejsu użytkownika (okna zwykłe i dialogowe, przyciski, listy itd.), a także operacje wykonywane w systemie (np. operacje graficzne, drukowanie) " zasadnicza funkcja biblioteki: ukrycie przed programistą szczegółów implementacyjnych i wyposażenie go w gotowe klocki do budowy aplikacji (programista zwolniony z konieczności zajmowania się szczegółami operacji systemowych, może skupić się na realizowanej aplikacji) " podstawowa korzyść: uproszczenie kodu zródłowego programu (o wiele prościej niż w programie napisanym z użyciem wywołań funkcji WinAPI); " cechą dobrze zaprojektowanej biblioteki klas powinno być właściwe wykorzystanie możliwości programowania obiektowego (hermetyzacja, dziedziczenie...) Biblioteka VCL " w 1995 Borland wprowadził na rynek narzędzie typu RAD o nazwie Delphi " językiem programwania był Object Pascal " Delphi zapoczątkowało rewolucję , której centralnym punktem jest pojęcie komponentu (ang. component) " komponent jest obiektem komunikującym się z innymi elementami aplikacji za pomocą właściwości, metod i zdarzeń " projektowanie aplikacji z użyciem komponentów sprowadza się praktycznie do ich umieszczenia na formularzu metodą przeciągnij i upuść (ang. drag and drop) " programowanie wizualne (ang. visual programming) zamiast tradycyjnego pisania programu, budowanie go z gotowych klocków (koncepcję programowania wizualnego przed Delphi zrealizował Microsoft w Visual Basic u, jednak programy w Delphi wykonywały się szybciej niż w Visual Basic u) " wprowadzona wraz z Delphi biblioteka VCL, po dostosowaniu do współpracy z językiem C++, stała się fundamentem systemu C++ Builder Komponenty " komponenty to obiekty wykonujące w aplikacji ściśle określone zadania " interfejs komponentu tworzą właściwości, metody i zdarzenia Właściwości komponentów " właściwości komponentu kontrolują jego wygląd i sposób zachowania (rozmiar, położenie, kolor, możliwość zmiany rozmiaru...) " każda właściwość jest skojarzona z jakimś polem (lub polami) klasy implementującej komponent " niektóre właściwości są wspólne dla grup komponentów (np. Left i Top, określające położenie lewego górnego wierzchołka komponentu na formularzu; Owner, określającą ich właściciela) " w inspektorze obiektów właściwości komponentu znajdują się na liście w porządku alfabetycznym nazwa właściwości wartość właściwości " właściwości mogą być zmieniane zarówno na etapie projektowania, jak i podczas wykonywania programu; w obu przypadkach odbywa się to za pośrednictwem metody dostępu (ang. access method) (o ile jest ona dla właściwości zdefiniowana) " zmiany na etapie projektowania mają natychmiastowy skutek w postaci widzialnej zmiany wyglądu komponentu (dotyczy to tylko komponentów widzialnych i tych ich właściwości, które są związane z wyglądem) " możliwość zmiany niektórych właściwości jest uzależniona od dodatkowych czynników np. właściwość Menu formularza można ustawić dopiero w momencie dołączenia menu do formularza, początkowo jest ona pusta " jeżeli wpiszemy niewłaściwą wartość właściwości, zobaczymy komunikat: " niektóre właściwości są obiektami, np. właściwość Font (typu TFont), opisująca czcionkę danego obiektu; znak + oznacza, że dana właściwość składa się z innych właściwości (krój, wielkość, kolor...) " rozwijamy listę właściwości... " ewentualnie klikamy w przycisk z wielokropkiem " właściwość Lines komponentu Memo (ang. memo), implementującego wielowierszowe pole edycyjne jest obiektem typu TStrings " właściwości mogą być typu zbiorowego, np. właściwość Style właściwości Font; zbiór wartości właściwości Style może być pusty, może też zawierać więcej niż jedną wartość odpowiadającą odmianie czcionki (pogrubionej, pochyłej, podkreślonej i przekreślonej) " właściwości mogą być typu wyliczeniowego, np. właściwość Cursor; właściwość typu wyliczeniowego może w danej chwili przyjąć tylko jedną wartość " zmiany podczas wykonywania programu sprowadzają się do wykonania operacji przypisania: Form1->Left = 200; //zmiana położenia lewej krawędzi formularza " dostęp do właściwości zrealizowany został za pomocą operatora dostępu pośredniego ->; wszystkie komponenty biblioteki VCL są w programie tworzone dynamicznie " właściwości mogą mieć różne atrybuty: " tylko do odczytu (ang. read-only property) " tylko do zapisu (ang. write-only propery) rzadko używane " właściwości dostępne wyłącznie w czasie wykonania (ang. runtime-only property) do właściwości takich można odwoływać się wyłącznie w trakcie wykonywania programu; w fazie projektowania są one niedostępne (nie są wyświetlane w oknie inspektora obiektów), np. właściwość Owner oznaczająca właściciela komponentu Typ zbiorowy " typ zbiorowy zaimplementowany w Pascalu, szeroko wykorzystywany jest w bibliotece VCL " zbiór (ang. set) to zestaw obiektów o zbliżonych cechach " zbiór może być pusty, może też zawierać więcej niż jedną wartość " np. właściwość Style klasy TFont, okreslająca odmianę czcionki, może przyjmować wartość fsBold, fsItalic, fsUnderline i fsStrikeOut, a także dowolną ich kombinację (lub nie przyjmować żadnej wartości) " C++ nie definiuje typu zbiorowego " w VCL istnieje szablon klasy o nazwie Set typedef Set UPPERCASESet; //typ elementów zbioru, minimalna i maksymalna wartość, jaką mogą przyjąć elementy UPPERCASESet s1; " dodawanie elemementów do zbioru - operator << przeciążony w definicji klasy Set s1 << 'A' << 'B' << 'C'; " usuwanie elementów ze zbioru - operator >> " inne metody klasy Set " Clear - usuwa wszystkie elementy ze zbioru " Contains - sprawdza, czy zbiór zawiera element " Emtpy - sprawdza, czy zbiór jest pusty " operator == (porównywanie dwóch zbiorów) " operator != (porównywanie dwóch zbiorów) Przykłady " zmiana czcionki etykiety na pogrubioną i pochyłą Label1->Font->Style=TFontStyles()<//tworzymy tymczasowy obiekt typu zbiorowego TFontStyles, umieszczamy w nim odpowiednie elementy i wstawiamy go do właściwości Style " sprawdzenie, czy czcionka wybranego komponentu jest pogrubiona bool isBold=Label1->Font->Style.Contains(fsBold); Uwaga Specyfika działania klasy Set wymaga, by każda zmiana właściwości typu zbiorowego była realizowana z wykorzystaniem operatora przypisania. Instrukcja: Label1->Font->Style<skompiluje się, ale da spodziewanego efektu. Poprawne wywołanie: Label1->Font->Style=TFontStyles()<//ewentualnie Label1->Font->Style=Label1->Font->Style<Typowe właściwości komponentów " Name " nazwa komponentu, z której korzystamy odwołując się do komponentu z funkcji " Caption " tekst, który pojawia się na powierzchni komponentu " przed ktorymś znakiem nagłówka można dodać symbol & -> klawisz akceleracji (komponent można klikać naciskając klawisz Alt + klawisz akceleracji) " jeżeli potrzebujemy w nagłówku symbolu &, wpisujemy "&&" " Text " posiadają ją komponenty, które umożliwiają użytkownikom wpisywanie tekstu " zwykle można określić wartość domyślną tej właściwości, która zostanie wyświetlona przy iperwszym wyświetleniu formularza " Width, Height " szerokość i wysokość komponentu (w pikselach) " Left, Top " położenie lewego górnego rogu komponentu względem lewego górnego rogu wewnątrz formularza (w pikselach) " Font " czcionka komponentu, który wyświetla tekst " Color " kolor tła komponentu " w przypadku komponentów, które wyświetlają tekst, kolor tekstu definiuje właściwość Color właściwości Font " TabStop " klikając na komponent powowdujemy, że staje się on komponentem bieżącym (aktywnym) - jest on na celowniku " gdy użytkownik naciska klawisz Tab, celownik przenosi się na następny komponent " TabStop określa, czy komponent może znalezć się na celowniku (true), czy też nie (false) " TabOrder " definiuje kolejność, w jakiej komponenty są brane na celownik " każdy komponent formularza ma niepowarzalną liczbę porządkową tabulacji (numerowane od 0) " po zmianie wartości TabOrder komponentu, nastąpi aktualizacja wszystkich liczb porządkowych innych komponentów " Edit -> Tab Order... " Visible " określa czy komponent będzie widoczny (true) czy też nie (false) " komoponent niewidoczny nie reaguje na zdarzenia " Enabled " określa, czy można będzie korzystać z komponentu (true) czy też nie (false) Metody " metodami nazywamy w VCL funkcje wywoływane w celu uzyskania pożądanego zachowania komponentu, np. metoda Show() wyświetla komponent, metoda Hide() ukrywa komponent " tak jak w C++, metody są funkcjami składowymi klasy definiującej komponent " wywołanie metody: MyWindwow->Show(); //coś się dzieje w okienku MyWindow->Hide(); MyWindow->Close(); " tak jak w C++, metody mogą być deklarowane jako publiczne, prywatne i chronione (ang. public, private, protected); znaczenie tych słów kluczowych jest takie same jak w C++ " metody publiczne (public) (Show() i Hide()) są swobodnie dostępne dla użytkowników komponentu " metody chronione (protected) są niedostępne z zewnątrz komponentu, lecz mogą być wywoływane w klasach pochodnych " metody prywatne (private) są dostępne wyłączne w obrębie klasy definiującej komponent " metody mogą pobierać z otoczenia parametry i zwracać wartości: char buf[256]; int numChars=myEdit->GetTextBuf(buf,sizeof(buf)); Wybrane metody " metoda int __fastcall GetTextBuf(char * Buffer, int BufSize); " pobiera dwa parametry i zwraca wartość typu całkowitego; tekst znajdujący się w kontrolce jest umieszczany w buforze buf, a funkcja zwraca jego długość " metoda int _fastcall GetTextLen(void); " zwraca długość tekstu kontrolki " virtual void __fastcall SetFocus(void); " ustawia daną kontolkę na celowniku " virtual void __fastcall Clear(void); " void __fastcall ClearSelection(void); " usuwają tekst z pola edycyjnego Zdarzenia " system Windows należy do systemów sterowanych zdarzeniami (ang. event-driven systems), tzn. przyczyną działań podejmowanych przez oprogramowanie systemowe i użytkowe są zdarzenia generowane w obrębie systemu, np. ruchy i klikanie myszką " zaistnienie zdarzenia powoduje wygenerowanie przez Windows tzw. komunikatu (ang. message), rozsyłanego do poszczególnych elementów systemu i pracujących w nim aplikacji " aplikacje przeglądają nadchodzące komunikaty, wychwytują te przeznaczone dla nich i reagują na nie w sposób określony przez programistę " komunikat jest złożoną strukturą danych zawierającą m.in. informacje o rodzaju zdarzenia, jego adresacie, czasie wygenerowania i in. " w bibliotece VCL każdy komponent reaguje na określoną liczbę zdarzeń " reakcja na zdarzenie nosi nazwę obsługi zdarzenia (ang. event handling), a funkcje przeznaczone do tego celu nazywane są funkcjami obsługi zdarzeń (ang. event handler) " nazwy funkcji obsługi zdarzeń generowane są automatycznie na podstawie nazwy komponentu i zdarzenia, np. Button1Click (zdarzenie OnClick komponentu Button1) " lista wszystkich zdarzeń, na które reaguje dany komponent znajduje się na karcie Events inspektora obiektów " obsłużenie wszystkich zdarzeń zdefiniowanych dla komponentu nie jest obowiązkowe; ograniczamy się do zdarzeń, które nas interesują " jeżeli nie zdefiniujemy obsługi danego zdarzenia, komponent albo użyje metody domyślnej, albo zignoruje komunikat o zdarzeniu Typowe zdarzenia komponentów " OnClick " generowane jest, kiedy użytkownik kliknie przycisk myszy po umieszczeniu jej wskaznika nad kontrolką " OnDoubleClick " generowane jest, kiedy użytkownik dwukrotnie kliknie przycisk myszy po umieszczeniu jej wskaznika nad kontrolką " OnMouseDown " kiedy przycisk myszy zostanie naciśnięty " OnMouseUp " kiedy przycisk myszy zostanie zwolniony " zdarzenia OnMouseDown i OnMouseUp dostarczają informacji, który przycisk myszy został wciśnięty i czy jednocześnie został wciśnięty klawisz Shift, Ctrl lub Alt (zdarzenie OnClick nie dostarcza żadnych dodatkowych informacji) " OnMouseMove " generowane jest, kiedy użytkownik przesuwa wskaznik myszy nad obiektem " OnDragOver " generowane jest, kiedy użytkownik przeciaga obiekt nad kontrolką " OnDragDrop " generowane jest, kiedy użytkownik upuści obiekt, który jest przeciągany " OnEnter " generowane jest, kiedy komponent zostaje wzięty na celownik " OnExit " generowane jest, kiedy komponent zostaje zdjęty z celownika " OnKeyPress " generowane jest, kiedy zostanie naciśnięty klawisz " może zostać podzielone na dwa inne zdarzenia: " OnKeyDown i OnKeyUp " OnChange " generowane jest, kiedy ulegnie zmianie wartość pola edycji, pola memo lub paska przewijania Zdarzenia przykład 1 " zmieniamy właściwość Name formularza na PMEForm (ang. properties, methods, events) " zmieniamy właściwość Name pola edycyjnego na Memo " zmieniamy właściwość Name przycisku na Button " klikamy dwukrotnie w polu zdarzenia OnClick przycisku " wpisujemy kod: " deklarator __fastcall w Builderze używany jest domyślnie w metodach klas biblioteki VCL; oznacza, że parametr funkcji zostanie przekazany poprzez rejestry procesora " właściwość Visible oznacza, czy komponent jest widoczny " metody Hide() i Show() wyświetlają i ukrywają komponent " parametrem funkcji ButtonClick() jest wskaznik do obiektu o nazwie Sender (występuje on zawsze jako parametr dla każdej funkcji obsługującej zdarzenie) " obiekt Sender jest nadawcą komunikatu, czyli obiektem, który wygenerował zdarzenie obsługiwane przez daną funkcję " w naszym przykładzie wskaznik ten nie jest wykorzystywany, gdyż nadawca komunikatu jest tylko jeden (przycisk Pokaż/Schowaj) " możliwa jest sytuacja, w której zdarzenie obsługiwane przez funkcję będzie miało kilku potencjalnych nadawców, których trzeba będzie rozpoznać (Sender) Zdarzenia przykład 2 " rozdzielamy funkcje przycisku Pokaż/Schowaj pomiędzy dwa nowe: Pokaż i Schowaj " zmieniamy właściwość Caption przycisku Pokaż/Schowaj na Pokaż a właściwość Name na Show " wstawiamy nowy przycisk (Name: Hide, Caption: Schowaj) " nazwa funkcji obsługującej kliknięcie przycisku Show zmieniła się na ShowClick, zmieniamy ją w inspektorze obiektów na ButtonClick " w inspektorze obiektów przycisku Hide odszukujemy zdarzenie OnClick i z listy wybieramy funkcję ButtonClick " klikamy dwukrotnie w polu nazwy funkcji i wpisujemy kod: " została utworzona funkcja obsługi zdarzenia OnClick wspólna dla obu przycisków " aby rozpoznać nadawcę komunikatu o zdarzeniu, wykorzystany został parametr Sender " funkcje obsługi zdarzeń mogą być powiązane z wieloma komponentami Zdarzenia - przykład 3 " podczas poruszania się myszą nad panelem, w polach edycyjnych wypisywane są współrzędne wskaznika myszy " dodatkowo na etykiecie Label3 wypisywane jest, czy wciśnięto klawisz Shit, Alt czy Ctrl " zdarzenie OnMouseMove " typ zbiorowy TShiftState określa stan klawiszy Shitf, Alt i Ctrl oraz przycisków myszy " TShiftState " ssShift został wciśnięty klawisz Shift " ssAlt został wciśnięty klawisz Alt " ssCtrl został wciśnięty klawisz Ctrl " ssLeft został wciśnięty lewy klawisz myszy " ssRight został wciśnięty prawy klawisz myszy " ssMiddle został wciśnięty środkowy klawisz myszy " ssDouble podwójnie kliknięto myszą Uwaga Zdarzenia OnMouseDown i OnMouseUp posiadają dodatkowy parametr Button, typu wyliczeniowego TMouseButton Zdarzenia - przykład 4 " formularz reagujący na naciśnięcie klawiszy: Enter, F1, Delete i Ctrl+k " zdarzenie OnKeyDown " parametr Key określa, który klawisz został naciśnięty (litery małe i duże są reprezentowane przez ich duże odpowiedniki) " wirtualne kody klawiszy przykładowe wirtualne kody klawiszy Uwaga Zdarzenie OnKeyPress generowane jest, kiedy użytkownik naciśnie klawisz. " w przeciwieństwie do zdarzeń OnKeyDown i OnKeyUp, klawisz naciśnięty dla tego zdarzenia musi być znakiem pojedynczym znakiem " małe i duże litery są reprezentowane przez oddzielne stałe ('K','k') " formularz nie zareaguje na naciśnięcie klawiszy F1 i Delete Nieco więcej o bibliotece VCL " mocno uproszczony schemat hierarchii klas w bibliotece VCL komponenty niewizualne komponenty wizualne " na szczycie drzewa klas znajduje się klasa TObject, abstrakcyjna klasa, której metody wykonują fundamentalne czynności wspólne dla wszystkich obiektów, np. tworzenie czy niszczenie obiektu " klasa TPersistant jest klasą bazową dla wszystkich obiektów, które posiadają właściwości; metody tej klasy odpowiadają m.in. za wysyłanie danych do strumieni, przydzielanie pamięci i in. " klasa TComponent implementuje podstawowe cechy funkcjonalne abstrakcyjnego komponentu, jest bezpośrednim przodkiem wszystkich klas komponentowych; metody tej klasy umożliwiają m.in. wyświetlenie komponentu na palecie komponentów i manipulowanie nim bezpośrednio na formularzu " komponenty nie posiadające widocznej reprezentacji (niewizualne) wywodzone są bezpośrednio od TComponent " komponenty niewizualne (np. timer) w fazie projektowania reprezentowane są przez ikony; umożliwia to manipulowanie ich właściwościami i zdarzeniami " komponenty wizualne, zwane kontrolkami, dziedziczą po klasie TControl; klasa ta dostarcza właściwości opisujące wizualne atrybuty kontrolek, np. wysokość czy szerokość " wyróżniamy dwa typy kontrolek: " te, które posiadają swoje własne okno (ang. windowed controls) " te, które używają okna swojego rodzica " kontrolki posiadające swoje własne okno dziedziczą po klasie TWinControl (np. przyciski, pola edycyjne); po uruchomieniu są dostępne z klawiatury, mogą być rodzicami innych kontrolek " kontrolki używające okna swojego rodzica nazywane są kontrolkami graficznymi i wywodzą się z klasy TGraphicControl (obrazki, kształty...); po uruchomieniu nie są dostępne z klawiatury, nie mogą być rodzicami innych kontrolek " klasa Exception jest klasą bazową dla wszystkich klas związanych z wyjątkami Klasy implementujące formularz i aplikację " każda aplikacja w Builderze deklaruje wskaznik do obiektu klasy TApplication o nazwie Application " po utworzeniu projektu, tworzona jest instancja klasy TApplication " klasa TApplication realizuje podstawowe cechy funkcjonalne aplikacji przeznaczonej dla środowiska Windows " zajmuje się ona obsługą komunikatów, implementacją systemu pomocy, wyświetlaniem ikony i innymi czynnościami administracyjnymi " niektóre jej właściwości (ikony, tytuł, pliku z tekstem pomocy) mogą być ustalone za pomocą okna dialogowego Project Options (Project -> Options), karta Application " aby utworzyć aplikację, wywoływana jest metoda Initialize() klasy TApplication: void __fastcall Initialize(void); " wywołanie tej metody powoduje utworzenie pustej aplikacji " klasa TForm definiująca formularz, jest jednym z głównych filarów biblioteki VCL " po utworzeniu aplikacji, kolejnym krokiem jest utworzenie formularza (formularz główny jest tworzony automatycznie po utworzeniu projektu, pozostałe można dodawać poleceniem File -> New -> Form) " po dodaniu formularza do projektu, w kodzie pliku projektu pojawiają się instrukcje: " Application->CreateForm(__classid(TForm1), &Form1); metoda CreateForm() klasy TApplication przyjmuje dwa parametry: pierwszym jest klasa formularza (operator __classid()), drugim adres zmiennej reprezentującej formularz; metoda powoduje utworzenie formularza " USEFORM("Unit1.cpp", Form1); makro USEFORM przyjmuje dwa parametry: pierwszym jest nazwa pliku zródłowego formularza, drugim zmienna reprezentująca formularz; wywołanie makra USEFORM specyfikuje nazwę pliku zródłowego, w którym zaimplementowany jest formularz " aby aplikacja mogła poprawnie działać (odbierać komunikaty od kontrolek, przetwarzać je i odpowiadać na nie we właściwy sposób), klasa TApplication używa metody Run(): Application->Run(); " gdyby metoda Run() nie była wywołana, aplikacja skompilowałaby się i wykonała poprawnie, ale nie mogłaby przetwarzać komunikatów Klasy komponentowe " zakładka Standard " zawiera komponenty realizujące popularne elementy interfejsu użytkownika TFrames TComboBox TMainMenu TScrollBar TPopupMenu TGroupBox TLabel TRadioGroup TEdit TPanel TMemo TActionList TButton TCheckBox TRadioButton TListBox " zakładka Additional " jest rozszerzeniem karty Standard, zawiera szereg dodatkowych komponentów przydatnych w projektowaniu aplikacji TBitBtn TScrollBox TSpeedButton TCheckBox TMaskEdit TSplitter TStringGrid TStaticText TDrawGrid TControlBar TImage TApplicationEvents TShape TChart TBevel " zakładka Win32 " zawiera wszystkie elementy sterujące reprezentowane w aplikacjach Windows TTabControl TMonthCalendar TPageControl TTreeView TImageList TListView TTrackBar THeaderControl TProgessBar TStatusBar TUpDown TToolBar THotKey TAnimate TDateTimePicker " zakładka Dialogs " komponenty tej zakładki reprezentują standardowe okna dialogowe Windows: okna do zapisu i odczytu pliku, drukowania, wyboru rodzaju czcionki czy palety kolorów TOpenDialog TColorDialog TSaveDialog TPrintDialog TOpenPictureDialog TPrinterSetupDialog TSavePictureDialog TFindDialog TFontDialog TReplaceDialog