Teraz wróćmy do mutatorów i funkcji prywatnych. Umieszcza się je tam, ponieważ Borland dodał małe "rozszerzenie" - słówko kluczowe "__published". Wszystkie właściwości komponentu muszą być deklarowane jako __published, a do dostępu do danych i ich zmiany używa się specjalnej składni. Po dodaniu trzech właściwości do sekcji __published kod wygląda tak: __published: __property bool LEDOn = {read = FOnOff, write = SetOnOff}; __property TColor OnColour = {read = FOnColour, write = SetOnColour}; __property TColor OffColour = {read = FOffColour, write = SetOffColour};Wszyskie właściwości zaczynają się słówkiem kluczowym __property, za którym stoi typ zmiennej i deklaracja odczytu (read) i zapisu (write). Interesujące jest to, że read wskazuje na zmienną, a write na funkcję. W zasadzie i read i write może wskazywać bądź to na zmienną, bądź na funkcję, ale zwykle powinieneś robić tak, jak napisałem wyżej. Nazwa właściwości nie ma żadnego związku ze zmienną, którą modyfikuje (na przykład: zmienna FOnOff jest modyfikowana przez właściwość LEDOn). Jednak zalecam stosowanie standardowego nazewnictwa i nadawanie właściwości tej samej nazwy co zmienna, bez literki "F" na początku. I to już wszystko co musieliśmy zmienić w pliku nagłówkowym. Właściwość może mieć domyślną wartość, na przykład: __property bool LEDOn = {read=FOnOff, write=SetOnOff, default=false};Teraz ta domyślna wartość nie jest domyślną wartością, którą zobaczysz w inspektorze obiektów (to musisz ustawić w konstruktorze komponentu, o czym dalej). Sądzisz, że użytkownik będzie używał właśnie takiej wartości (dlatego chyba nazywa się domyślną). Za każdym razem, kiedy dodajesz nowy komponent na formę, Builder umieszcza informacje o tym komponencie w pliku .DMF. Ponieważ wszystkie właściwości komponentu determinują jego wygląd , miejsce na formie, itp., są po prostu umieszczane w binarnym pliku .DMF na dysku. Wartość domyślna którą przypisujesz komponentowi określa czy ta wartość będzie zapisana do pliku .DMF, czy nie. Jeżeli wartość na formie jest taka sama jak wartość domyślna komponentu, to nie jest ona zapisywana na dysk. Jeżeli wartość różni się, to jest zapisywana. Właściwości można też deklarować z słówkiem kluczowym nodefault: __property bool LEDOn = {read=FOnOff, write=SetOnOff, nodefault};To oznacza, że będzie zawsze zapisywana. Dostępny jest także atrybut stored. Możesz unieważnić domyślne zapisywanie tym właśnie atrybutem . Jeżeli ustawisz go na true, to zawsze będzie zapisana, jeżeli na false, to nigdy nie będzie zapisana. __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=true}; __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=false}; __property bool LEDOn = {read=FOnOff, write=SetOnOff, stored=Check};Ostatnim atrybutem, jaki może mieć właściwość jest index. Jest użyteczny, gdy kilka mutatorów i akcesorów duplikuje kod. Zamiast pisania oddzielnych funkcji dla każdego, możesz stworzyć jednego akcesora z indeksem. Indeks jest pierwszym elementem przekazywanym do Twojego akcesora/mutatora. Na przykład: __property TColor OnColour = {read=FOnColour, write=SetOnOffColour, index=1}; __property TColor OffColour = {read=FOffColour, write=SetOnOffColour, index=2};a implementacja SetOnOffColor wyglądałaby tak: void __fastcall TLED::SetOnOffColour(int Index,TColor Colour) { switch(Index) { case 1 : FOnColour = Colour; break; case 2 : FOffColour = Colour; break; } Brush->Color = (FOnOff)?FOnColour:FOffColour; }Jednakże to uczyniłoby nasz kod mniej czytelnym (a to w końcu nasz pierwszy komponent) i nie osczędziłoby zbyt wiele miejsca.
|