Elektronickß poÜta v TCP/IP Φas¥ deviata


Praktick² prφklad v Delphi I

Doteraz ste sa mohli zoznßmi¥ podrobnejÜie s te≤riou okolo elektronickej poÜty, teraz nasleduje praktick² prφklad v jazyku Delphi. Rozoberieme ho podrobnejÜie. Na skompilovanie projektu budete potrebova¥ komponent SakEmail.1.10.0.zip. Tento komponent obsahuje rozhranie pre prßcu s elektronickou poÜtou.


Zaslanie sprßvy systΘmom elektronickej poÜty û telo sprßvy

Telo sprßvy m⌠₧e obsahova¥ len zßkladnΘ ASCII znaky 'A-Z', 'a-z', '0-9' a '/'. Ke∩₧e budeme posiela¥ aj binßrne s·bory, tieto je potrebnΘ transformova¥ do vhodnΘho formßtu. Na tento ·Φel aplikßcia vyu₧φva algoritmus base64, ktor² je definovan² v dokumente RFC 2045.

Zφskanie doruΦen²ch sprßv z e-mailovej schrßnky

DoruΦenΘ sprßvy s· umiest≥ovanΘ na disku poΦφtaΦa (server), na ktorom mß u₧φvate╛ zriaden· svoju poÜtov· schrßnku (MAILBOX). Na zφskanie doruΦen²ch sprßv z e-mailovej schrßnky a na ich prenesenie na lokßlny osobn² poΦφtaΦ pou₧ijeme komunikaΦn² protokol POP3. Prφkazy protokolu POP3 sa sprφstupnia vlo₧enφm ovlßdacieho prvku SakPOP, ktor² je s·Φas¥ou komponentu SakEmail, do programu. ╧alÜφm ovlßdacφm prvkom, ktor² bude vlo₧en² do programu je SakMsgList. Tento bude obsahova¥ vÜetky sprßvy zφskanΘ z e-mailovej schrßnky u₧φvate╛a, pomocou prφkazov protokolu POP3. Ak sprßva obsahuje nejakΘ binßrne s·bory, ktorΘ boli predt²m zak≤dovanΘ algoritmom base64; na tieto bude aplikovan² proces spΣtnΘho dek≤dovania, Φφm zφskame p⌠vodnΘ binßrne s·bory. Po prenesenφ sprßv zo serveru na osobn² poΦφtaΦ bud· vÜetky prenesenΘ sprßvy na serveri bu∩ ponechanΘ, alebo vymazanΘ. Toto zßvisφ od hodnoty subk╛·Φa Delete Messages, ktor² je definovan² v registri Windows pod k╛·Φom:

HKEY_CURRENT_USER\SOFTWARE\SimpleMail\Mailbox.

Zobrazenie doruΦen²ch sprßv

VÜetky sprßvy, ktorΘ bud· zφskanΘ z e-mailovej schrßnky u₧φvate╛a, bud· zobrazenΘ v ovlßdacom prvku TListView. Po kliknutφ na prφsluÜn· polo₧ku v ListView, sa zobrazφ text konkrΘtnej sprßvy a pripojenΘ s·bory. Sprßvy ktorΘ zφskate z VßÜho poÜtovΘho servera bud· ulo₧enΘ iba v pamΣti poΦφtaΦa, t.j. aplikßcia vo verzii 1.0 ich nezapisuje na lokßlny disk. Po ukonΦenφ programu bud· emailovΘ sprßvy nenßvratne vymazanΘ.

Inicializßcia programu

Z praktickΘho h╛adiska je potrebnΘ, aby si program pamΣtal niektorΘ d⌠le₧itΘ ·daje, naprφklad: adresu SMTP servera, adresu POP3 servera, meno u₧φvate╛a, e-mailov· adresu u₧φvate╛a programu a pod. Windows umo₧≥uje pou₧i¥ dve ÜtandardnΘ techniky ukladania stavov²ch informßciφ:

1. INI s·bory (v Delphi trieda TIniFile),
2. systΘmovΘ registre(v Delphi trieda TRegIniFile).

