Autor Beitrag
fishhed
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 77


Delphi 7
BeitragVerfasst: Di 06.03.07 13:56 
Hallo zusammen,

hier noch ne Anfängerfrage zu DLLs:

Ich möchte eine DLL erstellen, die externe Komponenten (List&Label 11 von der Firma combit) verwendetet.

Geht das?

Hier mein Konkretes Beispiel. Ich möchte eine DLL haben die bei Aufruf genau das Gleiche ausführt, das passiert wenn man Button2 drückt. Ich möchte also dieses Mini-Programm in eine DLL umwandeln:
(Leider ist LL nicht openSource, von daher werdet Ihr es wohl nicht genau so ausprobieren können.)

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, l11, cmbtLL11, StdCtrls;

type
  TForm1 = class(TForm)
    LL: TL11_;
    Button2: TButton;
    procedure LLDefineVariables(Sender: TObject; UserData: Integer; IsDesignMode: Boolean; var Percentage: Integer; var IsLastRecord: Boolean; var EventResult: Integer);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.LLDefineVariables(Sender: TObject; UserData: Integer; IsDesignMode: Boolean; var Percentage: Integer; var IsLastRecord: Boolean; var EventResult: Integer);

begin
  LL.LlDefineVariable('vAnzahl', '2');
  LL.LlDefineVariable('vLizenzArt', 'Monatslizenz');
  LL.LlDefineVariable('vProdukt', 'AutoBINGOOO');
  LL.LlDefineVariable('vFirma', 'Autohaus Müller');
  LL.LlDefineVariable('vAnrede', 'Herr');
  LL.LlDefineVariable('vNachname', 'Müller');
  LL.LlDefineVariable('vStrasse', 'Tiefenseestr. 11');
  LL.LlDefineVariable('vPlz', '49696');
  LL.LlDefineVariable('vOrt', 'Molbergen');
  LL.LlDefineVariable('vLand', 'Deutschland');
  LL.LlDefineVariable('vStkPreis', '16,83');
  LL.LlDefineVariable('vBrutto', '20,00');
  LL.LlDefineVariable('vNetto', '35,66');
  LL.LlDefineVariable('MwST', '19');
  LL.LlDefineVariable('vLizkey', 'UWR70-FMQRE-GGGG-GGGG');
  LL.LlDefineVariable('vVon', '12.02.2007');
  LL.LlDefineVariable('vBis', '13.02.2008');
  LL.LlDefineVariable('vRechnungsnummr', 'ABM234567');

  if not IsDesignMode then begin
    Percentage := 100;
    IsLastRecord := true;
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
  CurPath: string;
  ExporterName: string;
  FileName: string;
begin

  LL.Print(0, LL_PROJECT_LABEL, 'Etiket2.lbl', false, LL_PRINT_EXPORT, LL_BOXTYPE_NORMALWAIT, handle, 'Print labels to printer', false, '');
  ShowMessage(IntToStr(handle));
end;

end.
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: Di 06.03.07 15:13 
Ich weiß jetzt nicht, ob man zum dynamischen Erstellen dieser Komponente eine Form braucht. Du musst halt die Komponente in der DLL dynamisch erstellen, ohne Formular.
fishhed Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 77


Delphi 7
BeitragVerfasst: Di 06.03.07 15:26 
user profile iconChryzler hat folgendes geschrieben:
Du musst halt die Komponente in der DLL dynamisch erstellen, ohne Formular.


Danke für den Tipp. Und wie geht das? Gibt es irgendwo eine kleine Anleitung oder ein Tutorial?
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: Di 06.03.07 16:18 
Zitat:

Wie kann ich Komponenten zur Laufzeit des Programms dynamisch erstellen?
von Sven Künzler 10. September 1998 [ab D1]
Man kann sämtliche Properties aus dem Designer auch im Quelltext setzen. Wichtig ist, dass man als Parent die Form angibt, auf der die Komponente erstellt werden soll.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Procedure TMyForm.Labelmachen;
var ALabel: TLabel
Begin
   { Self steht für die aktuelle Instanz von TMyForm }
   ALabel:=TLabel.Create(self);
   ALabel.Parent:=self;
   ALabel.Caption:='Beschriftung';
   ALabel.Visible:=True;
   {sonstige Properties setzen, z.B. für Position, Höhe und Breite}
