Tipy a triky v Delphi, díl 9.

Stahování souborů z internetu, zjišťování stavu připojení či získávání informací z registru Windows. To jsou hlavní témata dnešního dílu.
Download souborů

V dnešních aplikacích se již pomalu stává standardem nabídnout uživateli možnost stažení nové verze programu z domovských stránek produktu. Nebudeme se teď zabývat problémem, jak zjistit, zda verze na webu je novější než ta, kterou máme nainstalovanou. To si necháme pro některý z příštích dílů seriálu. Dnes se podíváme na to, jak funguje samotné stažení daného souboru. Budeme potřebovat v podstatě pouze dva parametry, jedním je přesná adresa souboru a druhým je místo na disku, kam se soubor uloží. Nejprve přidejte do Uses knihovny URLMon a ShellApi, které budeme potřebovat. Vlastní funkce bude vypadat takto:

.
.
.
Uses URLMon, ShellApi;
.
.
.

function DownloadFile(Zdroj, Cil: string): Boolean;
begin
try
  Result := UrlDownloadToFile(nil, PChar(Zdroj), PChar(Cil), 0, nil) = 0;
except
  Result := False;
end;
end;

Opravdu velmi jednoduché. Funkci můžeme použít například v události po stisku tlačítka takto:

procedure TForm1.Button1Click(Sender: TObject);
const
ZdrojovySoubor = `/soubor.exe`;
CilovySoubor  = `c:\soubor.exe`;
begin
  if DownloadFile (ZdrojovySoubor, CilovySoubor) then ShowMessage(`Stažení souboru bylo úspěšné`)
  else ShowMessage (`Chyba při stahování souboru ` + SourceFile)
end;

Po stisknutí tlačítka dojde k pokusu o stažení souboru. Pokud bude spojení úspěšně navázáno a započne samotné stahování, bude program čekat na dokončení akce. Po stažení se zobrazí příslušný dialog nebo informace o chybě.

Jak otestovat, zda jsme online ?

Způsobů je poměrně dost, jejich funkčnost a univerzálnost je různá. Ukážeme si teď dva způsoby. Jeden je opravdu superkrátký na jeden řádek, druhý pracuje s registry. Oba jsou otestovány pod systémem Windows 98 pro běžné modemové spojení.

První způsob:

K němu je potřeba knihovna WinInet, takže opět nezapomeňte přidat do Uses. Samotná funkce vrací True, pokud jsme připojeni, False pokud nejsme.

function Online : boolean;
begin
result := (InternetGetConnectedState(nil, 0))
end;

Druhý způsob:

V tomto případě zase využijeme služeb knihoven StdCtrls a Registry. Stejně jako v předchozím příkladu nám funkce vrátí True nebo False podle stavu připojení.

function Online : boolean;
var
  reg  : TRegistry;
  buff : dword;
begin
  reg:= tregistry.Create ;
  Reg.RootKey:=HKey_local_machine;
  if reg.OpenKey(`\System\CurrentControlSet\Services\RemoteAccess`,false) then
  begin
    reg.ReadBinaryData(`Remote Connection`,buff,sizeof(buff));
    result := buff = 1;
    reg.CloseKey ;
    reg.Free ;
  end;
end;

Jméno uživatele a společnosti, verze Windows

Když jsme se už dnes trochu zabývali registry, nebudeme je ještě hned opouštět a ukážeme si, jak získat některé informace o systému. V registrech Windows je těchto informací obrovská spousta a zjistit se dá téměř cokoliv. Pro příklad si ukážeme, jak zjistit jméno registrovaného uživatele (to jméno, které se zadává při instalaci systému, neplést s uživatelským jménem), název společnosti, jméno a verzi systému. Příklad je dostatečně názorný a pokud budete chtít, není problém dané položky nahradit jinými (které Vás třeba zajímají více). Stačí jen najít v registrech danou větev a položku. K tomu můžete použít například program Editor registru dodávaný s Windows. Pokud náhodou nevíte, kde jej najít a jak ho spustit (protože není uveden ve Start menu ani nikde jinde), najdete ho v adresáři Windows pod názvem Regedit.exe

Nemusím snad připomínat (a určitě jste toto varování slyšeli mnohokrát), že musíte dávat pozor, co děláte a neměnit položky, o kterých nevíte co znamenají, protože byste mohli napáchat celkem dost škod včetně totálního zlikvidování systému. :)

Pomocí výše zmíněného programu však můžete registry pohodlně a bezpečně procházet a hledat zajímavé větve, které pak můžete použít pro náš příklad. Ten je udělán tak, že informace pouze čte a nic nezapisuje, takže žádné nebezpečí nehrozí. Nyní již však k naší ukázce:

procedure TForm1.Button1Click(Sender: TObject);
var key:string;
    Reg: TRegIniFile;
    uzivatel,spolecnost,system,verze:string;
begin
key:=`\Software\Microsoft\Windows\CurrentVersion`;
Reg:=TRegIniFile.Create;
try
Reg.RootKey:=HKey_Local_Machine;
if Reg.OpenKey(key,False) then
  begin
  uzivatel:=`Uživatel: `+Reg.ReadString(key,`RegisteredOwner`, ``);
  spolecnost:=`Společnost: `+Reg.ReadString(key,`RegisteredOrganization`, ``);
  system:=`Systém: `+Reg.ReadString(key,`ProductName`, ``);
  verze:=`Verze: `+Reg.ReadString(key,`VersionNumber`, ``);
  ShowMessage(uzivatel+#13+spolecnost+#13+system+#13+verze);
  end;
finally
Reg.Free;
end;
end;

Jak vidíte, jedná se opět o událost stisku tlačítka. Dojde k pokusu o načtení dat a pokud vše proběhne v pořádku, zobrazí se dialog s hledanými daty.

Takto získané informace můžete například klasicky použít v okně "O aplikaci..." Vašeho programu.

Delay ve Windows ? Není problém

Na závěr si ukážeme jeden tip, který možná profesionální programátory rozesměje (nebo rozzlobí a budou hned psát reakce, co že je to zase za hrůzu). Oč se jedná? Pokud přecházíte poprvé z programování pro DOS na Windows a byli jste zvyklí v Turbo (Borland) Pascalu často používat příkaz Delay na pozastavení běhu programu, možná vás překvapilo že pod Windows není. Správně byste se měli podobným příkazům pod Windows vyhnout, protože je celá koncepce programu postavena na odlišných základech. Přesto se však může někdy hodit (třeba při převodu starších programů z DOSu pod Windows, dokud jej celý nepředěláte a podobně). Jedna z možností je prostě nahradit příkaz Delay příkazem Sleep, jehož parametrem je taktéž doba pauzy v ms. Téhož se dá dosáhnout i jednoduchou procedurou, kterou si napíšeme.

procedure Delay(ms : integer);
var
kdy : integer;
begin
kdy := GetTickCount + ms;
while GetTickCount < kdy do Application.ProcessMessages;
end;

Takto dosáhneme nejen požadované pauzy, ale zároveň nedojde k "zamrznutí" systému na daný interval (pomocí Application.ProcessMessages).

Diskuze (9) Další článek: Dell uvedl na trh nový typ počítače Dimension 8200

Témata článku: , , , , , , , , , , , ,