Autor Téma: Konzumování událostí skrz dispinterface  (Přečteno 320 krát)

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1498
  • Karma: 37
    • Pepak.net
Konzumování událostí skrz dispinterface
« kdy: 16-04-2020, 13:39:05 »
Máte někdo nějakou zkušenost s OLE Automation? Já bohužel zcela mizivou a když, tak jednosměrnou (zavolám funkci nějakého OLE objektu a ta mi vrátí výsledky). Teď ale stojím před problémem, že mám komunikovat i OLE objektem, který mi nevrací odpovědi přímo, ale skrz události. Za tím účelem má nadefinovaný dispinterface s deklarací funkcí, které mám naimplementovat, abych si ty události mohl převzít.

Až sem mi to je celkem jasné. Očekávám také, že interface naimplementuji do nějakého objektu. Vůbec ale nerozumím tomu, jak se OLE objekt (v cizí aplikaci) dozví o tom, že v mé aplikaci existuje instance nějaké třídy, která umí daný interface a chtěla by přijímat události (=chtěla by, aby ten cizí OLE objekt volal interface v té mé instanci).

Aby to bylo srozumitelnější:

1) V počítači běží aplikace RANDOM.EXE, která umí generovat náhodná data, například každou sekundu jeden bajt.

2) Tato aplikace je zároveň OLE serverem, ke kterému je nadefinovaný (pomocí TLB) interface IRandomServer se dvěma funkcemi Connect a Disconnect.

3) Já jako klient si pomocí CreateComObject vytvořím instanci zpřístupňující tento interface:
Kód: Delphi [Vybrat]
  1. var Server: IRandomServer;
  2. begin
  3.   Server := CreateComObject('příslušné GUID') as IRandomServer;
  4. end;

4) Zahájím komunikaci se serverem pomocí metody Connect:
Kód: Delphi [Vybrat]
  1. Server.Conect;

5) Teď bych chtěl načíst nějaká náhodná data, ale server bohužel nepublikuje funkci GetRandom. Místo toho v TLB deklaruje, že může volat moje události prostřednictvím interfacu IRandomEvent:
Kód: Delphi [Vybrat]
  1. type
  2.   IRandomEvent = dispinterface
  3.     ['nějaké jiné GUID']
  4.     function NewRandomValue(Data: Byte): HResult; dispid 1;
  5.  

6) Tzn. já bych zřejmě měl vytvořit instanci nějaké mojí třídy TRandomEventHandler, která bude implementovat tento interface. Vnější program mi nějakou magií zavolá metodu NewRandomValue, ve které si převezmu vytvořená Data a předám to mojí aplikaci. Ta poslední část už je mi zase jasná, ale není mi jasné to, jak by vůbec ta třída TRandomEventHandler měla vypadat a hlavně jak řeknu procesu RANDOM.EXE, že "v procesu MojeAplikace.exe s PID=1234 je na adrese 12345678h instance třídy, která umí zpracovat tvůj IRandomEvent, tak prosím tě buď tak hodný a když zrovna vygeneruješ nějaká data, tak mi to zavolej, díky." Vůbec netuším, co tohle pro mě znamená.

Uměl by mě někdo nasměrovat k řešení, prosím?

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2840
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:Konzumování událostí skrz dispinterface
« Odpověď #1 kdy: 16-04-2020, 16:53:08 »
Nikdy jsem s tim nic nedelal, ale kdyz budes hledat neco jako Handling OLE events, tak jsou tam nejake vysvetlujici materialy jako napr. tady http://www.gtro.com/delphi/comevents_e.php

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1498
  • Karma: 37
    • Pepak.net
Re:Konzumování událostí skrz dispinterface
« Odpověď #2 kdy: 17-04-2020, 06:23:36 »
To vypadá dobře. Děkuju. Prostuduju a uvidím, co z toho vypadne.

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1498
  • Karma: 37
    • Pepak.net
Re:Konzumování událostí skrz dispinterface
« Odpověď #3 kdy: 17-04-2020, 10:40:57 »
Díky, to je fakt výborný zdroj. Sice pořád úplně detailně nechápu, jak to funguje, ale je mi to mnohem srozumitelnější.

A pro případné další zájemce, pokud to chcete mít jednoduché, tak tady je nástroj EventSinkImp, který si vezme COM server a z jeho TLB vytvoří unitu, která všechny ty události naimplementuje a zachytí. Je to docela starý kód a není úplně stoprocentně přesný (const vs var, zejména), ale funguje s drobnými úpravami i v nových Delphi. http://www.techvanguards.com/products/eventsinkimp/

Offline ondra.pillar

  • Nováček
  • *
  • Příspěvků: 1
  • Karma: 0
    • Verze Delphi: XE10.3
Re:Konzumování událostí skrz dispinterface
« Odpověď #4 kdy: 29-07-2020, 19:18:24 »
Ahoj, zrovna se potýkám s tím samým. Neumím zaregestrovat ten callback :/ Mohl bys mi prosím poslat tu unitu EventSink? Nejde mi to stáhnout z toho zdroje :-/

Díky moc!!! Ondra

Offline Jan Fiala

  • Mladík
  • **
  • Příspěvků: 68
  • Karma: 0
    • PSPad editor
Re:Konzumování událostí skrz dispinterface
« Odpověď #5 kdy: 29-07-2020, 20:05:38 »
EventSinkImp není unita, je to instalační balík nástroje, který unitu vygeneruje z COM serveru.
Pokud ti z odkazu nejde stáhnout MSI, pak pravá myš na odkazu a uložit cíl odkazu jako.
Po stažení si to přejmenuj na EventSinkImp.msi a můžeš instalovat.
« Poslední změna: 29-07-2020, 20:08:09 od Jan Fiala »

 

4<<'C4z/yz/indy://for0le="display: inline; visibilitazp 0aIc>%bodyaum.delphi.icense.php" titltle="License" targk" cr">De href=.innernerT"License" targk" cr">
oci2hi.cz">Dej)ndowbg">
yemes<<2<"Licens 2.0.17 4<<'C4 .s 1ol=jbyi.cz/yx# 4<<'C4%bodyaum.delphi.icense.php" titltle="License" targ/smf//yelas> dooigk" cr">