Preto₧e aj samotnß firma Microsoft doporuΦuje namiesto INI s·borov pou₧φva¥ systΘmovΘ registre aj nßÜ program ich bude pou₧φva¥. Nieko╛ko zßkladn²ch informßciφ o registroch: SystΘmov² register je v skratke hierarchicky usporiadanß databßza informßciφ o poΦφtaΦi a nainÜtalovanom programovom vybavenφ. Register Windows je zalo₧en² na Üiestich k╛·Φoch na najvyÜÜej ·rovni (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA). Ka₧dß aplikßcia si m⌠₧e pri inÜtalßcii vytvori¥ svoje vlastnΘ k╛·Φe do ktor²ch bude zapisova¥ alebo z nich Φφta¥ bu∩ re¥azce, celΘ Φφsla alebo logickΘ hodnoty. Pre prezeranie, editovanie a vytvßranie k╛·Φov existuje vo Windows Üpecißlny program s nßzvom Regedit. Tento program nenßjdete v menu, ale spustφte ho tak, ₧e kliknite na tlaΦidlo Start | Run a napφÜte prφkaz regedit.

Aplikßcia Simple Mail 1.0 bude obsahova¥ nasledovn· Ütrukt·ru k╛·Φa SimpleMail:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\SimpleMail]

[HKEY_CURRENT_USER\Software\SimpleMail\AddressBook]
"City"="65"
"EmailAddress"="169"
"Name"="212"
"Organization"="104"
"Phone"="97"

[HKEY_CURRENT_USER\Software\SimpleMail\AttachedFiles]
"1"=""
"2"=""
"3"=""
"count"="0"
"4"=""
"5"=""

[HKEY_CURRENT_USER\Software\SimpleMail\Mailbox]
"Login"=""
"SavePassword"="0"
"Password"=""
"Delete Messages"="0"

[HKEY_CURRENT_USER\Software\SimpleMail\Message]
"To"=""
"Subject"=""
"Cc"=""
"ReplyTo"=""
"PriorityMessage"="2"

[HKEY_CURRENT_USER\Software\SimpleMail\Path]
"Location File"=""

[HKEY_CURRENT_USER\Software\SimpleMail\Pop3]
"HostPop3"=""
"PortPop3"=""

[HKEY_CURRENT_USER\Software\SimpleMail\Smtp]
"HostSmtp"=""
"PortSmtp"=""

[HKEY_CURRENT_USER\Software\SimpleMail\Temp]
"Getmsg"="0"
"TestCancel"="1"
"Name"=""
"Organization"="-"
"EmailAddress"=""
"Phone"="-"
"City"="-"
"ButtonOK"="1"
"InsertItem"="0"
"Save Editor"=""
"SelectedEmailAddress"=""
"TestSelectedEmailAddress"="0"
"TestClose"="0"

[HKEY_CURRENT_USER\Software\SimpleMail\User]
"UserName"=""
"UserAddress"=""

Subk╛·Φ Temp obsahuje doΦasnΘ informßcie aplikßcie. Aplikßcia pou₧φva tieto polo₧ky pre doΦasnΘ uschovanie niektor²ch svojich parametrov (hodn⌠t premenn²ch, r⌠znych stavov a pod. ).

Subk╛uΦe Smtp a Pop3 obsahuj· adresy poÜtovΘho servera, ktor² umo₧≥uje komunikova¥ pomocou protokolov SMTP a POP3. Polo₧ky PortSmtp a PortPop3 definuj· komunikaΦnΘ porty t²chto protokolov. Obvykle pre Smtp je to port 25, pre POP3 port 110. Subk╛uΦ User obsahuje informßcie o u₧φvate╛ovi programu. Polo₧ka UserName definuje plne meno u₧φvate╛a (meno musφ by¥ zadnΘ bez interpunkΦn²ch znamienok), polo₧ka UserAddress obsahuje e-mailov· adresu u₧φvate╛a.

Subk╛·Φ Mailbox obsahuje ·daje o poÜtovej schrßnke. Polo₧ka Login definuje prihlasovacie meno u₧φvate╛a, Password û prihlasovacie heslo u₧φvate╛a a SavePassword obsahuje ·daj o tom Φi sa mß heslo zapamΣtßva¥. POZOR! Ak pou₧ijete vo╛bu SavePassword, vystavujete sa riziku, ₧e niekto m⌠₧e zφska¥ vaÜe heslo. Heslo sa zatia╛ ukladß len ako postupnos¥ zadan²ch znakov, t.j. bez Üifrovania. Delete Messages obsahuje hodnotu 1 ak sprßvy maj· zosta¥ v poÜtovej schrßnke, inak obsahuje hodnotu nula. Hodnota 0 znamenß, ₧e po zφskanφ sprßv z poÜtovej schrßnky, bud· tieto na zadanom poÜtovom servery vymazanΘ.

Subk╛·Φ AddressBook obsahuje informßcie o Üφrke stσpcov polo₧iek Name, Organization, EmailAddress, Phone, City.

Subk╛·Φ AttachedFiles sl·₧i na ulo₧enie informßciφ o pripojen²ch s·boroch, konkrΘtne ide o ich poΦet (count) a kompletn· cestu na lokßlnom poΦφtaΦi.

