Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Windows API / MS.NET Framework API (https://www.delphipraxis.net/20-library-windows-api-ms-net-framework-api/)
-   -   Delphi COM Collections durchlaufen (_NewEnum, IEnumVariant) (https://www.delphipraxis.net/11309-com-collections-durchlaufen-_newenum-ienumvariant.html)

sakura 4. Nov 2003 08:27


COM Collections durchlaufen (_NewEnum, IEnumVariant)
 
Hi,

die Frage zu COM Collections kam inzwischen schon öfters, also möchte ich an dieser Stelle mal zeigen, wie mal in Delphi folgenden Visual Basic - Konstrukt umsetzt.

Code:
[b]dim[/b] Doc, Nodes, Node

[b]set[/b] Doc = Server.CreateObject("Msxml2.DOMDocument.4.0")
Doc.load("C:\Temp\hallo.xml")
[b]set[/b] Nodes = Doc.selectNodes(".//*")

[b]for each[/b] Node [b]in[/b] Nodes

  ListBox1.Items.Add(Node.nodeName)

[b]next[/b]
Nun ist leider VB (bzw. VBScript) die einzige Sprache, welche dieses Konstrukt so unterstüzt. Damit dieses Konstrukt jedoch funktioniert, muss das COM Objekt das IEnumVariant Interface mittels der Methode _newEnum exportieren. Über diese Methode und dieses Interface kann man diese Collection auch in anderen Programmiersprachen ansteuern. Nun das ersehnte Delphi-Beispiel zu obigem Beispiel.

Delphi-Quellcode:
var
  // MSXML typische Interfaces

  // Das Basis Dokument
  Doc: IXMLDOMDocument2;
  // Die COM Collection
  Nodes: IXMLDOMNodeList;
  // Das COM Collection Objekt
  Node: IXMLDOMNode;

  // das Interface zum Collection-Container
  Enum: IEnumVariant;
  // Anzahl der zurückgelieferten Elemente
  Fetched: Cardinal;
  // Der Empfänger des Collection-Objektes
  ResultItem: OleVariant;
begin
  // okay, einfach mal den XML DOM initialisieren
  Doc := CoDOMDocument40.Create;
  // XML file laden
  Doc.load('C:\Temp\hallo.xml');

  // und eine Liste von aller (x) Nodes erzeugen
  Nodes := Doc.selectNodes('.//*');
  // die Collection zurückgeben lassen
  Enum := Nodes._newEnum as IEnumVariant;

  // die Collection reseten (ist theoretisch beim ersten Durchlauf nicht nötig
  // sollte imho aber gemacht werden
  Enum.Reset;
  // das erste Element ermitteln
  //   der erste Parameter gibt an, wie viele Objekte zurückgeliefert werden
  //     sollen
  //   der zweite Parameter nimmt das Zielobjekt auf
  //     für diesen kann auch ein SafeArray von OleVariants übergeben werden
  //   der dritte Parameter gibt an, wieviele Objekte zurückgeliefert wurden
  //
  // die Übergabe von "1" für den ersten Parameter entspricht dem VB Konstrukt
  //   for each Item in Collection
  Enum.Next(1, ResultItem, Fetched);
  // Fetched muß also "1" sein, solange ein Element gefunden wird
  while Fetched = 1 do
  begin
    // jetzt auf das gewünschte Interface casten - dazu als erstes das IDispatch
    //   Interface ermitteln und dann das Ziel-Interface
    Node := IDispatch(ResultItem) as IXMLDOMNode;

    // und nun wie gewohnt arbeiten...
    ListBox1.Items.Add(Node.nodeName);

    // das nächste Element ermitteln und weiter im Job...
    Enum.Next(1, ResultItem, Fetched);
  end;
  // jetzt noch die Collection freigeben - oder einfach weglassen, dann tut
  //   Delphi dieses spätestens beim Verlassen der Prozedur
  Enum := nil;
end;
...:cat:...


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz