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;