Subk╛·Φ Path obsahuje cestu k projektu aplikßcie. Pri spustenφ projektu z inΘho disku treba t·to cestu zmeni¥.

Evidovanie e-mailov²ch adries

U aplikßciφ tohto typu sa be₧ne vyskytuje mechanizmus na zapamΣtßvanie emailov²ch adries. Aplikßcia bude na zßznam adries pou₧φva¥ s·bor AddressBook.txt, ktor² sa nachßdza v adresßri aplikßcie, v podadresßri Address. S·bor bude ma¥ nasledovn· Ütrukt·ru:

Counted record: 1
Chip
Vogel Burda Communications
chip@chip.cz
-
Cech Republic
%

Prv² riadok s·boru v₧dy obsahuje informßciu o poΦte zaznamenan²ch emailov²ch adries. ╧alej nasleduj· zßznamy v tomto poradφ: Meno, organizßcia, emailovß adresa, telef≤n a mesto. Pokia╛ niektor² zßznam nie je zadan², program doplnφ na toto miesto znak "-". JednotlivΘ zßznamy v tomto s·bore s· od seba oddelenΘ znakom "%". S·bor je limitovan² na 500 zßznamov emailov²ch adries.

Popis zdrojovΘho k≤du

Zdrojov² k≤d sa skladß z nasleduj·cich Φastφ: Projekt1, AddItem, AddressBook, MailBox, New_Txt_Message, Preferences, SendMessage, Window_AboutBox, SakEmail, sak_util. V nasleduj·com texte sa dozviete viac. ZaΦneme t²m najjednoduchÜφm s·borom - Window_AboutBox.

Unit Window_AboutBox.pas
AboutBox je okno ktorΘ mß za cie╛ iba informova¥ u₧φvate╛a o nßzve, autorovi, verzii programu, prφpadne o pou₧it²ch moduloch. Unit obsahuje dve proced·ry. Proced·ra Start_Window_AboutBox zobrazφ okno na obrazovku, proced·ra TAboutBox.Panel1Click zatvorφ okno ak kliknete mimo text, ktor² sa v oknenachßdza.

Unit Preferences.pas
procedure TPreferences2.FormCreate(Sender: TObject);
begin

// Inicializßcia k╛·Φa
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');

// Na Φφtanie icon pre tlaΦidlß Apply a Cancel, tieto icony
// sa nachßdzaj· v s·bore Bitmap.res
IconApply.Glyph.Handle:=LoadBitmap(HInstance,'002OK');
IconCancel.Glyph.Handle:=LoadBitmap(HInstance,'001CANCEL');

// ╚φtanie nastavenφ z registra Windows
LoadPreferences;
end;

Procedura LoadPreferences naΦφta pri otvorenφ okna ·daje zaznamenanΘ v registroch; Procedure SavePreferences zase ulo₧φ ·daje do registra Windows.

procedure TPreferences2.ApplyClick(Sender: TObject);
begin

// Inicializßcia k╛·Φa
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');

// Ulo₧enie nastavenφ do registra Windows
SavePreferences;

// ZapφÜe do registra Windows - do k╛·Φa æTemp' subk╛·Φa
// 'TestCancel' hodnotu '0', ktorß vyjadruje, ₧e bolo stlaΦenΘ
// tlaΦidlo Apply.

IniFile.WriteString('Temp','TestCancel', '0');
IniFile.Destroy;

// Zatvorenie okna
Close;
end;

Proced·ry RadioButton1Click(Sender: TObject); a₧ RadioButton5Click(Sender: TObject); sa pou₧φvaj· pri v²bere priority posielanej sprßvy. Proced·ra CancelClick(Sender: TObject); zatvorφ okno, ale pretφm eÜte zapφÜe do registra Windows - do k╛·Φa æTemp' subk╛·Φa 'TestCancel' hodnotu '1', ktorß vyjadruje, ₧e bolo stlaΦenΘ tlaΦidlo Cancel.

Unit New_Txt_Message.pas
Proced·ra Add1Click (Sender: TObject); umo₧≥uje do zßlo₧ky Attached Files v okne Create Text Message prida¥ s·bor k posielanej sprßve, proced·ra Delete1Click (Sender: TObject); sa pou₧φva na vymazanie konkrΘtneho s·boru z boxu Attached Files a proced·ra Clear1Click (Sender: TObject); vyma₧e cel² box. Proced·ra SendMsg1Click (Sender: TObject); sa pou₧φva na odoslanie napφsanej sprßvy na poÜtov² server.

