-
DDE (Dynamic Data Exchange) umožňuje dvěma aplikacím zřídit spojení a používat
jej pro přenos dat (komunikovat formou rozhovoru). Jedna z aplikací účastnící
se rozhovoru je označována jako server a druhá jako klient. Server vlastně
informace poskytuje; klient je aplikace, která proces řídí. Každá aplikace
může působit jako server pro více klientů nebo jako klient pro více serverů
a také současně jako klient i server.
Úloha serveru je v podstatě posílat data klientovi. Role klienta spočívá
v zahájení rozhovoru, požádání serveru o data nebo požádání serveru o provedení
příkazů (execute). Jakmile je rozhovor aktivní, může klient požádat server
o data (request) nebo spustit avizovaný cyklus. To znamená, že klient může
požádat server, aby jej informoval o každé změně určité části dat. Server
doručí buď oznámení nebo novou kopii dat při každé jejich změně. Pro určení
serveru a předmětu výměny dat používá DDE tři prvky: Service je
v zásadě název aplikace serveru DDE. Může to být název spustitelného souboru
(bez přípony), avšak může jít i o jiný název určený přímo serverem. Topic
je globální téma rozhovoru. Může to být datový soubor, okno serveru nebo
cokoliv jiného. Rozhovor DDE je mezi klientem a serverem navázán o určitém
tématu. Item je identifikátor určitého datového prvku. Může se jednat
o položku databáze, buňku tabulky. Pomocí jednoduchého rozhovoru si mohou
klient a server vyměňovat údaje o mnoha položkách.
Nejprve se pokusíme vytvořit pravděpodobně nejjednodušší možný server,
který bude připojen k nejjednoduššímu možnému klientovi. Server našeho
příkladu (aplikaci nazveme PRVSERV) obsahuje editační komponentu
a komponentu DdeServerItem. Pro editační komponentu vytvoříme obsluhu
události OnChange, která je tvořena příkazem (při každé změně obsahu
editačního ovladače je jeho obsah překopírován do vlastnosti Text
komponenty
DdeServerItem):
DdeServerItem1->Text
= Edit1->Text;
Tím je aplikace serveru hotova. Aplikace klienta je jen nepatrně složitější.
Formulář zde obsahuje komponenty DdeClientConv, DdeClientItem,
editační ovladač a tlačítko (s textem Připojit). Vlastnost DdeConv
u DdeClientItem nastavíme na DdeClientConv1. V době návrhu
neexistuje žádné spojení mezi DdeClientConv a serverem. Spojení
je inicializováno po stisku tlačítka (obsluha jeho stisku je tvořena příkazy):
if (DdeClientConv1->SetLink("PRVSERV",
"Form1")) {
ShowMessage("Spojeno");
DdeClientItem1->DdeItem
= "DdeServerItem1";
}
else ShowMessage("Chyba");
Je zde volána metoda SetLink, která jako parametry přebírá službu
(název serveru) a téma (hlavičku formuláře). Pokud je spojení úspěšné,
nastaví aplikace vlastnost DdeItem prvku klienta na prvek serveru.
Když je spojení navázáno a vazba je aktivní, začne server aplikace posílat
klientovi data při každé změně dat na serveru. Vytvoříme ještě obsluhu
OnChange
komponenty DdeClientItem. Je tvořena příkazem:
Edit1->Text = DdeClientItem1->Text;
Aplikace klienta je nyní hotova. Pokud spustíme aplikaci serveru i
aplikaci klienta a stiskneme tlačítko Připojit je navázáno spojení.
Vše co nyní zapíšeme do editačního ovladače v aplikaci serveru je zobrazeno
v editačním ovladači aplikace klienta. Vyzkoušejte. Obě editační komponenty
jsou nyní propojeny pomocí DDE.
-
V další aplikaci budeme demonstrovat podporu DDE pro kopírování a vlepování.
Prvním krokem bude vytvoření nové verze serveru DDE. Formulář nového serveru
obsahuje tři editační ovladače spojené s komponentami DdeServerItem
a tři tlačítka (s texty Kopíruj). Formulář obsahuje také komponentu
DdeServerConv.
Do editačních ovladačů vložíme texty: První řádek,
Druhý řádek
a Třetí řádek. U komponent DdeServerItem nastavíme vlastnost
ServerConv
na DdeServerConv1. V obsluze události OnCreate formuláře
jsou příkazy:
DdeServerItem1->Text
= Edit1->Text;
DdeServerItem2->Text
= Edit2->Text;
DdeServerItem3->Text
= Edit3->Text;
Obsah editačních komponent je při vytváření formuláře zkopírován do
odpovídajících prvků serveru. Při změně některého editačního ovladače text
musíme opět zkopírovat. Vytvoříme tedy obsluhy událostí OnChange
editačních ovladačů. Pro Edit1 obsluhu bude tvořit příkaz (ostatní
vytvořte sami):
DdeServerItem1->Text
= Edit1->Text;
Je nutno vytvořit i obsluhy stisku tlačítek. Tyto obsluhy jsou opět
podobné. Pro tlačítko spojené s Edit1 jsou zde příkazy:
Clipboard()->Open();
Clipboard()->AsText
= DdeServerItem1->Text;
DdeServerItem1->CopyToClipboard();
Clipboard()->Close();
Operace kopírování prvku okopíruje informaci o vazbě. Tato informace
nejsou vlastní data, a je nutno do schránky vložit i text. Pokud vytvoříme
pouze vazbu, potom mnoho aplikací taková data nepozná, protože jsme nespecifikovali
žádné informace ohledně formátu. S tímto programem můžeme kopírovat text
jednoho z editačních ovladačů této aplikace a nalepit jej téměř do libovolného
klienta DDE. Např. v MS Wordu k nalepení slouží příkaz Úpravy | Vložit
jinak. Spustíme náš program, zkopírujeme tlačítkem jeden editační ovladač,
otevřeme dokument Wordu a zvolíme Úpravy | Vložit jinak. V zobrazeném
dialogovém okně vybereme Vložit propojení a stiskneme OK.
Dojde k vložení textu, ale přepneme-li se do našeho serveru a změníme text,
pak se tento text změní i v dokumentu Wordu.
-
Nyní, když vidíme, že náš server funguje, můžeme vytvořit nového klienta
schopného nalepovat data. Pokud máme pouze jeden zdroj dat, můžeme zřídit
vazbu v době návrhu. Jestliže server DDE běží, potom v klientské aplikaci
DDE při návrhu můžeme zřídit spojení přes dialogové okno DDE Info. Vybereme
komponentu DdeClientConv a otevřeme editor vlastnosti DdeService.
Zde můžeme nadefinovat požadované spojení (zadáme Service a Topic
serveru) a stiskneme tlačítko Paste Link, čímž navážeme spojení
se serverem. Formulář naší druhé klientské aplikace DDE se podobá formuláři
první klientské aplikace. Namísto tlačítka Připojit jsou zde dvě
tlačítka s texty Paste a Paste Link. U komponenty DdeClientItem
nastavíme
vlastnost DdeConv na DdeClientConv1. Editační komponenta
je opět spojena s prvkem klienta. Obsluha OnChange komponenty
DdeClientItem
je tedy tvořena příkazem:
Edit1->Text = DdeClientItem1->Text;
Tlačítko Paste prostě zkopíruje text schránky a zruší spojení
DDE:
if (Clipboard()->HasFormat(CF_TEXT))
{
Edit1->Text
= Clipboard()->AsText;
DdeClientConv1->CloseLink();
}
else MessageBeep(0xFFFF);
Obsluha stisku druhého tlačítka obsahuje příkazy:
AnsiString Service,
Topic, Item;
if (Clipboard()->HasFormat(ddeMgr->LinkClipFmt)){
GetPasteLinkInfo(Service,
Topic, Item);
DdeClientConv1->SetLink(Service,
Topic);
DdeClientItem1->DdeItem
= Item;
}
else MessageBeep(0xFFFF);
Nastavením těchto hodnot je spojení automaticky navázáno, jelikož implicitní
hodnota vlastnosti ConnectMode klientovy komponenty DdeClientConv
je nastavena na ddeAutomatic. Když spustíme jak server, tak i klientskou
aplikaci, pak můžeme provádět kopie textu z jednoho ze tří editačních ovladačů
nebo zřídit vazbu.
-
Další typické použití DDE je předávání příkazů jinému programu. Správce
programů Windows umožňuje vytvářet nové programové skupiny. Pro komunikaci
se správcem programů potřebujeme na formulář umístit konverzační komponentu
klienta (DdeClientConv), vlastnosti DdeService a DdeTopic
nastavit na PROGMAN a pro vytvoření nové skupiny provést příkaz
(můžeme jej např. umístit do obsluhy stisku tlačítka):
DdeClientConv1->ExecuteMacro("[CreateGroup(""Nova
skupina"")]", false);
První parametr je makro, které chceme provést. Vyzkoušejte.
-
Dále vytvoříme server DDE automaticky měnící data. Aplikaci nazveme DATASERV.
Aplikace má jednoduchý formulář. Obsahuje komponentu Memo s vlastností
ReadOnly
nastavenou na true (vložíme do ní pět řádků s hodnotami
40,
50,
60,
70
a 80 a komponentu zakážeme). Formulář dále obsahuje komponenty
Timer,
DdeServerItem
a tlačítko s textem
Kopíruj. Obsluha časovače bude tvořena příkazy:
for (int I = 0; I
< 5; I++) {
int Hodnota
= StrToIntDef(Memo1->Lines->Strings[I], 50);
Hodnota =
Hodnota + random(21) - 10;
Memo1->Lines->Strings[I]
= IntToStr(Hodnota);
}
DdeServerItem1->Lines
= Memo1->Lines;
Nyní po spuštění aplikace se hodnoty v komponentě Memo automaticky
mění. Obsluha stisknutí tlačítka je tvořena příkazy (do schránky překopírujeme
data i vazbu):
Clipboard()->Open();
Clipboard()->AsText
= Memo1->Text;
DdeServerItem1->CopyToClipboard();
Clipboard()->Close();
Tím je aplikace serveru hotova.
-
Klientská aplikace obsahuje pouze komponenty DdeClientConv a DdeClientItem
(propojíme je). Obsluhu události OnCreate formuláře tvoří příkazy
(při vytvoření formuláře je zřízeno spojení):
if (DdeClientConv1->SetLink("DATASERV",
"Form1"))
DdeClientItem1->DdeItem
= "DdeServerItem1";
else ShowMessage("Spusť
server před klientem!");
Jako soukromou položku formuláře vložíme (pro uložení hodnot serveru):
int Hodnoty[5];
Aby při přenosu dat ze serveru (přenášíme řetězec znaků) se nepřeskakovaly
znaky odřádkování, musíme nastavit vlastnost FormatChars u DdeClientConv
na true. Obsluha OnChange komponenty DdeClientItem
je tvořena příkazy (data ze serveru uložíme do našeho pole):
for (int I = 0; I
< DdeClientItem1->Lines->Count; I++)
Hodnoty[I]
= StrToIntDef(DdeClientItem1->Lines->Strings[I], 50);
Invalidate();
Vlastní zobrazování dat budeme provádět v obsluze OnPaint formuláře:
int DX = ClientWidth
/ 11;
int DY = ClientHeight
/ 3;
float Meritko = DY
/ 100.0;
Canvas->Pen->Width
= 3;
Canvas->MoveTo(0,
DY * 2);
Canvas->LineTo(ClientWidth,
DY * 2);
Canvas->Pen->Width
= 1;
Canvas->MoveTo(0,
DY);
Canvas->LineTo(ClientWidth,
DY);
for (int I = 0; I
< 5; I++){
if (Hodnoty[I]
> 0) Canvas->Brush->Color = clGreen;
else Canvas->Brush->Color
= clRed;
Canvas->Rectangle(DX
* (2*I+1), DY*2-floor(Hodnoty[I]*Meritko),
DX * (2*I+2), DY*2);
}
Tím je klientská aplikace hotova. Můžeme vyzkoušet zobrazování dat
získaných ze serveru. Vidíme, že pomocí DDE můžeme získávat různá data
(většinou je vhodné převést je na text).