Spowodowane jest to bra- kiem instancji wewnętrznego obiektu !0. Do sekcji publicznej pliku nagłówkowego klasy dodajemy następującą deklarację: 3(/>8# , - Do konstruktora i destruktora komponentu dodajemy następujący kod: (/>8# &&(/>8# ( ) 01 -&(>8# 1 - $ 8 ( $ 8+- $ 8@A % (/>8# &&3(/>8# , - $ 8- Rozdział 4. Tworzenie własnych komponentów 245 $ 8@A $ 8@A1 M $ 8 Właściwość z !0 jest typu % . Musi być ona ustawiona na kom- ponent, który korzysta z obiektu !0, aby móc zarządzać łączem do obiektu . Właściwość ustawiamy na , aby zaznaczyć, że łącze dotyczy kom- ponentu. Dostęp do uzyskujemy, dodając właściwość tylko do odczytu. Podany wiersz umieszczamy w sekcji publicznej definicji klasy. ( 0 " Deklarację ) dodajemy do sekcji prywatnej. ( 0" , - Podany kod umieszczamy w pliku kodu źródłowego. ( 0(/>8# &&" , - +$ 8@A - # $ Wykonaliśmy komponent łączący się ze źródłem danych, ale na razie nie reaguje on na zmiany danych. Teraz napiszemy kod, który umożliwi reakcję komponentu na zmiany pól, na przykład przejście do nowego rekordu. Klasy łączy danych posiadają zdarzenie zgłaszane w momencie, w któ- rym źródło danych wykryje zmianę w danych. Aby komponent mógł odpowiedzieć na tę zmianę, dodajemy metodę i przypisujemy ją do zdarzenia . !0 to klasa pomocnicza wykorzystywana w obiektach związanych z danymi. Listę jej metod, zdarzeń i właściwości zawiera pomoc środowiska programistycznego C++Builder. Zdarzenie jest typu , więc przy tworzeniu własnej metody musimy korzystać z tego samego prototypu. Poniższy fragment kodu dodajemy do sek- cji prywatnej nagłówka komponentu. !"#(/>8# &' (>8# ,& 55;;; , % +(1'20* - W konstruktorze przypisujemy metodę "# do zdarzenia . Przy- pisanie to usuwamy w destruktorze. 246 Część I Podstawy środowiska C++Builder (/>8# &&(/>8# ( ) 01 -&(>8# 1 - $ 8 ( $ 8+- $ 8@A % $ 8@A1 % % (/>8# &&3(/>8# , - $ 8- $ 8@A $ 8@A1 M $ 8@A1 % $ 8 Na końcu w następujący sposób definiujemy metodę "#. , (/>8# && % +(1'20* - =$ 8@A - ) *; + -- (4.) (4DD (4$ 8@A @A* Metoda "# sprawdza najpierw, czy łącze danych wskazuje na źródło (i pole) danych. Jeśli nie jest to poprawny wskaźnik, ustawia właściwość & (pole komponentu rodzica) na pusty tekst (w trakcie wykonywania programu) lub na nazwę kontrolki (w trybie projektowania). Jeśli jest to poprawne pole, ustawia właściwość & na zawartość pola, używając właściwości ' obiektu . Tym sposobem uzyskaliśmy kontrolkę przeglądania danych. Jest tak nazywana, ponie- waż umożliwia tylko wyświetlanie zmian źródła danych. Zamieńmy teraz komponent na kontrolkę edycji danych. ( !& Zamiana kontrolki przeglądania danych na kontrolkę edycji danych wymaga dodania kodu reagującego na zdarzenia myszy i klawiatury. Umożliwi to odzwierciedlenie zmian dokonanych w kontrolce w polu dołączonej bazy danych. %! Gdy użytkownik umieszcza kontrolkę edycji danych w projekcie, oczekuje, że kontrol- ka taka nie będzie tylko do odczytu. Domyślna wartość właściwości - klasy +0 (klasa rodzicielska) to , więc nie musimy niczego modyfikować. Jeśli Rozdział 4. Tworzenie własnych komponentów 247 kreujemy komponent zawierający własną właściwość -, upewnijmy się, że jest ona inicjalizowana na . ' Jeśli zajrzymy do pliku controls.hpp, dowiemy się, że +0 zawiera dwie metody chronione, ; 9"# i + 9"#. Metody te są wywoływane w odpowiedzi na komunikaty okien (*+,;5*, *+,!/*, *+,+/* i *+,-/*), a same mogą wywoływać odpowiednie zdarzenia, jeśli użytkownik takowe zdefiniuje. Aby przesłonić te metody, dodajemy własne metody ; 9"# i + 9"# do klasy +0. Wykorzystujemy deklaracje klas z pliku controls.hpp. , , > +(>/ (*% **% L S- , , ! + %Opis tych klas znajdziemy także w pliku pomocy środowiska C++Builder. Dodajemy kod źródłowy przedstawiony na listingu 4.59. Metody MouseDown() i KeyDown() , (/>8# &&> +(>/ / (*% **% L å S- =E1 <<$ 8@A# -- (>8# &&> +/ *% LS- 1 > - 1 > +% / *% LS- , (/>8# &&! + %*B %W! E1EW!1K.A! !!BBW! E1EBBW!.#L(BBW!#.BBW!J1>#BBW!$#(BBW!M BB åW!E"J(BBW!1K. =E1 <<+!; +!--<<$ 8@A# -- (>8# &&! +!*% - 1 ! - 1 ! +% !*% - W obydwu przypadkach sprawdzamy, czy komponent nie jest tylko do odczytu oraz czy !0 jest w trybie edycji. Metoda ; 9"# sprawdza jeszcze wszystkie kla- wisze kursorów (zdefiniowane w pliku winuser.h). Jeśli wszystkie testy przejdą po- myślnie, pole można edytować, więc wywoływana jest metoda klasy rodzica. Wywołuje ona automatycznie kod użytkownika przypisany do zdarzenia, jeśli istnieje. Jeśli pola nie można edytować, wywołujemy tylko kod użytkownika dotyczący zdarzenia. 248 Część I Podstawy środowiska C++Builder )( & Jeśli użytkownik zmodyfikuje zawartość kontrolki związanej z danymi, zmiana musi zostać odzwierciedlona w polu. Podobnie, jeśli zostanie zmodyfikowana wartość pola, kontrolka powinna uaktualnić swą wartość. Komponent +0 zawiera metodę "# wywoływaną przez zdarzenie z !0. Metoda ta odpowiada za aktualizację komponentu, gdy zmieniona została zawartość pola. Oznacza to, że drugi przypadek aktualizacji danych jest już wykonany. Zajmiemy się teraz aktualizacją wartości pola, gdy użytkownik zmodyfikował zawar- tość komponentu. Klasa !0 zawiera zdarzenie /, w którym to kontrolka może umieścić zmiany rekordu bazy danych. Możemy teraz wykreować me-
|