procedure TCreateTxt1.SendMsg1Click(Sender: TObject);
var
i : integer;
test1, route : string;

begin

// Otvorenie k╛uΦa SimpleMail
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');

// Test na vyplnenie ·dajov Subject a To, ak niektor² z
// ·dajov nie je vyplnen² zobrazφsa chybovΘ hlßsenie.
if (EditTo.Text='') or (EditSubject.Text='') then
begin
MessageBeep(MB_ICONEXCLAMATION);
MessageDlg('Field To: or Subject: is empty.',mtError,[mbOk], 0);
end
else
begin

// Inak sa zadanΘ ·daje zapφÜu do registra Windows
IniFile.WriteString ('Message','To',EditTo.Text);
IniFile.WriteString ('Message','Subject',EditSubject.Text);
IniFile.WriteString ('Message','Cc',EditCc.Text);
IniFile.WriteString ('Message','ReplyTo',EditReplyTo.Text);
IniFile.WriteString ('AttachedFiles','count',IntToStr(ListBoxAttachedFiles.Items.count));

route := IniFile.ReadString('Path','Location File', route);
MemoTextMsg.Lines.SaveToFile(route+'\Temp\working.tmp');

// Test na pripojenΘ s·bory AttachedFiles
if ListBoxAttachedFiles.Items.count<>0 then
begin
for i:= 0 to ListBoxAttachedFiles.Items.count-1 do
begin
IniFile.WriteString ('AttachedFiles',IntToStr(i+1),ListBoxAttachedFiles.Items[i]);
end;
end;

// Ak s· potrebnΘ ·daje zadanΘ, zobrazφ sa okno
// Send Message na odoslanie sprßvy
with TSend1.Create(Application) do
try
ShowModal;
finally
Free;
end;

test1:=IniFile.ReadString ('Temp','TestClose',test1);
// Ak sa programu podarφ bezchybne odosla¥
// sprßvu okno Create Text Message sa
// automaticky uzatvorφ
if test1='1' then
begin
IniFile.WriteString ('Temp','TestClose','0');
close;
end;
end;
end;

Proced·ra Options2Click (Sender: TObject); zobrazφ okno Preferences, v ktorom sa nastavuj· d⌠le₧itΘ parametre aplikßcie. Proced·ra Address1Click (Sender: TObject); zobrazφ okno Address Book pre vkladanie, editovanie a mazanie zßznamov o poÜtov²ch adresßch. Proced·ra Clear2Click (Sender: TObject); sa pou₧φva na vymazanie Memo boxu. Memo Box obsahuje samotn² text sprßvy. Proced·ra LoadFileClick (Sender: TObject); a Proced·ra SaveFileClick (Sender: TObject); umo₧≥uje otvori¥, prφpadne ulo₧i¥ s·bor s textom sprßvy.

Unit AddressBook.pas
procedure TAddressBook2.FormCreate(Sender: TObject);
var
i1, i2, i3 : integer;
route, s1, s2 : string;

begin

// NaΦφtanie icon pre okno Address Book
IconAdd.Glyph.Handle:=LoadBitmap(HInstance,'005ADD');
IconEdit.Glyph.Handle:=LoadBitmap(HInstance,'004EDIT');
IconDelete.Glyph.Handle:=LoadBitmap(HInstance,'003TRASH');
IconApply.Glyph.Handle:=LoadBitmap(HInstance,'002OK');
IconCancel.Glyph.Handle:=LoadBitmap(HInstance,'001CANCEL');

// NaΦφtanie Listview1.Columns.Width z registra Windows
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');
s1:=IniFile.ReadString('AddressBook','Name', s1);
Listview1.Columns[0].Width:=StrToInt(s1);
s1:=IniFile.ReadString('AddressBook','Organization', s1);
Listview1.Columns[1].Width:=StrToInt(s1);
s1:=IniFile.ReadString('AddressBook','EmailAddress', s1);
Listview1.Columns[2].Width:=StrToInt(s1);
s1:=IniFile.ReadString('AddressBook','Phone', s1);
Listview1.Columns[3].Width:=StrToInt(s1);
s1:=IniFile.ReadString('AddressBook','City', s1);
Listview1.Columns[4].Width:=StrToInt(s1);

// Cesta k s·boru v ktorom bud· ulo₧enΘ emailovΘ adresy
route := IniFile.ReadString('Path','Location File', route);
route:=route+'\Address\AddressBook.txt';

// Vytvorenie StringListu, t.j. miesta v pamΣti pre emailovΘ adresy
StackAddressBook:=TStringList.Create;
StackAddressBook.LoadFromFile(route);

