Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Actions in einer anderen Unit definieren (https://www.delphipraxis.net/199065-actions-einer-anderen-unit-definieren.html)

Int3g3r 21. Dez 2018 10:50

Delphi-Version: 10.1 Berlin

Actions in einer anderen Unit definieren
 
Guten Tag,

Ich möchte eine seperate Unit erstellen in dieser sollen nur Actions drin stehen. Diese möchte ich nachher bei allen anderen Units einbinden bei denen ich die Actions benötige.

z.b:
Im Objektinspektor unter Ereignisse kann ich z.b OnActivate Ereigniss erstellen. Hier öffne ich die DB.

Delphi-Quellcode:
procedure THauptprogramm.FormActivate(Sender: TObject);
begin
dm.QryKalDat.Open;
dm.QryKalRes.Open;
end;
Delphi-Quellcode:
unit ActionsOnly;

interface

      procedure Action1Execute(Sender: TObject);

implementation


procedure ActionsOnly.Action1Execute(Sender: TObject);
begin
dm.QryKalDat.Open;
dm.QryKalRes.Open;
end;

end.
Wie lässt sich diese procedure nun in einer anderen Unit definieren damit ich sie nachher bei dem "OnActivate" Ereigniss(im Objektinspektor) auswählen kann ?

Der schöne Günther 21. Dez 2018 11:06

AW: Actions in einer anderen Unit definieren
 
Mach keine einfache Unit sondern ein Datenmodul (
Delphi-Quellcode:
TDataModule
). Pack dort deine
Delphi-Quellcode:
TActionList
drauf und mache dort deine Actions.

Auf deinen Formularen welche diese Unit in der Uses-Anweisung haben kannst du nun direkt diese Actions anwählen. Verhält sich genauso mit Dingen wie ImageListen, DataSets, ...

Int3g3r 21. Dez 2018 11:10

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1421633)
Mach keine einfache Unit sondern ein Datenmodul (
Delphi-Quellcode:
TDataModule
). Pack dort deine
Delphi-Quellcode:
TActionList
drauf und mache dort deine Actions.

Auf deinen Formularen welche diese Unit in der Uses-Anweisung haben kannst du nun direkt diese Actions anwählen. Verhält sich genauso mit Dingen wie ImageListen, DataSets, ...

Besten Dank.
Habe mir gar nicht überlegt das ich eine zweite ActionsList verwenden könnte.
Aber warum soll die Unit ein Datenmodul sein ?

Der schöne Günther 21. Dez 2018 11:20

AW: Actions in einer anderen Unit definieren
 
Ein Datenmodul hat den Komfort dass du halt per Drag&Drop direkt Komponenten wie ImageLists, ActionList usw. darauf platzieren und bearbeiten kannst wie du es von Formularen gewohnt bist.

Und ich weiß gar nicht ob der Formular-Designer überhaupt so "schlau" wäre, eine von Hand per Code erzeugte ActionList in einer Unit einbinden und benutzen zu können.

Uwe Raabe 21. Dez 2018 11:37

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1421637)
Und ich weiß gar nicht ob der Formular-Designer überhaupt so "schlau" wäre, eine von Hand per Code erzeugte ActionList in einer Unit einbinden und benutzen zu können.

Geht ja auch nicht, da die ActionList dann zur Design-Zeit noch gar nicht existiert. Die auf einem Datenmodul (oder auch Form oder Frame) platzierten Komponenten werden direkt zur Designzeit erzeugt und somit dem Designer auch bekannt.

Int3g3r 21. Dez 2018 12:37

AW: Actions in einer anderen Unit definieren
 
Ich habe nun das Datenmodul eingefügt. Sobald ich aber den Dateiname des Datenmoduls ändere wird das Projekt nicht mehr kompilliert.
Zitat:

[dcc32 Fehler] hcTransport.dpr(18): E2003 Undeklarierter Bezeichner: 'TAction'
*.dpr Datei
Delphi-Quellcode:
program hcTransport;

uses
  Vcl.Forms,
  main in 'main.pas' {frmMain},
  dmod_prg in 'dmod_prg.pas' {dm: TDataModule},
  Kalender in 'Kalender.pas' {Hauptprogramm},
  Actions in 'Actions.pas' {Action: TDataModule};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(Tdm, dm);
  Application.CreateForm(TfrmMain, frmMain);
  Application.CreateForm(THauptprogramm, Hauptprogramm);
  Application.CreateForm(TAction, Action);
  Application.Run;
end.
Action.pas
Delphi-Quellcode:
unit Actions;

