Przedmiot: Programowanie usług internetowych - Delphi Przygotował: K. Strzałkowski Rok V. Semestr IX. Wydział ZiMK Ćwiczenie 10 Generowanie plików HTML 1. Przygotowanie aplikacji generującej prostą stronę. Przygotuj program wyświetlający formatkę jak na rysunku (w fazie projektowania): Przycisk pierwszy powinien powodować umieszczenie zapisu strony w komponencie Memo. Przycisk drugi powinien zapisywać tekst strony w pliku *.HTML, a następnie wyświetlać ją w przeglądarce. Realizacja zadania: Umieść na formatce komponenty: Memo, Label, Button i SaveDialog. Zdefiniuj właściwości Caption komponentów Label i Button wg rysunku. W kodzie modułu Unit1 zdefiniuj dwie metody - składowe komponentu formatki Form1: void TForm1::naglowek(String tytul) Memo1->Lines->Add("<HTML>"); Memo1->Lines->Add("<HEAD>\n"); Memo1->Lines->Add("<TITLE>" + tytul + "</TITLE>"); Memo1->Lines->Add("</HEAD>"); Memo1->Lines->Add("<BODY>"); Memo1->Lines->Add("<H1><CENTER>" + tytul + "</CENTER></H1>"); Metoda dopisuje do Memo zapis (w HTML) początku strony. void TForm1::stopka() Memo1->Lines->Add("<HR>"); Memo1->Lines->Add( "Strona wygenerowana przez napisany w C-Builder program:"+ ExtractFileName(Application->ExeName)); Memo1->Lines->Add("</BODY>"); Memo1->Lines->Add("</HTML>"); 1
Procedura powyższa dopisuje do Memo zapis końca (stopki) strony. Zdefiniuj metodę obsługi zdarzenia OnClick pierwszego przycisku. Proponowany zapis metody: void fastcall TForm1::Button1Click(TObject *Sender) String Str; Memo1->Clear(); naglowek("strona przykładowa"); DateTimeToString(Str, "yyyy-mm-dd", Now()); Memo1->Lines->Add("<HR> Data generacji strony: " + Str); // 1 stopka(); Zdefiniuj metodę obsługi zdarzenia OnClick drugiego przycisku. Proponowany zapis metody: void fastcall TForm1::Button2Click(TObject *Sender) if (SaveDialog1->Execute()) Memo1->Lines->SaveToFile(SaveDialog1->FileName); ShellExecute(Application->Handle, "open", AnsiString(SaveDialog1->FileName).c_str(), NULL, NULL, SW_NORMAL); Metoda powoduje nawiązanie dialogu w celu ustalenia nazwy pliku w którym zapisana będzie strona, a następnie wywołanie akcji systemu operacyjnego o nazwie open powodującej wyświetlenie pliku przez domyślny program. W przypadku rozszerzenia pliku, *.HTML lub *.HTM będzie to przeglądarka internetowa. Ew. ustaw opcję Project/ Option/ C++ (shared options) / _TChar maps to na char. Zapisz projekt w oddzielnym katalogu P1 i przetestuj jego działanie. Wygenerowaną stronę zapisuj w katalogu projektu pod nazwą STRONA1.HTML. Przed zapisem w pliku i wyświetleniem strony zmieniaj jej postać edytując odpowiednio tekst wyświetlany w komponencie Memo. 2. Wyświetlanie na stronie zawartości tabeli bazy danych. Skopiuj opracowany projekt do nowego katalogu P2. Dołącz na formatce dwa nowe komponenty z zakładki dbexpress i ustaw ich właściwości dla uzyskania połączenia z tabelą bazy SKOKI.GDB: SQLConnection: ConnectionName: Params: Connected: wybierz IBConnection (wybranie tego połączenia spowoduje że C-Builder ustawi inne właściwości zgodnie ze standardem InterBase) uruchom edytor właściwości, a następnie w wyświetlonej tabeli zmień pozycję DataBase wpisując nazwę pliku bazy (wraz ze ścieżką dostępu) wybierz True i wypełń odpowiednio okienko logowania do bazy 2
SQLDataSet: SQLConnection: CommandType: CommandText: Active: wybierz SQLConnection1 wybierz cttable wybierz Druzyny wybierz True Zmodyfikuj metodę obsługi zdarzenia OnClick dla przycisku pierwszego dodając deklarację: int i, k; oraz zastępując komentarz 1 zapisem: Memo1->Lines->Add("<HR> Tabela " + SQLDataSet1->CommandText); Str="<TABLE BORDER><TR>"; for (i=0; i<sqldataset1->fieldcount; i++) Str=Str + "<TD><B>" + SQLDataSet1->Fields->Fields[i]->FieldName + "</B></TD>"; Memo1->Lines->Add(Str + "</TR>"); SQLDataSet1->First(); for (k=1; k<=sqldataset1->recordcount; k++) Str="<TR>"; for (i=0; i<sqldataset1->fieldcount; i++) Str=Str+"<TD>" + SQLDataSet1->Fields->Fields[i]->DisplayText + "</TD>"; Memo1->Lines->Add(Str+"</TR>"); SQLDataSet1->Next(); Memo1->Lines->Add("</TABLE>"); Przetestuj działanie programu. Program powinien wyświetlać w przeglądarce zawartość tabeli Druzyny. 3. Zastosowanie komponentu PageProducer Skopiuj opracowany wg punktu 1 projekt P1 do nowego katalogu P3. Usuń z kodu modułu Unit1 definicje metod naglowek i stopka oraz ich zapowiedzi w definicji typu TForm1. Dołącz na formatce dwa komponenty do połączenia z bazą SKOKI.GDB i ustaw ich właściwości jak w punkcie 2 dla uzyskania połączenia z tabelą bazy. Dla komponentu SQLDataSet ustaw odmiennie właściwości: CommandType: wybierz ctquery CommandText: wpisz zapytanie: SELECT NAZWISKO, IMIE, NAZWA, DL FROM DRUZYNY, ZAWODNICY, SKOKI WHERE ID_DRU=ID_DRUZYNY AND ID_ZAW=ID_ZAWOD Active: true Dołącz do formatki komponent PageProducer z zakładki Internet. Ustaw właściwość komponentu: HTMLDoc: wpisz szablon strony: <HTML> 3
<HEAD> <TITLE>Tabela STANY</TITLE> </HEAD> <BODY> <H1><CENTER>Pozycja tabeli STANY</CENTER></H1> <HR><#p1><#p2><#p3><#p4><#p5><HR> Strona wygenerowana przez C-Buider dnia <#teraz><br> </BODY> </HTML> Wykasuj dotychczasowy zapis metody obsługi zdarzenia OnClick dla przycisku pierwszego i wpisz: void fastcall TForm1::Button1Click(TObject *Sender) Memo1->Clear(); Memo1->Text=PageProducer1->Content(); Dołącz algorytm obsługi znaczników rozmieszczonych w szablonie strony: - Wygeneruj szkielet metody obsługi zdarzenia OnHTMLTag dla komponentu PageProducer. - Wpisz kod metody: void fastcall TForm1::PageProducer1HTMLTag(TObject *Sender, TTag Tag, const UnicodeString TagString, TStrings *TagParams, UnicodeString &ReplaceText) if (TagString=="teraz") ReplaceText=DateTimeToStr(Now()); else if (TagString=="p1") ReplaceText=SQLDataSet1->Fields->Fields[0]->FieldName+" : " + SQLDataSet1->Fields->Fields[0]->AsString + "<BR>"; else if (TagString=="p2") ReplaceText=SQLDataSet1->Fields->Fields[1]->FieldName + " : " + SQLDataSet1->Fields->Fields[1]->AsString + "<BR>"; else if (TagString=="p3") ReplaceText=SQLDataSet1->Fields->Fields[2]->FieldName + " : " + SQLDataSet1->Fields->Fields[2]->AsString + "<BR>"; else if (TagString=="p4") ReplaceText=SQLDataSet1->Fields->Fields[3]->FieldName + " : " + SQLDataSet1->Fields->Fields[3]->AsString + "<BR>"; else if (TagString=="p5") if ( SQLDataSet1->Fields->Fields[3]->Value>125) ReplaceText="Uwaga! Skok długi"; else ReplaceText=""; Uwaga: wykorzystanie funkcji DaysBetween wymaga dołączenia (w pliku nagłówkowym) modułu DateUtils Przetestuj działanie programu. Program powinien po naciśnięciu przycisku pierwszego wyświetlać w komponencie Memo zapis strony wygenerowanej na podstawie szablonu i uzupełnionej odpowiednimi zapisami wstawionymi w miejsce znaczników. Po naciśnięciu 4
przycisku drugiego program powinien wyświetlać w przeglądarce internetowej zawartość jednego wiersza (pierwszego) tabeli utworzonej przez zapytanie. Uzupełnij zapis metody obsługi przycisku pierwszego o instrukcje (wpisane na początku metody): String szukaj; TLocateOptions Opts; Opts.Clear(); Opts << lopartialkey << locaseinsensitive; szukaj = InputBox("Podaj Nazwisko zawodnika","nazwisko",""); if (! SQLDataSet1->Locate("NAZWISKO", szukaj, Opts)) ShowMessage("Nie znaleziono nazwiska"); return; Zmiany powyższe umożliwiają wyświetlanie informacji o skoku wybranego zawodniku. W wyświetlanym funkcją InputBox okienku należy podawać nazwę towaru (wystarczą pierwsze litery). Przenieś zapis szablonu strony do pliku SZABLON.HTML (utworzonego w katalogu projektu) kasując jednocześnie jego zapis we właściwości HTMLDoc komponentu PageProducer. We właściwości HTMLFile tego komponentu wskaż plik szablonu. Sprawdź, że po tych zmianach aplikacja działa identycznie. Przy takiej konfiguracji dla dokonania zmian w zapisie strony wystarczy odmiennie zredagować szablon zmiany kodu źródłowego aplikacji ani nawet powtórna kompilacja nie są wymagane. Zmień zapis szablonu strony w pliku SZABLON.HTML w taki sposób żeby dodatkowo wyświetlana była wysokość ceny detalicznej (z marżą 20 proc) wstaw w odpowiednim miejscu znacznik: <#p7 marza=20>. Taki zapis znacznika powoduje wykonanie obliczeń ceny detalicznej dla wartości parametru marża równej 20. Sprawdź działanie aplikacji. ZADANIA 1. Zmodyfikuj aplikację z katalogu P2 w taki sposób by po naciśnięciu dodatkowego przycisku generować stronę z zapisem całej tabeli ZAWODNICY. 2. Zmodyfikuj aplikację z katalogu P3 w taki sposób by w informacjach wyświetlanych znalazła się wartość sumy not zawodnika. 3. Opracuj aplikację która wyświetla zawartość tabeli DRUZYNY z wykorzystaniem komponentu PageProducer. Do redagowania zawartości wiersza tabeli wykorzystaj komponent DataSetPageProducer. Wskazówka: Rozmieszczone w szablonie HTML tego komponentu znaczniki o postaci <#NazwaPola> - gdzie NazwaPola jest identyfikatorem pola dołączonej do komponentu tabeli - są interpretowane automatycznie bez żadnych dodatkowych zabiegów. Ich wystąpienia zastępowane są wartościami pól pobieranymi z bieżącego rekordu tabeli. 4. Opracuj podobną aplikację z wykorzystaniem komponentu DataSetTableProducer. Wskazówka: Przeznaczenie poszczególnych właściwości komponentu: Caption DataSet Header kod HTML opisujący tytuł wyświetlanej tabeli komponent reprezentujący wyświetlaną tabelę HTMLowy zapis strony przed wyświetlaną tabelą 5
Footer HTMLowy zapis strony za wyświetlaną tabelą MaxRows liczba wyświetlanych wierszy (-1 =wszystkie) Właściwości obiektowe: RowAttributes definiuje wygląd wierszy np. kolor zielony przez ustawienie właściwości: bgcolor=lime TableAttributes definiuje wygląd całej tabeli np. kolor niebieski (tylko dla nagłówka i obramowania bo wiersze będą zielone) szerokość równą 70% oraz wyśrodkowanie tabeli poprzez: bgcolor=blue, Width=70, Align=haCenter, Columns obsługiwana przez specjalizowany edytor właściwość pozwalająca na precyzyjne zdefiniowanie poszczególnych kolumn. W czasie ustawiania parametrów edytor na bieżąco wyświetla podgląd tabeli co pozwala na szybką korektę ewentualnych błędów. 6