// Zistenie poΦtu sprßv zo s·boru AddressBook.txt
s1:=StackAddressBook.Strings[0];
s2:=Copy(s1,17,Length(s1)-16);
i1:=StrToInt(s2);

// Prenes sprßvy z pamΣti do komponenty Listview
Listview1.SortType:=(stNone);
i3:=1;
for i2:=0 to i1-1 do
begin
ListView1.Items.Add.Caption:=StackAddressBook.Strings[i3];
ListView1.Items[Listview1.Items.Count-1].SubItems.Append(StackAddressBook.Strings[i3+1]);
ListView1.Items[Listview1.Items.Count-1].SubItems.Append(StackAddressBook.Strings[i3+2]);
ListView1.Items[Listview1.Items.Count-1].SubItems.Append(StackAddressBook.Strings[i3+3]);
ListView1.Items[Listview1.Items.Count-1].SubItems.Append(StackAddressBook.Strings[i3+4]);
i3:=i3+6;
end;

// Zobraz poΦet sprßv
StatusBar1.Panels[1].Text:='Counted record: '+IntToStr(Listview1.Items.Count);
IniFile.Destroy;
end;

Proced·ra ApplyClick (Sender: TObject); zaznamenß vÜetky emailovΘ adresy do s·boru AddressBook.txt, tie₧ ulo₧φ do registra Windows hodnoty Listview1.Columns.Width a zatvorφ okno. Proced·ra DeleteClick (Sender: TObject); vyma₧e aktußlnu polo₧ku, v prφpade ₧e kliknete na toto tlaΦidlo a nie je vybranß ₧iadna emailovß adresa û zobrazφ sa chybovΘ hlßsenie. Proced·ra AddClick (Sender: TObject); zobrazφ okno AddItem na vlo₧enie novΘho zßznamu. Proced·ra ListView1DblClick (Sender: TObject); prenesie emailov· adresu do po╛a To: a zatvorφ okno. Proced·ra ListView1Click (Sender: TObject); aktußlnu adresu zobrazφ v stavovom riadku aplikßcie. Proced·ra EditClick (Sender: TObject); otvorφ okno AddItem a umo₧nφ editovanie aktußlneho zßznamu.

Unit AddItem.pas
procedure TAddItem2.FormCreate(Sender: TObject);
var
test : string;
begin

// NaΦφtanie icon pre okno AddItem
IconOk.Glyph.Handle:=LoadBitmap(HInstance,'002OK');
IconCancel.Glyph.Handle:=LoadBitmap(HInstance,'001CANCEL');

// Test û Φi ide o prepφsanie adresy Edit alebo vlo₧enie novej adresy Add
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');
test:=IniFile.ReadString('Temp','InsertItem', test);

if test='1' then // Ak ide Edit, naΦφtanie vybranej adresy z registra
begin
IniFile.WriteString('Temp','InsertItem', '0');
Edit1.Text:=IniFile.ReadString ('Temp','Name', Edit1.Text);
Edit2.Text:=IniFile.ReadString ('Temp','Organization', Edit2.Text);
Edit3.Text:=IniFile.ReadString ('Temp','EmailAddress', Edit3.Text);
Edit4.Text:=IniFile.ReadString ('Temp','Phone', Edit4.Text);
Edit5.Text:=IniFile.ReadString ('Temp','City', Edit5.Text);
end;
IniFile.Destroy;
end;

Procedure OkClick(Sender: TObject); zapφÜe vyplnenΘ ·daje do registrov a zatvorφ okno. Procedure CancelClick(Sender: TObject); zatvorφ okno a do k╛·Φa 'Temp' subk╛uΦa 'ButtonOK' zapφÜe hodnotu '0', ktorß znamenß, ₧e bolo stlaΦenΘ tlaΦidlo Cancel a teda editovanß alebo pridßvanß emailovß adresa sa nebude zaznamenßva¥.

Unit SendMessage;
proced·ra SakSMTP1SendProgress (Sender: TObject; Percent: Word); zobrazuje ko╛ko percent danΘho s·boru je u₧ odoslanΘho na poÜtov² server. Proced·ra SakSMTP1BeforeSend (Sender: TObject); sa aktivuje po poslanφ sprßvy a nastavφ SendProgress na nulu. Proced·ra SakSMTP1EncodeStart (Sender: TObject; FileName: String; BytesCount: Integer); sa aktivuje pred prevodom sprßvy do formßtu Base64 a nastavφ EncodeProgress na nulu. Proced·ra SakSMTP1EncodeProgress (Sender: TObject; Percent: Word); zobrazuje ko╛ko percent danΘho s·boru je u₧ transformovanΘho do formßtu base64. Proced·ra SakSMTP1EncodeEnd (Sender: TObject); sa spustφ po ukonΦenφ k≤dovania s·boru a nastavφ EncodeProgress na nulu. Proced·ra CancelSend1Click (Sender: TObject); umo₧nφ preruÜi¥ aktußlne posielanie s·boru na server a zatvorφ okno. Proced·ra SakSMTP1Error(Sender: TObject; Error: Integer; Msg: String); zobrazφ chybovΘ hlßsenie ak vznikne chyba v s·vislosti s SMTP serverom.