interface

uses
  System.SysUtils, System.Classes;

type
  TAction = class(TDataModule)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Action: TAction;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

end.

Delphi.Narium 21. Dez 2018 12:48

AW: Actions in einer anderen Unit definieren
 
Das ist klar:

Actions sind vom Typ TAction.

Du hast nun auch noch ein Datenmodul erstellt, dass ebenfalls vom Typ TAction ist.

Aber: TAction <> TAction

Beim Erstellen von Datenmodulen ... solltest Du darauf achten, dass Du keinen Typen verwendest den es in anderem Kontext schon gibt.

Du hast doch schon ein
Delphi-Quellcode:
dmod_prg in 'dmod_prg.pas' {dm: TDataModule}
, warum dann nicht statt
Delphi-Quellcode:
Actions in 'Actions.pas' {Action: TDataModule};
einfach
Delphi-Quellcode:
dmActions in 'dmActions.pas' {dmActions: TDataModule}
?

Int3g3r 21. Dez 2018 13:06

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1421647)
Das ist klar:

Actions sind vom Typ TAction.

Du hast nun auch noch ein Datenmodul erstellt, dass ebenfalls vom Typ TAction ist.

Aber: TAction <> TAction

Beim Erstellen von Datenmodulen ... solltest Du darauf achten, dass Du keinen Typen verwendest den es in anderem Kontext schon gibt.

Du hast doch schon ein
Delphi-Quellcode:
dmod_prg in 'dmod_prg.pas' {dm: TDataModule}
, warum dann nicht statt
Delphi-Quellcode:
Actions in 'Actions.pas' {Action: TDataModule};
einfach
Delphi-Quellcode:
dmActions in 'dmActions.pas' {dmActions: TDataModule}
?

Besten Dank!

Int3g3r 21. Dez 2018 13:34

AW: Actions in einer anderen Unit definieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe nun das Datenmodul eingebunden.
Von einem anderen Formular aus kann ich nun mit dem Befehl:
Delphi-Quellcode:
ac.dmOpenAll;
die Datenbanken öffen.

Ich möchte aber nicht einen Befehl im Quelltext ausführen sondern mit dem Objektinspektor verknüpfen.
Siehe Bild (Rot = so möchte ich die Action eingetragen).

Ist dies überhaupt möglich ?

Delphi.Narium 21. Dez 2018 13:42

AW: Actions in einer anderen Unit definieren
 
Steht das Datenmodule im Uses der frmMain?

Wenn nein, bitte dort eintragen.

Im Objektinspektor bitte eingeben:

Delphi-Quellcode:
Datenmodulname.ActionnameExecute


also in etwa
Delphi-Quellcode:
ac.dmOpenAllExecute


Eigentlich sollte der Objektinspektor aber beim Klick auf den Pfeil rechts eine Liste mit alle dem anzeigen, was dem Ereignis zugewiesen werden kann.

Uwe Raabe 21. Dez 2018 13:49

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1421656)
Eigentlich sollte der Objektinspektor aber beim Klick auf den Pfeil rechts eine Liste mit alle dem anzeigen, was dem Ereignis zugewiesen werden kann.

Dazu muss das Datenmodul in der uses-Anweisung stehen und im Designer geöffnet sein.

Int3g3r 21. Dez 2018 13:55

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1421656)
Steht das Datenmodule im Uses der frmMain?

Wenn nein, bitte dort eintragen.

Im Objektinspektor bitte eingeben:

Delphi-Quellcode:
Datenmodulname.ActionnameExecute


also in etwa
Delphi-Quellcode:
ac.dmOpenAllExecute


Eigentlich sollte der Objektinspektor aber beim Klick auf den Pfeil rechts eine Liste mit alle dem anzeigen, was dem Ereignis zugewiesen werden kann.

A) Was ist der unterschied zwischen der Uses am Anfang, und der Uses bei der Implementation ? Ich habe es bei der Uses am Anfang eingetragen.

B) Designer ? Also einfach in der Delphi IDE muss die Unit geöffnet sein richtig ? Diese ist geöffnet.

Wie gesagt im Code kann ich
Delphi-Quellcode:
ac.dmOpenAllExecute
verwenden doch beim Objektinspektor wird mir diese Action im Dropdown-Menü nicht angezeigt.


Code:
unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, dmActions;

type
  TfrmMain = class(TForm)
   private
      { Private-Deklarationen }
  public
      { Public-Deklarationen }
  end;

var
   frmMain: TfrmMain;

