Delphi __ Kompendium __ Roz11.pdf

(1764 KB) Pobierz
Delphi :: Kompendium :: Roz...
Delphi :: Kompendium :: Rozdział 11 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_11
Logowanie | Rejestracja | Forum | Pomoc | Reklama | Szukaj
Strona główna :: Delphi :: Kompendium
Rozdział 11
Edytuj
Historia
Delphi
Artykuły
Kompendium
Gotowce
FAQ
.NET
Turbo Pascal
FAQ
PHP
FAQ
Java
FAQ
C/C++
Artykuły
FAQ
C#
Wprowadzenie
Assembler
FAQ
(X)HTML
CSS
JavaScript
Z pogranicza
Algorytmy
WIĘCEJ »
Aplikacje sieciowe
Czy nie zauważyłeś, drogi Czytelniku, że programy, z których korzystamy na co dzień, posiadają coraz więcej
opcji umożliwiających integrację z serwerami producenta? Programy sprawdzają, czy w Internecie jest już
dostępna nowa wersja , umożliwiają aktualizację modułów, a nawet ?szpiegowanie? Twojego komputera. W
tym rozdziale zajmiemy się wykorzystaniem dostępnych w Delphi komponentów, aby choć trochę usprawnić
działanie naszych programów.
Spis treści
1 Z czego będziemy korzystać?
2 Odrobinę teorii
2.1 IP
2.2 TCP
2.3 Porty
2.4 HTTP
2.5 HTTPS
2.6 FTP
2.7 SMTP
3 Biblioteka WinInet.dll
3.1 Ustanawianie połączenia
3.2 Otwieranie konkretnego adresu URL
3.3 Odczyt pliku
3.4 Pobieranie rozmiaru pliku
4 Sprawdzanie połączenia
5 Sprawdzanie IP
5.1 Zainicjowanie biblioteki
5.2 Pobieranie adresu IP
6 Łączenie przy użyciu gniazd
6.1 Czego użyć?
6.2 Łączenie pomiędzy komputerami
6.3 Wymiana danych
6.3.1 Tworzenie komend
6.4 Jak działają ?konie trojańskie??
7 Pingi
7.1 Wysyłanie sygnału ping
7.2 Odpowiedzi z serwera
8 Kontrolka TWebBrowser
8.1 Ładowanie strony
8.2 Odświeżanie
8.3 Następna i poprzednia strona
8.4 Pozostałe kody
8.4.1 Wyświetlanie adresu załadowanej strony
8.4.2 Wyświetlanie tytułu strony
8.4.3 Sprawdzenie, czy strona jest chroniona (SSL)
8.4.4 Ustawienie koloru tła strony
9 Protokół SMTP
9.1 Interfejs programu
9.2 Działanie programu
9.3 Zdarzenia komponentu
9.3.1 Kod źródłowy
10 Protokół HTTP
10.1 Łączenie z serwerem
10.2 Wymiana danych
10.2.1 Metoda POST
10.2.2 Metoda GET
10.3 Pobieranie kodu strony WWW
10.4 Wysyłanie danych przez skrypt PHP
10.4.1 Wysyłanie danych do skryptu PHP
11 Praktyczne przykłady wykorzystania HTTP
11.1 Sprawdzenie nowej wersji programu
11.1.1 Jak to działa?
11.1.2 Budowa programu
11.2 Korzystanie z zewnętrznej wyszukiwarki
11.2.1 Jak to działa?
11.2.2 Struktura kodu HTML
11.2.3 Analiza kodu HTML
11.2.4 Kod źródłowy programu
12 Protokół FTP
13 Podsumowanie
Delphi
C/C++
Turbo Pascal
Assembler
PHP
Programy
Dokumentacja
Kursy
Komponenty
WIĘCEJ »
W tym rozdziale:
omówię zasady działania najpopularniejszych protokołów sieciowych;
dowiesz się, jak wykrywać, czy istnieje połączenie internetowe;
napiszesz program służący do pobierania plików z Internetu;
nauczysz się obsługiwać protokół SMTP i wysyłać e-maile;
dowiesz się, jak ? korzystając z protokołu HTTP ? wysyłać dane do skryptów lub odczytywać zawartość
strony WWW.
1 z 25
2009-03-14 15:41
77981395.009.png 77981395.010.png 77981395.011.png 77981395.012.png 77981395.001.png 77981395.002.png
Delphi :: Kompendium :: Rozdział 11 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_11
Z czego będziemy korzystać?
RSS | Forum | Pastebin |
Regulamin | Pomoc | Usuń
cookies | Prawa autorskie |
Kontakt | Reklama
Windows posiada bibliotekę DLL o nazwie WinSock.dll , która realizuje bardzo wiele czynności związanych z
dostępem do Internetu. Wykorzystanie funkcji z owej biblioteki może być trochę trudne, dlatego nie warto
wyważać otwartych drzwi ? można skorzystać z komponentów oferowanych nam przez firmę Borland.
W zakładce Internet znajdują się np. takie komponenty, jak TTcpClient i TTcpServer , przeznaczone do
łączenia się ze sobą za pomocą protokołu TCP/IP. Na tej samej zakładce znajduje się także komponent
TudpSocket do łączenia się za pomocą protokołu UDP/IP. Zrezygnowano natomiast z komponentów, do których
wiele ludzi mogło się już przyzwyczaić ? TClientSocket oraz TServerSocket . Teraz ich funkcję mają pełnić
właśnie komponenty TTcpClient i TTcpServer .
Copyright © 2000-2006 by Coyote Group 0.9.3-pre3
Czas generowania strony: 2.8404 sek. (zapytań SQL:
11)
Do Delphi dołączony jest bardzo popularny pakiet komponentów Indy, ułatwiających wykorzystanie różnych
protokołów sieciowych. Do obecnej wersji Delphi dołączono Indy 9, w efekcie czego powstało pięć nowych
zakładek: Indy Clients , Indy Servers , Indy Intercepts , Indy I/O Handlers i Indy Misc . Komponenty te
udostępniane są na zasadzie Open Source. Najnowszą wersję możesz znaleźć na stronie
www.nevrona.com/Indy/.
Nie musimy korzystać wyłącznie z pakietu Indy ? ze strony www.overbyte.be możemy
ściągnąć równie popularny pakiet ICS, stworzony przez belgijskiego programistę François
Piette. Zdaniem wielu programistów pakiet ICS jest lepszy od Indy, lecz nieco trudniejszy w
użytkowaniu.
Odrobinę teorii
Internet jest pełen fachowych określeń i niezbyt zrozumiałych skrótów. Dla zwykłego, ?szarego? użytkownika
nie jest istotne, co oznacza i jak działa IP czy protokół TCP. Rozpoczynając pisanie aplikacji korzystających z
Internetu, powinieneś być zorientowany przynajmniej w podstawach funkcjonowania protokołów
internetowych. Dlatego też parę najbliższych stron poświęcimy omówieniu podstawowych zagadnień z tym
związanych.
Jeżeli Cię to nie interesuje lub znasz zasadę działania protokołów internetowych, to możesz śmiało ominąć te
strony.
IP
Z pojęciem adres IP zetknąłeś się pewnie nieraz. Jest to skrót od angielskiego słowa Internet Protocol .
Najprościej mówiąc, adres IP jest to adres komputera w sieci. Internet to ?pajęczyna?, w której połączonych
jest wiele komputerów. IP jest 32-bitową liczbą, informującą, do jakiej sieci włączony jest dany komputer.
Liczba ta zapisywana jest w postaci czterech liczb, oddzielonych od siebie kropką. Przykładowy adres IP
wygląda np. tak: 223.125.100.155. Adresy IP podzielone są na klasy ? patrz tabela 11.1.
Tabela 11.1. Klasy IP
Klasa Najmniejszy adres Największy adres
A 0.1.0.0
126.0.0.0
B 128.0.0.0
191.255.0.0
C 192.0.1.0
223.255.255.0
D 224.0.0.0
239.255.255.255
E 240.0.0.0
247.255.255.255
Tabela 11.1 nie zawiera jednak m.in. adresów IP od 127.0.0.0 do 127.255.255.255. Powód jest prosty ? są to
adresy lokalne, które nie istnieją w Internecie.
W celu zapewnienia zgodności adresy są przydzielane przez jedną organizację o nazwie Internet Network
Information Center. Organizacja przydziela adresy wielkim sieciom, które z kolei rozdzielają przyznane adresy
między swoich użytkowników.
Ilość komputerów w sieci stale rośnie. Aby każdemu z nich zagwarantować stały, niepowtarzalny numer,
trzeba było rozbudować protokół IP ? nowa wersja nosi nazwę IPv6. Wykorzystywane w niej są liczby
128-bitowe, a nie ? jak dotychczas ? 32-bitowe.
TCP
Protokół TCP (ang. Transmission Control Protocol ) jest drugą co do ważności usługą w sieci (po IP). Polega ona
na przesyłaniu danych (pakietów) pomiędzy dwoma komputerami. Połączenie z dwoma komputerami odbywa
się poprzez podanie adresu IP. Wtedy jeden z komputerów na podstawie adresu IP oraz portu (o portach czytaj
dalej) łączy się z drugim komputerem. Protokół TCP jest często nazywany niezawodną usługą przesyłania
danych ? dlatego, że po wysłaniu pakietu komputer czeka na otrzymanie potwierdzenia, tzw. ACK (patrz
rysunek 11.1).
Rysunek 11.1. Zasada wysyłania pakietów TCP/IP
2 z 25
2009-03-14 15:41
77981395.003.png 77981395.004.png
Delphi :: Kompendium :: Rozdział 11 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_11
Jeżeli komputer nie otrzyma potwierdzenia ACK, czeka określoną ilość czasu, po czym uznaje, iż pakiet nie
dotarł ? następuje przesyłanie po raz kolejny.
Na TCP opiera się wiele innych protokołów ? np. FTP czy SMTP. Także sieci lokalne LAN korzystają z tego
protokołu.
Porty
Komputer, który próbuje się połączyć z innym komputerem, to klient. Natomiast komputer po drugiej stronie,
który oczekuje na przyłączenie klienta, jest nazywany serwerem. Jednak na jednym komputerze może być
uruchomionych wiele aplikacji ? skąd mamy wiedzieć, do której klient chce się połączyć? Do tego służą porty,
które stanowią swoiste ?furtki?. Jest to liczba z zakresu od 1 do 65 000; gdy chcemy się połączyć z innym
komputerem, wraz z adresem IP musimy podać numer portu. Tak więc port aplikacji klienta oraz aplikacji
serwera musi być taki sam, aby doszło do połączenia.
HTTP
Niezwykle popularny protokół HTTP ( Hyper-Text Transfer Protocol ) służy do transmisji stron internetowych
WWW z serwera do przeglądarki. Na podstawie wpisanego w przeglądarce adresu następuje lokalizacja adresu
IP serwera (adres IP jest ustalany na podstawie domeny) ? stamtąd przesyłane są informacje do przeglądarki
użytkownika. Możliwe jest zwrócenie przez serwer komunikatu o błędzie ? np. błąd o numerze 404 to brak
strony, którą próbujemy załadować. W tabeli 11.2 przedstawiłem najczęstsze numery błędów.
Tabela 11.2. Numery błędów HTTP
Numer błędu Opis
200 OK
206 Częściowa zawartość
301 Przeniesiono na stałe
302 Przeniesiono tymczasowo
304 Niezmodyfikowany
400 Błędne żądanie
403 Zakazane (brak dostępu)
404 Brak strony
405 Nieuznawania metoda
412 Warunki niespełnione
500 Błąd serwera
HTTPS
Protokół HTTP może nie zapewniać wystarczającego poziomu bezpieczeństwa dla szczególnie ważnych operacji
internetowych ? np. zakupów, operowania pieniędzmi w bankach itp. HTTPS jest rozbudowaną wersją protokołu
HTTP, umożliwiającą szyfrowanie danych przepływających z komputera klienta do serwera WWW i odwrotnie.
Takie szyfrowanie nosi nazwę SSL ( Secure Socket Layer ). To, czy strona jest szyfrowana, czy też nie, określa
adres internetowy ? adresy stron wykorzystujących SSL zaczynają się od https://.
FTP
FTP to skrót od angielskiego słowa File Transfer Protocol . Jest to niezwykle stary protokół, obecny praktycznie
od początku istnienia Internetu. Polega on na połączeniu dwóch komputerów na zasadzie klient-serwer.
Połączenie zazwyczaj odbywa się poprzez port 21. (popularne usługi, np. FTP, zawsze mają taki sam port, aby
wystarczyło znać tylko sam adres). Tak więc klient łączy się z danym komputerem w wyniku podania jego
adresu IP. Po połączeniu może odbywać się dwustronna komunikacja na zasadzie przesyłania plików.
SMTP
Jeżeli korzystasz z Internetu, to pewnie nieraz słyszałeś o tym protokole. Służy on do wysyłania listów
elektronicznych. Komunikacja odbywa się na zasadzie klient-serwer ? klient łączy się z określonym adresem IP
przez określony port (zazwyczaj 25.). Wysyła do serwera komendę MAIL, po czym, gdy otrzyma odpowiedź,
następuje transmisja listu do serwera (najpierw nagłówek, a potem treść wiadomości). Niektóre serwery
wymagają tzw. autoryzacji. Zabezpieczają się w ten sposób przed wysyłaniem spamu. Przy zakładaniu konta
pocztowego ? niezależnie od tego, na którym serwerze ? musimy podać nazwę użytkownika (login) oraz hasło.
Podczas konfiguracji programu pocztowego należy wpisać w odpowiednie pola obie te wartości. Podczas
połączenia te dane przesyłane są do serwera; serwer sprawdza, czy są prawdziwe (tj. czy taka skrzynka e-mail
jest rzeczywiście założona na tym serwerze) i, jeżeli wszystko się powiedzie, odbywa się transmisja.
Biblioteka WinInet.dll
Na samym początku tego rozdziału zaczniemy od korzystania z biblioteki WinInet.dll , a nie z komponentów. To
może być trudny początek, gdyż korzystanie z biblioteki WinInet.dll wcale nie jest takie proste. To dlatego tak
popularne są pakiety komponentów w stylu Indy, gdyż ułatwiają znacznie pracę z programem. Chciałbym
jednak pokazać, na czym opiera się tworzenie programów z użyciem tej biblioteki, gdyż ogólnie dostępne
informacje na ten temat są raczej skąpe. Przy okazji czytania tego rozdziału napiszemy program umożliwiający
pobieranie plików z Internetu (rysunek 11.2).
Rysunek 11.2. Program pobierający plik z Internetu
Do skorzystania z funkcji biblioteki WinInet.dll będzie Ci potrzebny moduł WinInet.pas ?
dodaj jego nazwę do listy modułów uses.
Ustanawianie połączenia
W celu zainicjowania biblioteki Wininet.dll będziemy musieli skorzystać z funkcji InternetOpen :
3 z 25
2009-03-14 15:41
77981395.005.png
Delphi :: Kompendium :: Rozdział 11 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_11
function InternetOpen ( lpszAgent: PChar ; dwAccessType: DWORD;
lpszProxy, lpszProxyBypass: PChar ; dwFlags: DWORD ) : HINTERNET; stdcall ;
Znaczenie poszczególnych parametrów jest następujące:
lpszAgent ? nazwa programu (przeglądarki), jaka będzie identyfikowana przez serwer.
dwAccessType ? dostęp do sieci Internet ? patrz tabela 11.3.
lpszProxy ? serwer pośredniczący (proxy), z którym będziemy się łączyli.
lpszProxyBypass ? lista adresów IP, które z jakiegoś powodu nie powinny mieć dostępu do serwera
proxy.
dwFlags ? dodatkowe flagi, używane wraz z połączeniem.
Tabela 11.3. Tryby dostępu do sieci Internet
Tryb
Opis
INTERNET_OPEN_TYPE_DIRECT
Połączenie lokalne
INTERNET_OPEN_TYPE_PRECONFIG
Typ połączenia oraz ewentualny adres serwera
proxy jest pobierany z rejestru
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY
Połączenie jest odczytywane z plików
systemowych Windows
INTERNET_OPEN_TYPE_PROXY
Połączenie poprzez serwer proxy
W naszym przypadku inicjowanie biblioteki może wyglądać w sposób następujący:
hSession := InternetOpen ( 'Fast Download' , INTERNET_OPEN_TYPE_PRECONFIG, nil , nil , 0 ) ;
Funkcja InternetOpen zwraca uchwyt sesji w postaci zmiennej hInternet ? ów uchwyt będzie nam potrzebny
w kolejnych operacjach. W ostatnim parametrze możesz dodać także flagę INTERNET_FLAG_FROM_CACHE , dzięki
której plik już raz pobrany będzie odczytywany z pamięci podręcznej ? tzw. cache?u.
Każda zmienna typu hInternet musi zostać zwolniona po zakończeniu korzystania. Realizuje to funkcja
InternetCloseHandle .
Otwieranie konkretnego adresu URL
Do odczytania konkretnego pliku będziemy musieli skorzystać z funkcji InternetOpenURL :
function InternetOpenUrl ( hInet: HINTERNET; lpszUrl: PChar ;
lpszHeaders: PChar ; dwHeadersLength: DWORD; dwFlags: DWORD;
dwContext: DWORD ) : HINTERNET; stdcall ;
W pierwszym parametrze będziemy musieli podać uchwyt uzyskany dzięki funkcji InternetOpen . Kolejny
parametr określa adres strony, którą próbujemy otworzyć. Kolejne dwa parametry są związane z nagłówkami,
które możemy wysłać. W naszym przykładzie nie będziemy wysyłać żadnych nagłówków, więc pozostawimy te
wartości puste ( nil i 0). Kolejny parametr może określać dodatkowe parametry połączenia ? np. połączenie za
pomocą trybu bezpiecznego (HTTPS) czy np. autoryzację. Przykład wywołania tej funkcji:
hURL := InternetOpenURL ( hSession, PChar ( URL ) , nil , 0 , 0 , 0 ) ;
Funkcja InternetOpenURL także zwraca uchwyt w postaci zmiennej hInternet , która będzie nam potrzebna w
czasie pobierania pliku.
Odczyt pliku
Wreszcie nadchodzi kolej na odczytanie pliku, tj. pobranie jego części i zapisanie na dysku. W tym celu
skorzystamy z funkcji InternetReadFile :
function InternetReadFile ( hFile: HINTERNET; lpBuffer: Pointer ;
dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD ) : BOOL; stdcall ;
Pobieranie pliku będzie następować partiami, po 1 kB każda. Pierwszy parametr musi zawierać wskazanie
(uchwyt) zmiennej typu hInternet . Wartość tę uzyskaliśmy w czasie wywoływania funkcji InternetOpenURL .
Kolejne dwa parametry są związane z buforem, który będzie przechowywać pobrane fragmenty pliku. Parametr
lpBuffer musi zawierać wskazanie bufora, a dwNumberOfBytesToRead rozmiar owego bufora (ilość danych,
które mają zostać pobrane). Ostatni parametr przekazuje ilość rzeczywiście odczytanych bajtów. Pobieranie
pliku z Internetu może wyglądać następująco:
AssignFile ( F, FileName ) ;
try
Rewrite ( F, 1 ) ;
repeat
if Broken then Break ;
{ pobieranie kolejnych fragmentów pliku }
InternetReadFile ( hURL, @Buffer, SizeOf ( Buffer ) , dwRead ) ;
BlockWrite ( F, Buffer, dwRead ) ; // zapisanie buforu w pliku
TotalRead := TotalRead + dwRead;
Application. ProcessMessages ;
{ wyświetlenie postępu }
lblProgress. Caption := 'Ściągam ' + IntToStr ( TotalRead div 1024 ) + ' kB z ' +
IntToStr ( dwSize div 1024 ) + ' kB' ;
ProgressBar. Position := TotalRead div 1024 ;
until dwRead = 0 ;
finally
CloseFile ( F ) ;
end ;
4 z 25
2009-03-14 15:41
77981395.006.png 77981395.007.png
Delphi :: Kompendium :: Rozdział 11 - 4programmers.net http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_11
Część z tych instrukcji na pewno jest Ci znana, chociażby z poprzednich rozdziałów dotyczących obsługi plików.
W skrócie można powiedzieć, że w powyższym kodzie w pętli następuje cykliczne odczytywanie fragmentów
pliku i przypisywanie ich zmiennej Buffor . Następnie zawartość tej zmiennej zostaje wstawiona do pliku.
Zakończenie operacji sygnalizuje zmienna dwSize , która przybiera wartość 0 w przypadku, gdy pobieranie
zostało zakończone.
Pobieranie rozmiaru pliku
W gruncie rzeczy z fragmentów kodów, które przedstawiłem wyżej, można by było skonstruować program do
ściągania plików. Żeby wszystko wyglądało lepiej, a program był bardziej użyteczny, będziemy musieli także
dowiedzieć się, jaki jest rozmiar pliku, który próbujemy pobrać. Pozwoli to nam ukazać na komponencie
TProgressBar postęp w ściąganiu pliku. Skorzystamy z funkcji HTTPQueryInfo , która umożliwia uzyskanie
wielu informacji na temat pliku (nazwa serwera, rozmiar, rodzaj pliku itp.):
function HttpQueryInfo ( hRequest: HINTERNET; dwInfoLevel: DWORD;
lpvBuffer: Pointer ; var lpdwBufferLength: DWORD;
var lpdwReserved: DWORD ) : BOOL; stdcall ;
W pierwszym parametrze musi się znaleźć uchwyt uzyskany w wyniku działania funkcji InternetOpenURL . Drugi
parametr musi zawierać flagę informującą o typie informacji, jaką chcemy uzyskać. My w naszym programie
musimy wpisać tutaj wartość: HTTP_QUERY_CONTENT_LENGTH . Uzyskana informacja jest zwracana w formie
wskaźnika:
dwBufLen := 1024 ;
dwIndex := 0 ;
GetMem ( pBuf, dwBufLen ) ;
{ pobranie informacji na temat wielkości pliku }
HttpQueryInfo ( hURL, HTTP_QUERY_CONTENT_LENGTH,
pBuf, dwBufLen, dwIndex ) ;
dwSize := StrToInt ( StrPas ( pBuf )) ;
ProgressBar. Max := ( dwSize div 1024 ) ;
FreeMem ( pBuf, dwBufLen ) ;
Ważne jest to, że parametry podawane w funkcji HTTPQueryInfo muszą być zmiennymi. Dlatego też
zadeklarowałem zmienne dwIndex i dwBufLen . Na początku należało przeznaczyć 1 kB pamięci na poczet
wskaźnika, który będzie zawierał informację o rozmiarze pliku. Po wykonaniu funkcji zmienna pBuf zawierała
informacje, które są nam potrzebne ? nie pozostało nic innego, jak przedstawić je w formie liczby (wartość
Integer) i zwolnić pamięć.
W listingu 11.1 znajduje się cały kod źródłowy programu.
Listing 11.1. Pobieranie pliku za pomocą biblioteki Wininet.dll
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
type
TMainForm = class ( TForm )
ProgressBar: TProgressBar;
btnDownload: TButton;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
edtURL: TEdit;
edtFile: TEdit;
lblProgress: TLabel;
procedure btnDownloadClick ( Sender: TObject ) ;
procedure FormClose ( Sender: TObject ; var Action: TCloseAction ) ;
private
Broken : Boolean ;
procedure Download ( const URL : String ; FileName : String ) ;
public
{ Public declarations }
end ;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
{ TMainForm }
uses WinInet;
procedure TMainForm. Download ( const URL: String ; FileName: String ) ;
var
Buffer : array [ 1 .. 1024 ] of Byte ; // bufor zawierający pobrany fragment pliku
hSession, hURL : HINTERNET;
dwRead : DWORD; // ilość odczytanych danych
dwSize : DWORD; // rozmiar pliku
F : File ;
pBuf : Pointer ;
dwBufLen : DWORD;
dwIndex : DWORD;
TotalRead : Integer ;
begin
{ otwieranie połączenia }
hSession := InternetOpen ( 'Fast Download' ,
INTERNET_OPEN_TYPE_PRECONFIG, nil , nil , 0 ) ;
Application. ProcessMessages ;
lblProgress. Caption := 'Łączenie z serwerem...' ;
5 z 25
2009-03-14 15:41
77981395.008.png
Zgłoś jeśli naruszono regulamin