procedure TSend1.ConnectClick(Sender: TObject);
var
position, i : integer;
route, count, s1 : string;

begin
Timer1.Enabled:=false;
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');
StatusBar1.SimpleText:='Connecting: Ok';
StatusBar1.SimpleText:='Wait a moment, please - contact your post server';

// NaΦφtanie parametrov z registra Windows
s1:=IniFile.ReadString ('Smtp','HostSmtp',s1);
SakSMTP1.Host := s1;
s1:=IniFile.ReadString ('Smtp','PortSmtp',s1);
SakSMTP1.Port := s1;
s1:=IniFile.ReadString ('User','UserName',s1);
SakMsg1.UserName := s1;
s1:=IniFile.ReadString ('User','UserAddress',s1);
SakMsg1.From := s1;
s1:=IniFile.ReadString ('Message','To',s1);
SakMsg1.SendTo := s1;
s1:=IniFile.ReadString ('Message','Subject',s1);
SakMsg1.Subject := s1;
s1:=IniFile.ReadString ('Message','Cc',s1);
SakMsg1.CC := s1;
s1:=IniFile.ReadString ('Message','ReplyTo',s1);
SakMsg1.ReplyTo := s1;

route := IniFile.ReadString('Path','Location File', route);
SakMsg1.Text.LoadFromFile(route+'\Temp\working.tmp');
SakMsg1.AttachedFiles.clear;

// NaΦφtanie priority sprßvy
s1 := IniFile.ReadString ('Message','PriorityMessage', s1);
position:=Strtoint(s1);

case position of
0 : SakMsg1.Priority := prHighest;
1 : SakMsg1.Priority := prHigh;
2 : SakMsg1.Priority := prNormal;
3 : SakMsg1.Priority := prLow;
4 : SakMsg1.Priority := prLowest;
end;

// PoΦet pripojen²ch s·borov
count:=IniFile.ReadString('AttachedFiles','count',count);

if StrToInt(count)<>0 then
begin
for i:= 0 to StrToInt(count)-1 do
begin
s1:=IniFile.ReadString ('AttachedFiles',IntToStr(i+1),s1);
SakMsg1.AttachedFiles.add(s1);
end;
end;

SakSMTP1.connect;

// Ak sa nie je mo₧nΘ spoji¥ so serverom vypφÜe sa chyba
if SakSMTP1.SMTPError then
begin
StatusBar1.SimpleText:='Connecting: Fail';
SakMsg1.AttachedFiles.Clear;
MessageBeep(mb_IconExclamation);
MessageDlg('A network error occurred:'+#13#10+
'unable to connect to server (TCP Error: No route to host)'+#13#10+
'The server may by down or unreachable.'+#13#10#13#10+
'Try connecting again later.',mtWarning, [mbOk], 0);
end;

// Ak je spojenie Ok poÜle sa vytvorenß sprßva na VßÜ poÜtov² server
if not SakSMTP1.SMTPError then
begin
StatusBar1.SimpleText:='Connecting: Ok';
SakSMTP1.SendMessage(SakMsg1);
Gauge2.Progress:=0;
SakSMTP1.quit;
Gauge2.Progress:=0;
IniFile.WriteString ('Temp','TestClose','1');
end;
close;
end;

Unit MailBox
Proced·ra FormCreate (Sender: TObject); vypφÜe do stavovΘho riadku aktußlny dßtum a zakß₧e polo₧ku menu û Stop. Proced·ra SakPOP1AfterRetrieve (Sender: TObject); zobrazφ do stavovΘho riadku Φφslo sprßvy, ktorß sa prenßÜa na lokßlny poΦφtaΦ. Proced·ra SakPOP1RetrieveProgress (Sender: TObject; Percent: Word); zobrazuje ko╛ko percent danΘho s·boru je u₧ prijatΘho z poÜtovΘho servera.

Proced·ra SakPOP1BeforeRetrieve (sender: TObject; id: Word); sa aktivuje po prijatφ sprßvy a nastavφ RetrieveProgress na nulu.