implementation

{$R *.dfm}


end.

jsp 21. Dez 2018 14:00

AW: Actions in einer anderen Unit definieren
 
http://wiki.freepascal.org/IDE_Window:_New_Item

Und da Data Module wählen.

Jörn

Delphi.Narium 21. Dez 2018 14:13

AW: Actions in einer anderen Unit definieren
 
Datenmodul mit Taste F12 anzeigen lassen.

Zum frmMain wechseln und mit Taste F12 anzeigen lassen.
Im Objektinspektor zum gewünschten Ereignis gehen und passende Routine auswählen.

Wird nix angezeigt, einfach das gewünschte reinschreiben.

Eventuell muss man einmal kompilieren, damit Delphi die Anhängigkeiten mitkriegt. (Zumindest bei meinem ollen Delphi 7 ist das (manchmal) so.)

Int3g3r 21. Dez 2018 14:19

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1421662)
Datenmodul mit Taste F12 anzeigen lassen.

Zum frmMain wechseln und mit Taste F12 anzeigen lassen.
Im Objektinspektor zum gewünschten Ereignis gehen und passende Routine auswählen.

Wird nix angezeigt, einfach das gewünschte reinschreiben.

Eventuell muss man einmal kompilieren, damit Delphi die Anhängigkeiten mitkriegt. (Zumindest bei meinem ollen Delphi 7 ist das (manchmal) so.)

Alles genau so gemacht. Sogar von hand eingetragen.
""ist kein gültiger bezeichner

Int3g3r 21. Dez 2018 14:41

AW: Actions in einer anderen Unit definieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Gerade habe ich bemerkt das ich unter Ereignisse -> Action die ac.dmOpenAllExecute auwählen kann.
Ich möchte es aber unter Ereignisse -> OnActivate auswählen können.

Im Anhang habe ich nochmals das Bild angehängt.
Ich weis nicht ob ihr das richtig verstanden habt was ich möchte.

Uwe Raabe 21. Dez 2018 16:40

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Int3g3r (Beitrag 1421665)
Ich weis nicht ob ihr das richtig verstanden habt was ich möchte.

In dem Fall hilft es oft, wenn du deinen aktuellen Code hier anhängst.

Delphi.Narium 21. Dez 2018 16:55

AW: Actions in einer anderen Unit definieren
 
Sagen wir so, ich habe verstanden was Du möchtest, weil das für mich eigentlich der Normalfall ist, also nix ungewöhnliches.

Daher wundert es mich, dass es bei Dir momentan irgendwie nicht funktioniert.

Und aktuell hab' ich auch keine Idee mehr, was da wo klemmen könnte.

Könntest Du eventuell mal das ganze Projekt als Zip hier anhängen, damit man mal alle Abhängigkeiten sehen kann? So ist das momentan doch eher ein Stochern im Nebel und nicht wirklich zielführend.

Int3g3r 7. Jan 2019 08:31

AW: Actions in einer anderen Unit definieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hoffe ihr habt die Feiertage genossen. Ich wünsche alle nachträglich noch ein gutes neues Jahr!

Ich habe hier im Anhang das Projekt eingefügt.
Wie bereits beschrieben ist es mir nicht möglich eine Action auf dem Form Main die ich in der Actions List auf einem DataModule erstellt habe im Objektinspektor unter Ereignisse -> OnCreate auszuwählen.

Ich kann die Action aber unter dem Form Main -> Ereignisse -> Action auswählen. Es soll aber unter OnCreate auswählbar sein.

Schokohase 7. Jan 2019 08:43

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Int3g3r (Beitrag 1422758)
Ich kann die Action aber unter dem Form Main -> Ereignisse -> Action auswählen. Es soll aber unter OnCreate auswählbar sein.

Das wird nicht funktionieren, genauso wenig wie Münzen in den Schlitz für die Scheine zu werfen, denn eine Münze ist kein Schein und eine Action ist eben keine Event-Methode. Es passt einfach nicht zusammen.

Delphi.Narium 7. Jan 2019 09:40

AW: Actions in einer anderen Unit definieren
 
In meinem Delphi (7) lassen sich im Objektinspektoer im OnCreate eines Formulars die Executemethoden von Actions zuweisen.

