![]() |
Aus DLL auf Prgramm zugreifen
Ich brauche eure Hilfe! Ich habe schon die ganze DP durchsucht, aber nie die konkrete Antwort auf mein Problem:
Aus meiner Anwendung heraus wird eine procedure aufgerufen (aus einer DLL), die ein Formular erzeugt und es anzeigt, aber nicht ShowModal! Die DLL wird dynamisch erzeugt und nach erfolgreichem Ausführen der "Startprocedure" in der DLL die Caption eines in der Anwendung vorkommenden Labels auf 'Gestartet' gesetzt. Wenn das DLL-Formular geschlossen wird, soll es das irgendwie der Anwendung mitteilen oder direkt die Caption des Labels auf 'Geschlossen' setzen. Ich hab's selbst schon mit der Übergabe von Pointer, dem label selbst... versucht, aber es hat nie geklappt! Könnt ihr mir sagen, wie ich das machen kann? |
Re: Aus DLL auf Prgramm zugreifen
das sollte eigentlich so gehen... an sonsten mach es über eine windows-message, die zu abschluss gefeuert wird.
|
Re: Aus DLL auf Prgramm zugreifen
Oder du machst einen Callback rein.
|
Re: Aus DLL auf Prgramm zugreifen
Könnt ihr mal n Beispiel geben? :shock:
|
Re: Aus DLL auf Prgramm zugreifen
[delphi]//dll: ganz am ende:
SendMessage(Form2.Handle, succ(WM_USER), myDATA, myDATA); // hauptprogramm: interface: procedure myProc(var msg: TMessage); message succ(WM_USER); // hauptprogramm: code: procedure TForm2.myProc(var msg: TMessage); begin ShowMessage(inttostr(msg.LParam)); end; |
Re: Aus DLL auf Prgramm zugreifen
Das funktioniert aber nur, wenn die DLL nur von einem Prozess benutzt wird. Ich würde mir mal das DLL Tutorial von Assarbad ankucken:
![]() |
Re: Aus DLL auf Prgramm zugreifen
@luckie: meinst du, weil die dll es nicht auf die Reihe bekäme, sich zwei verschiedene Form.Handles merken könnte, oder was ganz anderes?
|
Re: Aus DLL auf Prgramm zugreifen
Die DLL wird nur entladen, wenn kein Prozess sie mehr benutzt. Führts du den Code nur beim Entladen aus, dann trifft meine Aussage zu. Man muss den Code dann ausführen, wenn sie von einem Prozess entladen wird. dazu muss man seine eigene DLLProc einsetzten und auf DLL_UNDETACHE oder wie das heißt reagieren.
|
Re: Aus DLL auf Prgramm zugreifen
mann muss es ja nicht beim entladen machen. reicht ja vollkommen, wenn man es immer dann aufruft, wenn der codeabschnitt, der durchgeführt werden soll, damit sich was ändert (siehe allererste post des fragestellers) durchgelaufen ist.
|
Re: Aus DLL auf Prgramm zugreifen
Zitat:
Du mußt hier sehr deutlich zwischen DLL und Anwendung unterscheiden. Das bitte ich dich mal zu tun um hier dein Problem herauszustellen. Ich kann jedenfalls noch immer dein Problem nicht verstehen. Ich denke dies ließe sich einfach lösen, aber ich will hier nicht Rätselraten. Es ist nun an dir. |
Re: Aus DLL auf Prgramm zugreifen
Ok, sorry!
Meine Anwendung und meine DLL haben 1 Form. Die Anwendung besteht aus einer Liste, in die alle DLLs gelesen werden, die sich im Ordner befinden. Alle DLLs haben mindest. 2 Proceduren, GetInhalt und StartDLL. Mit GetInhalt fragt die Anwendung beim Verzeichnischeck nach dem Inhalt der DLLs, quasi wie ein About, das die jeweilige DLL als String (PChar) zurückgibt. Später kann man dann aus der Liste in der Anwendung eine DLL auswählen und sie wird mit StartDLL gestartet und läuft dann selbstständig (weil nicht Modal), bis sie oder die Andwendung beendet wird. Das Prob: In der Liste wird ihr Handle gespeichert, dadurch kann sie von der Anwendung beendet werden. Wenn man jetzt aber am Formular der DLL Beenden anklickt, soll in der Liste das Handle zurückgesetzt werden (standartmäßig 0) und ein SubItem (Liste ist TListView) wird statt mit 'gestartet' mit 'nicht gestartet' o.ä. beschriftet. :angel2: |
Re: Aus DLL auf Prgramm zugreifen
Aha, so langsam steige ich dahinter was du willst. Dann solltest du IMO folgendes machen.
StartDLL erzeugt ein Event/Mutex/... im Kontext der Anwendung und gibt das Handle zurück (StartDLL gibt also 1 Handle zurück). Dieses Event wird beim Entladen der DLL gepulst (PulseEvent()) und ein Thread (vorzugsweise der, der die DLl geladen hat) in der Hauptanwendung Wartet mit WaitForSingleObject() auf eben diesen Puls. Schon wissen beide Instanzen bescheid. Der wartende Thread kann dann dem Hauptform bescheidgeben, daß die DLL entladen ist und dieses kann den Status updaten. Warum benutzt du aber eine eigene Func StartDLL() und nich direkt den Einsprungspunkt der DLL? |
Re: Aus DLL auf Prgramm zugreifen
Ich habe mir über nichts gedanken gemacht, die Sachen, die du aufgezählt hast, sagen mir alle nicht viel.
Die Procedure StartDLL erzeugt nur die Form und zeigt sie an, danach kümmert sie sich. Es sollte quasi ein Starter werden, mit dem man die Sachen verwalten kann. Die DLLs waren zwar wie Plugins, liefen aber nach dem Start selbst ständig, ich könnte die StartDLL auch anders nennen... Gibts da nicht noch was einfacheres? |
Re: Aus DLL auf Prgramm zugreifen
Es geht IMO nicht einfacher. Im Endeffekt müssen beide miteinander kommunizieren. Bei WMs hätte ich nur Bedenken, daß die nicht mehr abgesetzt werden, weil die DLL sich entlädt (ist aber nur eine Befürchtung). Versuch es halt mit WMs - wenn's nicht geht nimmste Mutexe o.ä.
|
Re: Aus DLL auf Prgramm zugreifen
Na gut, ic werd' mal sehen, tüfteln und ausprobieren! :coder2:
|
Re: Aus DLL auf Prgramm zugreifen
Alternativ kannst du eine vereinfachte Version der Sourcen der DLL und der EXE hier reinstellen. Irgendjemand wird sich vermutlich erbarmen. Ab Montag auch ich wieder :-D
|
Re: Aus DLL auf Prgramm zugreifen
Nehmen wir mal ein vergleichbares einfacheres (aber sinnloses) Szenario: Die Anwendung hat ein TRichEdit und ein Editfeld.
Um den String aus dem Editfeld in das Richedit formatiert einzufügen ruft die Anwendung eine Procedure der DLL auf und übergibt ihr den String und irgendwas, (KEINE AHNUNG WAS!) damit die DLL Zuhriff auf das RichEdit der Anwendung hat. Dann formatiert die DLL den String über das RichEdit und fügt ihn ein:
Delphi-Quellcode:
Wie das realisieren?
TheRichEdit.SelAttributes.Color := clred;
TheRichEdit.SelAttributes.Name := 'Courier New'; TheRichEdit.SelAttributes.Size := 10; TheRichEdit.SelAttributes.Style := [fsBold]; TheRichEdit.Lines.Add(S); Danke! |
Re: Aus DLL auf Prgramm zugreifen
Liste der Anhänge anzeigen (Anzahl: 1)
Siehe Anhang
Delphi-Quellcode:
// DLL-Code
function GetRichEditSetEdit(Rich:TRichEdit; Edit:TEdit):Boolean; var s : String; begin s := Edit.Text; Rich.SelAttributes.Color := clred; Rich.SelAttributes.Name := 'Courier New'; Rich.SelAttributes.Size := 10; Rich.SelAttributes.Style := [fsBold]; Rich.Lines.Add(S); Rich.Lines.Text := s; end;
Delphi-Quellcode:
Aber dieses Problem ist um einiges einfacher zu lösen als o.g. - oder???
// EXE-Code
function GetRichEditSetEdit(Rich:TRichEdit; Edit:TEdit):Boolean;external 'Dingens.dll'; // TEdit == Pointer // TRichEdit == Pointer // Beide sind schließlich nur Instanzenpointer ... also kann man sie übergeben. // Die aufgerufene Funktion muß nur über das Objekt bescheidwissen. Also immer // DLL und EXE mit gleicher Delphi-Version kompilieren!!! procedure TForm1.Button2Click(Sender: TObject); begin GetRichEditSetEdit(RichEdit1, Edit1); end; Theoretisch kann man die Objektinstanzen auch typecasten - dazu verwendest du den AS-Operator |
Re: Aus DLL auf Prgramm zugreifen
Endlich es funktioniert!!! :cheers: :witch: :dancer2: :hello:
Das reicht, damit sich die DLL selbst kümmert. Sie sucht jetzt im Listview nach ihrem Handle eintrag und setzt den Eintrag auf Gestoppt! Den darum ging es mir ja! :warn: |
Re: Aus DLL auf Prgramm zugreifen
Hallo nochmal!
:arrow: Ich überarbeite gerade ein Programm komplett. Und wollte die Variante mit der DLL benutzen, da dieser Teil oft in Updates drinstecken wird und da macht sich das mit DLLs einfach praktischer. Dieses Mal ist es wie im Beispiel, ein RichEdit in den Text eingefügt werden soll. Aber der Text steht nicht in einem String, sondern in einem Stream. Es wird also das RichEdit und der Stream übergeben (und das Hauptformular, weil geprüft wird, ob es sichtbar ist). Die DLL soll den String aus dem Stream lesen und ihn in das RichEdit einfügen, ans Formatieren denke ich momentan noch nicht. Das Problem liegt jetzt darin, dass er nach der 1. zeile einfach aufhört die Anweisungen der Procedure abzuarbeiten:
Delphi-Quellcode:
:warn: IMHO ist das wieder so ein Problem, wo man alles machen kann was man will, aber es nicht zum laufen bekommt, den ganzen Quelltext in ein neues Projekt kopieren... Würde nicht funktionieren. Nur wenn man sich eine Stunde hinsetzen würde und alles nochmal abtippen würde, dann würde wahrscheinlich alles gehn! :kotz:
(***************Ausschnitt aus der DLL***************)
procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream); export; stdcall; procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream); var I: Integer; I64: Int64; Kennung: Char; S: String; begin St.Seek(0, soFromBeginning); //<- Die Zeile macht er immer ohne Probleme St.ReadBuffer(Kennung, 1); //<- Diese Zeile macht er nicht mehr, aber er zeigt keinen Fehler an! if Kennung = 'T' then begin St.ReadBuffer(I, SizeOf(I)); St.ReadBuffer(S[1], I); RE.Lines.Add(S); Melden(MainForm); end else if Kennung = 'C' then begin St.ReadBuffer(I, SizeOf(I)); { ... } end else if Kennung = 'B' then begin St.ReadBuffer(I64, SizeOf(I64)); { ... } end; end; //Und so wird alles aufgerufen: (***************Ausschnitt aus dem programm***************) TGetMsg = procedure(RE: TRichEdit; MainForm: TForm; St: TStream); procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream); stdcall; procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream); var GM: TGetMsg; H: Cardinal; begin if not FileExists(Main.Pfad+'DLL_Messaging.dll') then begin Beep; Exit; end; H := LoadLibrary(PChar(Main.Pfad+'DLL_Messaging.dll')); if H <> 0 then begin @GM := GetProcAddress(H, 'GetMsg'); if @GM <> NIL then begin GM(RE, MainForm, St); end; FreeLibrary(H); end; end; procedure TMain.ServerExecute(AThread: TIdPeerThread); var I: integer; St: TStream; begin I := AThread.Connection.ReadInteger; if I > 0 then begin St := TMemoryStream.Create; try AThread.Connection.ReadStream(St, I); GetMsg(Main.RE, Main, St); finally St.Free; end; end; end; Bitte helft mir, ich bin ratlos! |
Re: Aus DLL auf Prgramm zugreifen
Einen weiteren Fehler habe ich inzwischen gefunden:
Delphi-Quellcode:
Allerdings, weil ich die hier ausgeführten Zeilen ins Programm geschrieben habe. Dort funktioniert es zwar, nütz mir aber nichts!
procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream);
{ ... } if Kennung = 'T' then begin St.ReadBuffer(I, SizeOf(I)); [color=#ff0000] SetLength(S, I);[/color] St.ReadBuffer(S[1], I); RE.Lines.Add(S); Melden(MainForm); { ... } |
Re: Aus DLL auf Prgramm zugreifen
Hallo,
ich habe heute mal das Beispiel von Assarbad genommen weil ich genau so einen Fall habe. Nur leider bringt er mir bei compilieren der Dll den Fehler das TEdit ein undefinierter Bezeichner ist. BeimRichEdite genau dasselbe. Hab ich was in der Uses vergessen oder an was könnt das liegen? Gruß Arma |
Re: Aus DLL auf Prgramm zugreifen
Jepp, du hast bestimmt in der Uses-Liste die Units der beiden Compos vergessen!
TEdit >> StdCtrls TRichEdit >> ComCtrls |
Re: Aus DLL auf Prgramm zugreifen
Danke F.W.
genau das war's hab es vorhin selbst bemerkt. Trotzdem Danke. :-) |
Re: Aus DLL auf Prgramm zugreifen
Guten morgen alle Früh-aufsteher :D oder Spät-ins-Bett-geher :D
Ich hätte nicht geglaubt, dass ich zu meinem heutigen Problem was in der Suche finde (ich tu mich irgendwie mit der Bezeichnung meiner Probleme schwer, oder mit den Schlagworten in der Suche). Aber ich hab was gefunden, und nicht irgendeinen Beitrag, sondern gerade auch noch einen von mir selbst :D Problem: In ![]()
Delphi-Quellcode:
Das ist die Stelle mit der ich mein jetziges Problem mit diesem Thread verbinde! Bloß dass der Dll jetzt mal keine Beachtung geschenkt werden soll.
procedure GetMsg(RE: TRichEdit; MainForm: TForm; St: TStream);
{ ... } St.Seek(0, soFromBeginning); //<- Die Zeile macht er immer ohne Probleme St.ReadBuffer(Kennung, 1); //<- Diese Zeile macht er nicht mehr, aber er zeigt keinen Fehler an! Ich arbeite in einer Procedure mit einem TFileStream. Zwischendurch soll ein Position in ihm gesucht werden, da das auch an anderen Stellen des Programms geschieht, ist der Teil in einer Funktion ausgelagert, dem der Stream als Parameter übergeben wird. Nach dem Aufruf der Funktion ist mein Stream aber weg oder was auch immer ?? Mal Stückchen Quellcode:
Delphi-Quellcode:
Ich habe mal etwas probiert:
//soviel zum Aufruf:
var FS: TFileStream; begin if GetStartDataPosition(FS) = -1 then begin //... //das ist die aufgerufene Funktion: function TMainForm.GetStartDataPosition(S: TFileStream): Integer; var Buffer: String; begin Result := -1; //schauen ob [ENDE] als letztes im Stream steht S.Seek(-Length(EndString), soFromEnd); SetLength(Buffer, Length(EndString)); S.ReadBuffer(Buffer, Length(EndString));// << böse Stelle << // ... end; Wenn in der Funktion nur S.Seek drinsteht, geht nachher noch alles. Sobald ich aber S.ReadBuffer ausführe kann ich mit FS (von oben, in der aufrufenden Procedure) nicht mehr weiterarbeiten. Das lustige dabei ist aber, innerhalb von GetStartDataPosition kann ich nach S.ReadBuffer noch arbeiten Kann mir das jemand erklären warum das so ist und was man dagegen machen kann? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:04 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