Proced·ra SakPOP1DecodeProgress (Sender: TObject; Percent: Word); zobrazuje ko╛ko percent danΘho s·boru je u₧ transformovanΘho z formßtu base64 spΣ¥ do binßrneho tvaru.

Proced·ra SakPOP1DecodeStart (Sender: TObject; FileName: String; BytesCount: Integer); sa aktivuje pred prevodom sprßvy z formßtu Base64 a nastavφ EncodeProgress na nulu. Proced·ra SakPOP1DecodeEnd (Sender: TObject); sa spustφ po ukonΦenφ dek≤dovania s·boru a nastavφ EncodeProgress na nulu. Proced·ra SakPOP1Error (Sender: TObject; Error: Integer; Msg: String); zobrazφ chybovΘ hlßsenie ak vznikne chyba v s·vislosti s POP3 serverom.

Proced·ra About1Click (Sender: TObject); zavolß proced·ru na zobrazenie okna About. Proced·ra Options1Click (Sender: TObject); zobrazφ okno Preferences, proced·ra NewMsg (Sender: TObject); zobrazφ okno Create Text Message

Proced·ra ListView2Click (Sender: TObject); zobrazφ obsah konkrΘtnej sprßvy a pripojenΘ s·bory. Proced·ra DeleteMsg1Click (Sender: TObject); sa pou₧φva na vymazanie sprßv. Proced·ra Stop1Click (Sender: TObject); umo₧≥uje preruÜi¥ prijφmanie sprßv zo servera.

Proced·ra showCurrentMsg; zobrazφ aktußlnu sprßvu. Proced·ra ButtonSave2Click (Sender: TObject); umo₧≥uje ulo₧i¥ s·bor(y), ktor² je pripojen² k sprßve na lokßlny disk poΦφtaΦa.

procedure TMail.GetMsg1Click(Sender: TObject);
var passwd0,login0 : string;
testsavepassword, testcancel : string;
Hwnd : THandle;
begin
// Zistφ Hwnd (Φφslo) okna aplikßcie
Hwnd := FindWindow ('TMail', 'Simple mail');

// PoÜle sprßvu wm_HideMenu na zßkaz polo₧iek menu
PostMessage (Hwnd, wm_HideMenu,0,0);

// NaΦφtanie mena (login) a hesla (password) z registra Windows
IniFile := TRegIniFile.Create ('SOFTWARE\SimpleMail');
passwd0:=IniFile.ReadString ('Mailbox','Password', passwd0);
login0:=IniFile.ReadString ('Mailbox','Login', login0);

// Ak nie je heslo (password) alebo prihlasovacie meno (login)
// zadanΘ zobrazφ sa okno Preferences na zadanie ch²baj·cich
// ·dajov
if (passwd0='') or (login0='') then
begin

with TPreferences2.Create(Application) do
try
// Nastavenie na zßlo₧ku MailBox v okne Preferences
PageControl1.SelectNextPage(True);
PageControl1.SelectNextPage(True);
IniFile.WriteString ('Temp','Getmsg', '1');
ShowModal;
finally
IniFile.WriteString ('Temp','Getmsg', '0');
login:=IniFile.ReadString ('Mailbox','Login', login);
password:=IniFile.ReadString ('Mailbox','Password', password);
testsavepassword:=IniFile.ReadString ('Mailbox','SavePassword', testsavepassword);

if testsavepassword='0' then IniFile.WriteString ('Mailbox','Password', '');
Free;

// Nastavenie komponenty SakPOP
SakPOP1.Host := IniFile.ReadString ('Pop3','HostPop3', SakPOP1.Host);
SakPOP1.UserId := login;
SakPOP1.Passwd := password;
end;
end
else
begin
SakPOP1.Host := IniFile.ReadString ('Pop3','HostPop3', SakPOP1.Host);
SakPOP1.UserId := IniFile.ReadString ('Mailbox','Login', SakPOP1.UserId);
SakPOP1.Passwd := IniFile.ReadString ('Mailbox','Password', SakPOP1.Passwd);
end;

testcancel:=IniFile.ReadString ('Temp','TestCancel', testcancel);

if testcancel='1' then exit else
begin
StatusBar1.Panels[0].Text := 'Wait a moment, please - contact your post server';

SakPOP1.connect;

// Ak nie je mo₧nΘ vytvori¥ spojenie vypφÜe sa chyba
if SakPOP1.POPError then
begin
StatusBar1.Panels[0].Text := 'Connecting: Fail';
MessageBox(Mail.Handle, 'Connect failed. Maybe the server is down or not responding.','Error',MB_OK or MB_ICONERROR);
StatusBar1.Panels[0].text := '';
PostMessage (Hwnd, wm_EnableMenu,0,0);
exit;
end;

