[ Pobierz całość w formacie PDF ]
.__published:__property AnsiString DataField ={read = GetDataField, write = SetDataField, nodefault};__property TDataSource *DataSource ={read = GetDataSource, write = SetDataSource, nodefault};.};Wspominaliœmy na wstêpie, i¿ nasz komponent powinien umo¿liwiaæ na ¿¹danieblokadê modyfikacji danych, udostêpniaj¹c je wy³¹cznie do podgl¹du; ten aspektjego funkcjonowania nie jest jednak¿e elementem ³¹cznoœci z danymi – ustawieniena true w³aœciwoœci ReadOnly uniemo¿liwia jedynie modyfikacjê wyœwietlanejzawartoœci, co oczywiœcie nie zabrania u¿ytkownikowi dokonywania bezpoœrednichzapisów do pola bazy danych identyfikowanego przez w³aœciwoœci DataSource iDataField.Implementacjê metod dostêpowych wspomnianych w³aœciwoœci przedstawia wydruk7.57.Wydruk 7.57.Implementacja metod dostêpowych w³aœciwoœci po³¹czeniowychAnsiString __fastcall TDBMaskEdit::GetDataField(void){return(FDataLink->FieldName);}TDataSource * __fastcall TDBMaskEdit::GetDataSource(void){return(FDataLink->DataSource);}void __fastcall TDBMaskEdit::SetDataField(AnsiString pDataField){FDataLink->FieldName = pDataField;}void __fastcall TDBMaskEdit::SetDataSource(TDataSource *pDataSource){if(pDataSource != NULL)pDataSource->FreeNotification(this);FDataLink->DataSource = pDataSource;}Pewnego komentarza wymaga tu u¿ycie funkcji FreeNotification().Jak ju¿wczeœniej pisaliœmy, komponent musi byæ œwiadom zwalniania obiektów, na którewskazuj¹ jego w³aœciwoœci.Œwiadomoœæ tê zapewnia metoda Notification(), lecztylko w stosunku do komponentów znajduj¹cych siê na tym samym formularzu;zwalnianie komponentów znajduj¹cych siê na innych formularzach nie jest dlaniego zauwa¿alne w sposób standardowy i musi byæ zapewnione przy u¿yciu metodyFreeNotification().Komponent, wywo³uj¹c tê metodê w kontekœcie komponentupowi¹zanego, zapewnia sobie tym samym informacjê o destrukcji tego ostatniego.Wykorzystaliœmy tê mo¿liwoœæ, poniewa¿ nie mo¿na wykluczyæ, i¿ powi¹zanykomponent wskazywany przez w³aœciwoœæ DataSource znajduje siê na innymformularzu.Nasz komponent nie jest jeszcze kompletny – próba jego wykorzystania waplikacji skoñczy siê rych³o komunikatem o naruszeniu mechanizmu ochrony(access violation).Oczywistym tego powodem jest brak egzemplarzaobiektu-³¹cznika wskazywanego przez w³aœciwoœæ FieldDataLink.Egzemplarz tenpowinien byæ utworzony w konstruktorze komponentu__fastcall TDBMaskEdit::TDBMaskEdit(TComponent* Owner): TMaskEdit(Owner){FDataLink = new TFieldDataLink();FDataLink->Control = this;FDataLink->OnUpdateData = UpdateData;FDataLink->OnDataChange = DataChange;}Po utworzeniu obiektu-³¹cznika zainicjowane zostaj¹ jego w³aœciwoœci: Control,wskazuj¹ca macierzyst¹ kontrolkê (czyli nasz komponent) i dwie w³aœciwoœcizdarzeniowe, którym przypisuje siê funkcje obs³ugi (bêd¹ce metodami naszegokomponentu).Egzemplarz obiektu-³¹cznika powinien byæ tak¿e zwolniony w ramach destruktora,po uprzednim anulowaniu powi¹zañ z naszym komponentem i jego metodami:__fastcall TDBMaskEdit::~TDBMaskEdit(void){if(FDataLink){FDataLink->Control = 0;FDataLink->OnUpdateData = 0;FDataLink->OnDataChange = 0;delete FDataLink;}}Ró¿norodne atrybuty pola bazy danych, z którym po³¹czony jest nasz komponent,dostêpne s¹ poprzez reprezentuj¹cy to pole komponent TField.Ten ostatniwskazywany jest przez w³aœciwoœæ Field, stanowi¹c¹ tak naprawdê powieleniew³aœciwoœci obiektu ³¹cznikowego o tej samej nazwie.W³aœciwoœæ ta jestw³aœciwoœci¹ tylko do odczytu – jej deklaracja nie zawiera klauzuli write:__property TField *Field = {read = GetField};.TField * __fastcall TDBMaskEdit::GetField(void){return(FDataLink->Field);}Aktualizowanie zawartoœci kontrolki – zdarzenie OnDataChangeNasz komponent, mimo po³¹czenia z baz¹ danych, nie posiada jeszcze mechanizmówumo¿liwiaj¹cych reagowanie na zmiany w powi¹zanych danych, na przyk³ad„przesuniêcie” bazy danych do kolejnego rekordu („wiersza”).Mechanizmy takieudostêpniane s¹ przez klasy ³¹cznikowe – ka¿da zmiana w po³¹czonych danychpowoduje mianowicie wygenerowanie zdarzenia OnDataChange w kontekœcie obiektu³¹cznikowego.Zdarzenie to jest typu TNotifyEvent, co decyduje o postaci jegofunkcji obs³ugi, bêd¹cej de facto metod¹ DataChange() naszego komponentu:class PACKAGE TDBMaskEdit : public TMaskEdit{private:.void __fastcall DataChange(TObject *Sender);.}.void __fastcall TDBMaskEdit::DataChange(TObject *Sender){if(!FDataLink->Field) // czy okreslono obiekt ³¹cznikowy?{// nie okreœlono obiektu ³¹cznikowego;// w czasie projektowania zwróæ nazwê komponentu,// w czasie wykonania – pusty ³añcuchif(ComponentState
[ Pobierz całość w formacie PDF ]
Darmowy hosting zapewnia PRV.PL