AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Form dynamisch erzeugen

Ein Thema von whiteF · begonnen am 16. Okt 2016 · letzter Beitrag vom 24. Okt 2016
Antwort Antwort
Seite 1 von 2  1 2      
whiteF

Registriert seit: 14. Okt 2008
45 Beiträge
 
#1

Form dynamisch erzeugen

  Alt 16. Okt 2016, 23:35
Hallo,
ich möchte eine Form dynamisch erstellen lassen. Die dynamische Form namens "FormMessengerNW" habe ich bereits in Delphi erstellt und mit labels bestückt. Über eine public Variable bestimme ich einen Text den ich bei der Form "FormMessengerNW" beim OnShow einlesen/anzeigen möchte.
Die "FormMessengerNW" ist ein Hinweisfenster das am Rand eingeblendet wird und mit einem Timer nach ein paar sekunden wieder verschwindet (oder mittels close button).
Diese Form funktionierte an sich bereits als ich sie direkt aufrief, jedoch bekomme ich den dynamischen Aufruf nicht ganz hin.

Das hatte ich bereits probiert:

Form1
Delphi-Quellcode:
...
var
  FormMessengerNW_Instanz : TFormMessengerNW;
begin
...
    try
      showmessage('0');
      FormMessengerNW_Instanz := FormMessengerNW.Create(Application.MainForm);
      FormMessengerNW_Instanz.OnCreate:= FormMessengerNW.OnCreate;
      FormMessengerNW_Instanz.OnShow := FormMessengerNW.OnShow;
      FormMessengerNW_Instanz.OnClose := FormMessengerNW.OnClose;
    finally
    showmessage('1');
      FormMessengerNW_Instanz.Show;
      showmessage('2');
    end;
...
FormDyn
Delphi-Quellcode:
procedure TFormMessengerNW.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  //FormMessengerNW.Release;
end;

procedure TFormMessengerNW.FormShow(Sender: TObject);
begin
  showmessage('form open');
end;

procedure TFormMessengerNW.FormCreate(Sender: TObject);
begin

  (Sender as TForm).AlphaBlendValue := 235;

  lblTitle.Left := 35;

  imgClose0.Top := imgClose0.Top;
  imgClose0.Left := 324;
  imgClose1.Top := imgClose0.Top;
  imgClose1.Left := imgClose0.Left;

  reMessage.Width := 323;
  reMessage.Left := 15;
  reMessage.Top := 30;
  reMessage.Height := 62;
end;
das showmessage "2" wird nicht mehr eingeblendet.
Es kommt immer "EAcces Vioalation"


Wie würdet ihr soetwas lösen?

VG
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#2

AW: Form dynamisch erzeugen

  Alt 16. Okt 2016, 23:38
Da es das Formular ja bereits gibt, probier statt
Delphi-Quellcode:
FormMessengerNW_Instanz := FormMessengerNW.Create(Application.MainForm);
FormMessengerNW_Instanz.Show;
mal
Delphi-Quellcode:
Application.CreateForm(TFormMessengerNW, FormMessengerNW);
FormMessengerNW_Instanz.Show;

Geändert von Jim Carrey (16. Okt 2016 um 23:41 Uhr)
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 00:00
Deine Klasse ist ja TFormMessengerNW

Also musst Du auch eine Instance davon erzeugen.

Dein Aufruf von:


 FormMessengerNW_Instanz := FormMessengerNW.Create(Application.MainForm); ruft auf der bestehenden Instance Create auf nicht den von der Klasse!!!
also ändere einfach zu:

 FormMessengerNW_Instanz := TFormMessengerNW.Create(Application.MainForm); Achte auf das "T" in TFormMessengerNW.Create

Meiner Meinung nach sollte das Aufrufen eines Constructors zumindest eine Hint liefern, aber man kann ja nicht alles haben
Fritz Westermann
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#4

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 00:17
Warum aber eine neue Variable der Klasse anlegen, wenn er doch eh schon eine hat?
Dann wäre folgendes doch viel sinniger:

Application.CreateForm(TFormMessengerNW, FormMessengerNW);
  Mit Zitat antworten Zitat
whiteF

Registriert seit: 14. Okt 2008
45 Beiträge
 
#5

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 08:35
oh nein,
ich habe tatsächlich nur das "T" vergessen... vielen Dank! 4 Augen sehen mehr als 2. Jetzt klappts ohne EAccess Violation.

Da hätte ich dann noch eine kleine Anschlussfrage:

Wie spreche ich diese dynamisch erzeugte Form dann am besten an?