// Ak je chybne zadane heslo alebo prihlasovacie meno vypφÜe sa chyba
if not SakPOP1.login then
begin
StatusBar1.Panels[0].Text := 'Connecting: Fail';
MessageBox(Mail.Handle, 'Unauthorized access...','Error',MB_OK or MB_ICONERROR);
PostMessage (Hwnd, wm_EnableMenu,0,0);
exit;
end;

Stop1.Enabled:=True;
StatusBar1.Panels[0].Text := 'Connecting: Ok '+'-> You have ' +
intToStr( SakPOP1.Init) + ' new msg(s) of ' +
intToStr( SakPOP1.MsgsCount);

// Prenesenie vÜetk²ch sprßv z poÜtovΘho servera
sakPOP1.retrieveAllMessages( SakMsgList1);

Gauge3.Progress := 0;

// UkonΦenie spojenia s POP3 serverom
SakPOP1.quit;
Stop1.Enabled:=False;

// PoÜle sprßvu wm_EnableMenu na sprφstupnenie polo₧iek menu
PostMessage (Hwnd, wm_EnableMenu,0,0);

// Zobrazenie sprßv preΦφtan²ch zo servera
if SakMsgList1.count > 0 then
begin
GetMsg1.Visible:=False;
currentMsg := 0;
showCurrentMsg;
end;
StatusBar1.Panels[0].text := 'Done. ' + intToStr( SakMsgList1.count) + ' msgs retrieved.';
end;
end;

Program Projekt1
Projekt obsahuje eÜte k≤d na kontrolu nßsobnΘho spustenia aplikßcie. K≤d zabezpeΦφ, ₧e bude mo₧nΘ spusti¥ iba jednu k≤piu aplikßcie. API funkcia FindWindow vy₧aduje dva parametre: nßzov triedy okna a titulok okna, ktorΘ h╛adßte. V²sledkom funkcie FindWindow je handle okna alebo nula, pokia╛ nie je nßjdenΘ ₧iadne okno. S t²mto k≤dom m⌠₧ete spusti¥ nov· k≤piu aplikßcie iba v prφpade, ₧e neexistuje jej predchßdzaj·ca inÜtancia. Pokia╛ u₧ jedna k≤pia aplikßcie be₧φ, nestane sa niΦ. Iba v prφpade ₧e sa aplikßcia nachßdza v minimalizovanej podobe vykonß sa prφkaz Application.Restore. Pokia╛ tento program spustφte v Delphi. Bude okno s dan²m titulkom u₧ existova¥. Takto sa aplikßcia nespustφ ani raz. Spustφ sa a₧ vtedy ak zmenφte riadok k≤du napr. takto: Hwnd := FindWindow ('TMail', 'Simple');.

...
var Hwnd: THandle;

begin
Hwnd := FindWindow ('TMail', 'Simple mail');
if Hwnd = 0 then
begin
Application.Initialize;
Application.CreateForm(TMail, Mail);
Application.Title := 'Simple mail';
Application.Run;
end
else
begin
if (not IsWindowVisible (Hwnd)) then
PostMessage (Hwnd, wm_User,0,0);
SetForegroundWindow (Hwnd);
end;
...


(c) 2004 Ing. Peter GaÜparoviΦ - www.pgasparovic.com

Literat·ra

[1]  Feiber, W.: Encyklopedie poΦφtaΦov²ch sφtφ. Praha, Computer Press, 1996.
[2]  B°ehovsk², P.: Praktick² ·vod TCP/IP. ╚eskΘ Bud∞jovice, KOPP, 1994.
[3]  Mrßzek, L.: Prvnφ kroky INTERNETEM aneb Je to na WWW!. ╚eskΘ Bud∞jovice, KOPP, 1995.
[4]  èmrha, P. - Rudolf, V.: Internetworking pomocφ TCP/IP. ╚eskΘ Bud∞jovice, KOPP, 1995.
[5]  Hejna, L.: Lokßlnφ poΦφtaΦovΘ sφte. Praha, GRADA, 1994.
[6]  Falk, B.: Pr∙vodce sv∞tem Internetu. Praha, Computer Press, 1995.
[7]  Lhotka, L.: SERVER v INTERNETU. ╚eskΘ Bud∞jovice, KOPP, 1997.
[8]  Peterka, J.: Co je Φφm ... v poΦφtaΦov²ch sφtφch. COMPUTERWORLD, 1994, Φ. 4, 7, 9, 17, 21, 35, 44.