Es müsste eigentlich (in etwa) so aussehen:
Delphi-Quellcode:
DataModule1.openDBExecute
Wenn man Routinen aus anderen Formularen, Datenmodulen ... als Ereignisroutinen zuweisen will, muss man manchmal ein bisserl nachhelfen und es selbst schreiben, weil (zumindest bei Delphi 7) die IDE diese Abhängigkeiten / Möglichkeiten nicht immer zwingend von alleine hinbekommt.
Sprich: Man kann über den Objektinspektor ggfls. mehr zuweisen, als er einem als Auswahlmöglichkeiten anbietet.
Weiß nicht, ob sich das durch alle Delphiversionen hinzieht oder nur bei Delphi 7 so war.

Schokohase 7. Jan 2019 10:08

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1422763)
In meinem Delphi (7) lassen sich im Objektinspektoer im OnCreate eines Formulars die Executemethoden von Actions zuweisen.

Kein Wunder, denn so eine Action hat ein
Delphi-Quellcode:
OnExecute
Event und dem weise ich eine Event-Methode zu. Wenn die Methoden-Argumente passen, dann kann man diese Methode auch anderen Events zuweisen (die die gleichen Methoden-Argumente erwarten).

Man kann aber NICHT einem Event eine Action zuweisen. Das geht nicht!

Delphi.Narium 7. Jan 2019 10:19

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Schokohase (Beitrag 1422766)
Man kann aber NICHT einem Event eine Action zuweisen. Das geht nicht!

Natürlich nicht, das ist auch klar, aber eventuell liegt ja genau hier das Verständnisproblem.

Uwe Raabe 7. Jan 2019 11:24

AW: Actions in einer anderen Unit definieren
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1422763)
In meinem Delphi (7) lassen sich im Objektinspektoer im OnCreate eines Formulars die Executemethoden von Actions zuweisen.

Das funktioniert nur, wenn diese auch in dem Formular deklariert sind. Soweit mir bekannt ist, lassen sich Ereignisse auch nur dann zuweisen, wenn sie im selben Form, Frame oder Datamodule - auch in Delphi 7 war das wohl nicht anders.

Anders ist das bei Komponenten (was Actions ja auch sind). Die können aus anderen Instanzen (Form, Frame, DataModule) zugewiesen werden, solange die betreffende Unit in der Uses-Anweisung steht und die Instanz aktuell vorhanden ist (nicht zwingend auch sichtbar).

Also, die Action im Datenmodul kann man einem Action-Property einer Komponente im Form oder des Forms selbst zuweisen, nicht aber die im Datenmodul deklarierten Events. Das ging wohl noch nie.

Delphi.Narium 7. Jan 2019 12:06

AW: Actions in einer anderen Unit definieren
 
Einem Ereignis kann man eine für dieses Ereignis parameterkompatible Methode zuweisen.

Nichts anderes habe ich beschrieben.

Das von mir beschrieben mache ich seit Jahr und Tag und es funktioniert.

Ein OnIrgendwas ist "nur" ein Methodenzeiger, dem man eine passende Methode zuweisen kann, wo diese deklariert ist, ist egal, dass kann in der gleichen Unit sein, muss es aber nicht.

Ob etwas im Objektinspektor zugewiesen werden kann oder nicht hängt eigentlich nur davon ab, ob die IDE die entsprechende Methode findet und im Objektinspektor anzeigen kann oder nicht (und zuweisen will oder nicht). Sie prüft dabei schon, ob die Methoden parameterkompatibel sind und zeigt nur die (ihrer Meinung nach) passenden Methoden an.

Es würde mich wundern, wenn hier im konkreten Fall eine Ereigniszuweisung im Quelltext in der Form
Delphi-Quellcode:
Main.OnCreate := DataModule1.openDBExecute
nicht funktionieren würde. Kompilieren lässt sich das und funktioniert prinzipiell auch, allerdings ist es fraglich, ob eine Zuweisung auf das onCreate-Ereignis eines Formulares im OnCreate-Ereignis dieses Formulares noch irgendeinen Sinn ergibt, wohl eher nicht.

Int3g3r 16. Jan 2019 10:29

AW: Actions in einer anderen Unit definieren
 
Besten Dank für die vielen Antworten und Hilfestellungen.

Inzwischen weis ich das Methoden und Funkionen nicht das gleiche sind. Methoden existieren nur innerhalb einer Klasse. Da ich noch keine eigenen Klassen programmiert habe werde ich dies vorerst ruhen lassen.

Mein Problem ist das der source code meines erachtens nicht gerade übersichtlich ist wenn man 20 "beforPost", "afterInsert" etc. Events hat und diese durch die Unit zerstreut sind. Daher wollte ich solche Events auf eine seperate Unit auslagern.

Gruss,
Int3g3r


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz