Einzelnen Beitrag anzeigen

bierwart

Registriert seit: 15. Okt 2006
Ort: Geldern
3 Beiträge
 
Delphi 7 Professional
 
#5

Re: COM Events und Threads - Problem

  Alt 24. Mär 2008, 15:12
O.K.,
habe ich verstanden, jedoch

a) Wie bekomme ich die Instanz des Interface Zeigers im Primär Thread ?
b) Wie jedoch bekomme ich dann den Schritt vom "korrektem Interfacezeiger" zum Zünden des Events in diesem
Kontext hin ? Zur Zeit wird das Event durch Verknüpfung mit einem Formular Event gezündet.

Habe mal probiert meine "Button-Methode" entsprechend umzuschreiben um mein Problem aufzuzeigen
(obwohl diese ja nur im Primär Thread läuft )

Delphi-Quellcode:
procedure TForm1.btnNavtestClick(Sender: TObject);
var XMLDoc : IXMLDocument;
    XMLDoc_RESP : IXMLDocument;
    SizeOfIncoimingStream : Integer;
    sFileName : string;
    sFilePath : string;
    sFilePathName : string;
begin

  RequestType := 'FLATFILE';
  sWorkingDirectory := Ini.GetWorkingPath;
  sFileCreationDate := FormatDateTime('ddmmyyyy',date)+FormatDateTime('hhnnss',now)+'_';
  XMLDoc := CreateXMLDoc;

  sFilePathName := Ini.GetIniFilePathName;
  sFileName := ExtractFilename(sFilePathName);
  CopyFileTo(sFilePathName,(sWorkingDirectory+sFileCreationDate+sFileName));

  Ini.GetXMLFile((sFileCreationDate+sFileName),XMLDoc,RequestType);
  XMLDoc.Save(sWorkingDirectory+sFileCreationDate+sFilename +'.XML');
  XMLDoc.load(sWorkingDirectory+sFileCreationDate+sFilename +'.XML');

  // Aktualisierung der Übergabe XML mit Pfadangabe
  XMLManagement.AddWorkingDirToXML(XMLDoc,sWorkingDirectory);

  NAV_XMLOut := XMLDoc;


  // Verarbeitung in Navision ******************************
  //SendDataToNavision(XMLDoc,XMLDoc_RESP);

  // <-- Aufruf muss im Primär Thread erfolgen, z.B.Thread.create, Wie bekomme ich die Instanz von FOLEInterface ?
  OLECheck(CoMarshalInterThreadInterfaceinStream(IOLEInterface,FOLEInterface,ISTREAM(FStream)));

  // <-- Aufruf im Sekundär Thread, Zeiger anschliessend in FOLEInterface
  OLECheck(CoInitialize(nil));
  OLECheck(CoGetInterfaceandReleaseStream(ISTREAM(FStream),IOLEInterface,FOLEInterface));

  // --> Hier Zünden des Events Im Kontext von FOLEInterface nötig ???
  

  CoUnInitialize;
  // **************************************************

end;

Zur Zeit erfolgt der Aufruf des Events über ein Event des Formulars. Was ich ja benötigen würde
wäre wohl die "AutoFactory.EventIID" ??

Delphi-Quellcode:
procedure TOLEInterface.Initialize;
begin
  inherited Initialize;
  FConnectionPoints := TConnectionPoints.Create(Self);
  if AutoFactory.EventTypeInfo <> nil then
    FConnectionPoints.CreateConnectionPoint(
      AutoFactory.EventIID, ckMulti, EventConnect);
  Form1.NewDataAvailable := self.Ev_NewXMLData_All; //Event verknüpfen
end;

procedure TOLEInterface.Ev_NewXMLData_All(Sender : TObject);
var
  aEnum : IEnumConnections;
  aCData : TConnectData;
  aSink : IUnknown;
  iFetch : Cardinal;
  OLEInVariant : OLEVariant;
  OLEOutVariant : OLEVariant;
  XMLOut : IXMLDocument;
  XMLIn : IXMLDocument;
  XMLOutStream : TMemoryStream;

begin
  aEnum := GetConnectionEnumerator(self);
  If aEnum <> Nil Then begin
    XMLOutStream := TMemoryStream.Create;
    Form1.GetXMLOut(XMLOut);
    XMLOut.SaveToStream(XMLOutStream,ofNone);
    XMLOutStream.Position := 0;
    OLEOutVariant := StreamToOleVariant(XMLOutStream, XMLOutStream.Size);

    while aEnum.Next(1,aCData,@iFetch) = S_OK do begin
      aSink := aCData.pUnk;
      If Assigned(aSink) Then
        //(aSink as IOLEInterfaceEvents).NewXMLData(OLEOutVariant,OLEInVariant);
        (aSink as IOLEInterfaceEvents).NewXMLData(OLEOutVariant);
    end;
  end;
end;

function TOLEInterface.GetConnectionEnumerator(FOLEInterface : IOLEInterface) : IEnumConnections;
var
  aCPC : IConnectionPointContainer;
  aCP : IConnectionPoint;
begin
  Result := nil;
  OLECheck(FOLEInterface.QueryInterface(ICOnnectionPointContainer,aCPC));
  OLECheck(aCPC.FindConnectionPoint(AutoFactory.EventIID,aCP)); //<----- !!
  aCP.EnumConnections(Result);
end;
  Mit Zitat antworten Zitat