End;


Wie du siehst, muss man dem Konstruktor und der Parent-Eigenschaft die Form zuweisen. Ich wüsste jetzt nicht wie man die irgendwie weglassen könnte. :?
Bei ner DLL gibts ja keine Forms.
fishhed Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 77


Delphi 7
BeitragVerfasst: Do 08.03.07 11:48 
Okay, das scheint mir logisch. Ich werde es mal ausprobieren...

Nun dazu eine weitere Frage:
Wie kann ich die Ereignisse einer Komponente verändern?
Im speziellen Fall möchte ich bei 'OnCreate' eine Prozedur ausführen.
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Do 08.03.07 12:00 
user profile iconChryzler hat folgendes geschrieben:
Wie du siehst, muss man dem Konstruktor und der Parent-Eigenschaft die Form zuweisen. Ich wüsste jetzt nicht wie man die irgendwie weglassen könnte. :?
Bei ner DLL gibts ja keine Forms.
Erstell doch in der Bibliothek eine Methode, welcher du das Formular übergeben kannst, auf welchem die Komponente erstellt werden soll. Dieses [Formular] kannst du ja global speichern.

Zu deiner letzten Frage:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure MyOnCreate(Sender: TObject);
begin
  ShowMessage('HALLo');
end;

//irgendwo in einer Methode...
  {Form1.}OnCreate := MyOnCreate;
Gruß Hape!
fishhed Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 77


Delphi 7
BeitragVerfasst: Do 08.03.07 12:20 
Hmm, ich habe es probiert. Bei mir lässt sich der DLL-Code nicht kompilieren.
Fehlermeldung: "Undefinierter Bezeicherner 'MyOnClick'".

Was mache ich falsch? Hier der komplette Quelltext:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
library dllPdf;

uses
  SysUtils,
  Classes,
  l11,
  cmbtLL11,
  Controls,
  StdCtrls,
  Dialogs,
  Forms,
  Windows;

{$R *.res}
var
  Form1: TForm;

function erzeugePdf(sName: string): PChar; stdcall;
begin
  Form1 := TForm.Create(nil);
  Form1.Show;
  Form1.OnClick := MyOnClick;

  Result := 'abgeschlossen';
end;
exports
  erzeugePdf;

procedure MyOnClick(Sender: TObject);
begin
  ShowMessage('HALLO');
end;

begin
end.
fishhed Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 77


Delphi 7
BeitragVerfasst: Do 08.03.07 12:43 
Okay, habe es selber hinbekommen. Danke für eure Hilfe!

Das war die Lösung:

ausblenden Delphi-Quelltext
1:
Form1.OnClick := Form1.MyOnClick;					
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Do 08.03.07 15:02 
Wie es gibt keine Forms in DLLs ? Mach ich da jetzt irgendwas falsch, weil ich x-viele Forms in DLLs habe ? Und die auch alle wunderbar funktionieren? :shock:

Mal ernsthaft.. ich habe noch nie eine visuelle oder nicht visuelle Komponente getroffen, die sich drüber beschwert hat, nicht auf einem Form erzeugt wurden zu sein. Keine halbwegs vernünftig programmierte Komponente würde das tun, da man ja auch mit einem nil-owner erzeugen kann. In Deiner Routine "ErzeugePdf" brauchst du keine Form, erzeuge einfach Deine List&Label-Komponente und mach, was du machen willst. Zumindest mir scheint es so, als würde die Funktion des Pdfs erzeugen nicht-visuell zu sein (im Gegensatz zum Ergebnis :P)

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Fr 09.03.07 14:31 
user profile iconHelgeLange hat folgendes geschrieben:
Mal ernsthaft.. ich habe noch nie eine visuelle oder nicht visuelle Komponente getroffen, die sich drüber beschwert hat, nicht auf einem Form erzeugt wurden zu sein.
Was macht ein Button ohne Form für einen Sinn? :?

Gruß Hape!
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Fr 09.03.07 16:03 
ich rede nicht von Sinn oder Unsinn, sondern ob es möglich ist oder nicht. Und man kann einen Button erzeugen, ohne ihn auf ein Form zu legen. und wenn ich das richtig sehe, dann nimmt er den Button ja nur, um das Print anzuschubsen. Kann er ja auf seiner form weiterhin machen, aber eben statt dem print anschubsen einfach in die DLL gehen und es dort anschubsen, richtig?

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Chryzler
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1097
Erhaltene Danke: 2



BeitragVerfasst: Sa 10.03.07 13:09 
user profile iconHelgeLange hat folgendes geschrieben:
ich rede nicht von Sinn oder Unsinn, sondern ob es möglich ist oder nicht. Und man kann einen Button erzeugen, ohne ihn auf ein Form zu legen. und wenn ich das richtig sehe, dann nimmt er den Button ja nur, um das Print anzuschubsen. Kann er ja auf seiner form weiterhin machen, aber eben statt dem print anschubsen einfach in die DLL gehen und es dort anschubsen, richtig?

Yep.
Wusste nicht, dass man als Owner einfach nil nehmen kann. Wenn nämlich die Kompo auf sein Parent zugreift, dann gibts ne schöne Access Violation.
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Sa 10.03.07 13:34 
Komponenten baut man so, dass sie NIChT auf ihren parent zugreifen, wenn diser Nil ist. Das gleiche gilt übrigends auch für den Owner oder andere Member-Objeckte :P

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
guido
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22

ME
Delphi 3 / 5
BeitragVerfasst: Do 13.08.09 05:41 
Hallo,

habe das selbe Problem, bin nur leider nicht in der Lage das Ergebnis meines "Vorposters" nachzuvollziehen.

- DLL erzeugt Formular , Darauf kommt ein Button mit Parent"Formular" der bei OnClick eine Prozedur oder Funktion anspringen soll..

Code:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
//....

Procedure erzeuge_Formular;
begin
  Formular := TForm.Create(nil);
  Formular.Show;

  MyButton:=TButton.create(Formular);
  Mybutton.top:=10;
  Mybutton.left:=10;
  Mybutton.show;
  Mybutton.OnClick:=formular.MyOnCLick;    //= Fehler 'undefinierter Bezeichner...'

end;

Procedure MyOnClick;
begin
  ShowMessage('HALLO');
end;

begin

end.

Auch wenn ich die Prozedur oben mit "formular.mybutton.click=MyOnClick" definiere passiert nix. Mit fehlt da wohl ein "Anstoss...". Hab versucht diverse Interntergenisse nachzuvollziehen, leider ohne Erfolg.

Gruss
Guido

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.08.09 09:54 
Das Ereignis erwartet eine Methode, d.h. eine Prozedur innerhalb einer Klasse (z.B. einer Formularklasse). Denn da wird anders als bei normalen Prozeduren noch ein Zeiger auf das Objekt mitgeführt, zu dem die Methode gehört.

Ohne Klasse kann die Zuweisung so also auch nicht gehen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 18.08.09 03:37 
Auf Rückfrage per PN einmal noch eine kleine Ergänzung:
Es gibt einen Unterschied zwischen einer normalen Prozedur:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure Foo(Sender: TObject);
begin

end;
Und einer Methode einer Klasse:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  TFoo = class
  private
    procedure Foo(Sender: TObject);
  end;

...
implementation
...

procedure TFoo.Foo(Sender: TObject);
begin

end;
Wenn du jetzt eine solche Methode an OnClick zuweist, dann wird dabei auch ein Zeiger auf die Instanz der Klasse (hier TFoo) mit gespeichert. So dass du innerhalb deiner Methode mit Self z.B. auf diese Instanz zugreifen kannst.

Wenn du eine normale Prozedur hast wie im ersten Beispiel, dann hast du ja kein zugehöriges Objekt. OnClick-Ereignisse müssen aber eines haben. Und deshalb funktioniert die Zuweisung nicht.

Du musst also eine eigene Klasse deklarieren wie im zweiten Beispiel und dann eine Instanz davon erzeugen. Die Methode aus der Instanz der Klasse, dem Objekt im Speicher also) kannst du dann dem OnClick-Ereignis zuweisen.