ich beende über ein ImgClick diese Form, das hatte bei direkter Formnutzung ja so geklappt (FormMessengerNW.Close und bei dynamischer?
und bei dynForm?
(Sender as TForm).Close; //wobei Sender nicht immer TForm ist
ThisForm.Close; //


Ich steh da etwas auf dem Schlauch...
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 09:27
Hi,

im Endeffekt genauso, wie du auf alle anderen Eigenschaften und Methoden zugreifen kannst, über die Instanz

Code:
FormMessengerNW.Close
bzw. über

Code:
FormMessengerNW.Hide
kannst du die Form wieder verschwinden lassen, ohne die Instanz zu löschen und beim nächsten
mal neu erzeugen zu müssen.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#7

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 12:08
Zitat:
Da hätte ich dann noch eine kleine Anschlussfrage:

Wie spreche ich diese dynamisch erzeugte Form dann am besten an?
Guck dir mal meinen Lösungsvorschlag an. Dann kannst du das Formular ansprechen wie jedes andere Formular auch und du brauchst keine extra Variable, welche total sinnlos ist.
  Mit Zitat antworten Zitat
Darlo

Registriert seit: 28. Jul 2008
Ort: München
1.196 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#8

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 12:12
Zitat:
Da hätte ich dann noch eine kleine Anschlussfrage:

Wie spreche ich diese dynamisch erzeugte Form dann am besten an?
Guck dir mal meinen Lösungsvorschlag an. Dann kannst du das Formular ansprechen wie jedes andere Formular auch und du brauchst keine extra Variable, welche total sinnlos ist.
Kommt natürlich darauf an wieviele parallele Instanzen benötigt werden.
Philip
  Mit Zitat antworten Zitat
whiteF

Registriert seit: 14. Okt 2008
45 Beiträge
 
#9

AW: Form dynamisch erzeugen

  Alt 17. Okt 2016, 23:57
Also, da ich ja die Form mehrfach eingeblendet werden sollte bei meinem programm, dürfte ich ja für die form keinen festen Namen vergeben, sonst könnte ja in der 2.ten Instanz ja nicht mehr die Form created werden da ja der Name bereits existiert (vermute ich jetzt mal ganz stark).

Es funktionieren beide Varianten:

#1
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  FormMessengerNW_Instanz : TFormMessengerNW;
begin
  try
    FormMessengerNW_Instanz := TFormMessengerNW.Create(Application.MainForm);
  finally
    FormMessengerNW_Instanz.Show;
  end;
end;
#2
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    Application.CreateForm(TFormMessengerNW, FormMessengerNW);
  finally
    FormMessengerNW.Show;
  end;
end;
Um die dynamisch erzeugte Form zu schliessen kommt es zum Teil drauf an wie diese erstellt worden ist.
Das klappt immer:
Delphi-Quellcode:
procedure TFormMessengerNW.Button1Click(Sender: TObject);
begin
  Self.Close;
end;
Das klappt nur in Verbindung mit der #2-Variante:
Delphi-Quellcode:
procedure TFormMessengerNW.Button1Click(Sender: TObject);
begin
  FormMessengerNW.Close; //Wenn mehrere Instanzen erstellt werden, gibt es hiermit jedoch Probleme
//das funktioniert aber auch: Self.Close; //Wenn mehrere Instanzen erstellt werden, gibt es hiermit KEINE Probleme
end;
Variante #2 kann hiermit gefunden (gelistet) werden kann //Variante #1 nicht... wieso nicht? :
Delphi-Quellcode:
procedure TForm1.Button11Click(Sender: TObject);
var
  i, ii: Integer;
begin
  Memo1.Clear;
  ii := 0;
  for i := 0 to Application.ComponentCount - 1 do
  begin
    if Application.Components[i] is TForm then
    begin
      Memo1.Lines.Add(Application.Components[i].Name);
      ii := ii + 1;
    end;
  end;
  Edit1.Text := IntToStr(ii);
end;
Das hier funktioniert für Variante #1 & #2
Delphi-Quellcode:
procedure TForm1.Button22Click(Sender: TObject);
var
  i, ii: Integer;
begin
  Memo1.Clear;
  ii := 0;
  for i := 0 to Screen.CustomFormCount - 1 do
  begin
    Memo1.Lines.Add(Screen.Forms[i].Name);
    ii := ii + 1;
  end;
  Edit1.Text := IntToStr(ii);
end;

Ein kleines praktisches Beispiel Projekt liegt anbei.
Angehängte Dateien
Dateityp: rar DynForm.rar (6,1 KB, 8x aufgerufen)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.081 Beiträge
 
Delphi 2009 Professional
 
#10

AW: Form dynamisch erzeugen

  Alt 23. Okt 2016, 22:35
Man erstellt grundsätzlich mit Application.CreateForm und referenziert die in sich mit Self (wobei man das auch weglassen kann, was das gleiche ergibt). Bei Application.CreateForm ist Application der Besitzer der Form. Beim direkten Aufruf von Create ist halt derjenige der Besitzer, den du angibst. Das Durchlaufen der Kindkomponenten von MainForm oder Application ist auch reichlich ineffizient. Man nimmt sich am ehesten eine TList oder ein Array.
Wenn du eine Form entwirfst, gibt dir Delphi eine Instanzvariable mit dem Namen der Form ohne T dran (denn T ist der uninstanzierte Typ). Heißt deine Form TFormMessengerNW, so heißt diese Variable also FormMessengerNW. Du musst die Instanz erst erstellen, das macht man mit Application.CreateForm.
Wenn du in deinem Code, wie du es machst, nicht Self sondern eine ganz bestimmte Instanzvariable, in dem Fall die vorgegebene FormMessengerNW, schließt, aber eine völlig andere Instanzvariable namens FormMessengerNW_Instanz erstellt hast, klappt das natürlich nicht.

Du benutzt zudem try-finally-Konstrukte komplett falsch. Der finally-Block wird immer aufgerufen, egal was im try-Block passiert. Schlägt das Erstellen der Form fehl, rufst du Show auf. Show schlägt fehl, weil die Instanz gar nicht erstellt wurde. Dein try-finally-Konstrukt bringt also absolut nichts. Daher haut dir der Compiler die erste Variante auch um die Ohren, denn das Create gehört niemals in dasselbe try-finally-Konstrukt wie jegliche Befehle, die darauf zugreifen. Wenn du im finally-Block auf etwas zugreifst, was du im try-Block erstellt hast, hast du ja überhaupt keine Ahnung, ob du das überhaupt erstellt hast oder nicht.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:55 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