Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Interface-Events aus Typbibliothek zum Laufen bringen (https://www.delphipraxis.net/176014-interface-events-aus-typbibliothek-zum-laufen-bringen.html)

fedcba 6. Aug 2013 18:27

Interface-Events aus Typbibliothek zum Laufen bringen
 
Hallo liebes Forum,

ich habe heute ein großes Delphi Programm vorgesetzt bekommen. Es kommuniziert mit einer .dll mit anderen Programmen.

Ich habe die .dll in das Projekt eingefügt und erhalte 3 Interfaces mit verschiedenen Funktionen und Prozeduren.

Ein Interface davon enthält alle Events, die auftreten können (z.B. function ScanModeChanged(NewState: WideString): Integer;)

Ein weiteres Interface alle Prozeduren, die aufgerufen werden können. Da gibt es auch ein Objekt im Programm.

Jetzt möchte ich im Programm bei Eintritt des Events gerne eine eigene Prozedur aufgerufen haben:

Delphi-Quellcode:
procedure ScanModeChanged(NewState: WideString);
begin
  ...
end;
Aber wie mache ich das? Es sollte ja möglichst wie ein Event abgearbeitet werden...

Ich hab mir überlegt:

Delphi-Quellcode:
Events: IEvents;
...

implementation

OnFormCreate
begin
  Event := Events.MeinEvent;
end;

Event
begin
end;
Da gibt es aber Probleme, weil ja MeinEvent eine function und Event eine procedure... undso...

Ich hoffe ihr versteht mein Problem und könnt mir helfen. Ich kenne mich in Delphi nicht sonderlich aus, bin eher der C#ler

Grüße

Sir Rufo 6. Aug 2013 18:33

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Auch mit C# würdest du für die Beantwortung der Frage mehr Informationen benötigen.

Wie wäre es, wenn du die echte Interface-Deklaration hier postest?

Achja, und Pseudocode ist hier generell auch schlecht, weil es bei DLL auch um Aufrufkonventionen geht.
Delphi-Quellcode:
stdcall
oder
Delphi-Quellcode:
cdecl
oder nix ist ein großer Unterschied

Bernhard Geyer 6. Aug 2013 18:40

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Ich komm mit http://www.techvanguards.com/products/eventsinkimp/ immer ganz gut zurecht.
Der "bastelt" aus einer Event-Interface eine Delphi-komponente.

fedcba 6. Aug 2013 19:42

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Hallo,

danke für die Antworten erst einmal.

ich habe die richtigen Deklarationen momentan nicht da, ich werde sie morgen reinstellen...

Aus der Erinnerung sah die Deklaration ungefähr so aus:

Delphi-Quellcode:
IEvents = interface (IDispatch)
    function Foo (Result: WideString): HRESULT; stdcall;
    function Foo2 (Result: WideString): HRESULT; stdcall;
    ...
end;
Vielleicht hilft dir das schon erst einmal? Was macht denn eigentlich stdcall, cdecl oder nichts?

sx2008 6. Aug 2013 20:27

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Wenn es sich um ein Dispatch-Interface handelt, dann hast du Glück gehabt denn Delphi kann mit Bordmitteln nur auf
Delphi-Quellcode:
IDispatch
basierende Events verarbeiten.
Falls nicht siehe Beitrag #3.

Beim Importieren der Typbibliothek muss man sich eine Komponente erzeugen lassen.
In diese Komponente gibt es dann normale Delphi Events, die du z.B. auf einem Form oder Datenmodul benützen kannst.

fedcba 7. Aug 2013 10:06

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Hallo,

Delphi-Quellcode:
IS7ProSimEvents = interface(IUnknown)
    ['{********-****-****-****-************}']
    function ScanFinished(ScanInfo: OleVariant): HResult; stdcall;
    function ConnectionError(const ControlEngine: WideString; Error: Integer): HResult; stdcall;
    function PLCSimStateChanged(const NewState: WideString): HResult; stdcall;
    function PauseStateChanged(const NewState: WideString): HResult; stdcall;
    function ScanModeChanged(const NewState: WideString): HResult; stdcall;
  end;
Ich habe versucht, mit dem EventSinkImp daraus was zu erstellen und erhalte eine veränderte S7PROSIMLib_TLB.pas und eine S7PROSIMLibEvents.pas. Die verwende ich im Programm (uses ...).
So. Jetzt habe ich in der Events.pas:

Delphi-Quellcode:
//SinkEventsForwards//
  TIS7ProSimEventsPLCSimStateChangedEvent = function (Sender: TObject; const NewState: WideString): HResult of object;

...

TS7PROSIMLibIS7ProSimEvents = class (TS7PROSIMLibEventsBaseSink
    , IS7ProSimEvents
  )
protected
    function IS7ProSimEvents.PLCSimStateChanged = DoPLCSimStateChanged;
...
protected
    //SinkInterface//
    DoPLCSimStateChanged(const NewState: WideString): HResult; stdcall;
...
protected
    //SinkEventsProtected//
    FPLCSimStateChanged: TIS7ProSimEventsPLCSimStateChangedEvent;
...
published
    //SinkEventsPublished//
    property PLCSimStateChanged: TIS7ProSimEventsPLCSimStateChangedEvent read FPLCSimStateChanged write FPLCSimStateChanged;

...

implementation

...

function TS7PROSIMLibIS7ProSimEvents.DoPLCSimStateChanged(const NewState: WideString): HResult;
begin
  Result := S_OK;
  if not Assigned (PLCSimStateChanged) then System.Exit;
  Result := PLCSimStateChanged (Self, NewState);
end;
und das Event, ebenso wie die anderen, möchte ich jetzt im Hauptprogramm haben...

Ich habe so etwas probiert:

Delphi-Quellcode:
S7ProSimPLCSimStateChanged := S7PROSIMLibEvents.TIS7ProSimEventsPLCSimStateChangedEvent;
Delphi-Quellcode:
procedure TMainForm.S7ProSimPLCSimStateChanged(Sender: TObject;const NewState: WideString);
begin
  ...
end;
Funktioniert irgendwie nicht:
E2035 Nicht genügend wirkliche Parameter

Was mache ich falsch?

Sir Rufo 7. Aug 2013 12:05

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Liegt wohl daran, dass hier sowas erwartet wird ;)
Delphi-Quellcode:

function (Sender: TObject; const NewState: WideString): HResult of object;
Zur weiteren Erklärung:

Intern wird eine function als procedure verarbeitet, wobei der Result als zusätzlicher Parameter behandelt wird.
Daher kommt der Fehler "Nicht genügend wirkliche Parameter"

fedcba 7. Aug 2013 15:00

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Ich bin in der _TLB.pas jetzt über folgendes gestolpert:

Delphi-Quellcode:
TS7ProSimPLCSimStateChanged = procedure(ASender: TObject; const NewState: WideString) of object;
...

TS7ProSim = class(TOleServer)
  private
    FOnPLCSimStateChanged: TS7ProSimPLCSimStateChanged;
    ...
  published
    property OnPLCSimStateChanged: TS7ProSimPLCSimStateChanged read FOnPLCSimStateChanged write FOnPLCSimStateChanged;
    ...
Das ist doch schon ein Event-Handler, soweit ich das jetzt in Delphi verstanden habe, oder? Da könnte man mit
Delphi-Quellcode:
if Assigned(FOnPLCSimStateChanged) then FOnPLCSimStateChanged(...);
eigentlich schon das Event aufrufen, richtig?

Blöd ist nur, dass ich jetzt nicht so etwas machen kann:
Delphi-Quellcode:
S7ProSim.OnPLCSimStateChanged := S7ProSimPLCSimStateChanged
E2003 Undeklarierter Bezeichner: 'OnPLCSimStateChanged'

stahli 7. Aug 2013 17:14

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Ist denn S7ProSim überhaupt eine Instanz von TS7ProSim?
Dann sollte OnPLCSimStateChanged bekannt sein...

fedcba 8. Aug 2013 18:21

AW: Interface-Events aus Typbibliothek zum Laufen bringen
 
Ja... Richtig... Hab statt dem T nichts gehabt... :oops:

Toll. Alle Prozeduren stürzen mit einer Exception ab (adress violation).

Falls ihr eine Idee habt, ich werde sie definitiv probieren.

Wenn nicht, auch nicht schlimm. Ich hab mich entschlossen, das ganze Programm einfach in C# neu zu schreiben. Kann bei uns in der Firma eh keiner so richtig Delphi/Pascal.

Vielen Dank für eure Hilfe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 Uhr.
Seite 1 von 2  1 2      

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 by Thomas Breitkreuz