Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Close eines dynamisches TForm
ardely - Mo 04.03.13 10:37
Titel: Close eines dynamisches TForm
Guten Morgen,
Ich habe das Wochenende im Internet lange gesucht, allerdings ohne wirklichen Erfolg!
Meine Fragestellung ist bei der Erstellung eines dynamische Form, ich möchte gern mit der Mausetaste auf die Form anklicken, sodass die 'FormV' schließt.
Hier ist ein Beispiel, beim Kompilieren bekomme ich ein Error an dieser Stelle "FormV.OnClick := CloseMe;".
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:
| procedure ShowMyFormV; var FormV: TForm;
procedure CloseMe(Sender: TObject); begin close; end;
begin
FormV := TForm.Create(nil); try FormV.BorderStyle := bsDialog; FormV.Caption := 'My Dynamic Form!'; FormV.Position := poScreenCenter; FormV.BorderStyle := bsNone; FormV.ClientWidth := 500; FormV.ClientHeight := 100; FormV.OnClick := CloseMe; <-- Kompilier error FormV.ShowModal; finally FormV.Free; end;
end; |
Ich bedanke mich herzlich für hier Hilfe.
Grüsse.
Mathematiker - Mo 04.03.13 10:49
Hallo,
Deine Methode CloseMe muss zur Klasse TFormV gehören, d.h.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| TFormV = class(TForm ... ... private procedure CloseMe(Sender : TObject); published end; |
und außerdem
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TFormV.CloseMe(Sender: TObject); begin close; end; |
Dann müsste es funktionieren.
Beste Grüße
Mathematiker
ardely - Mo 04.03.13 11:23
Ich habe noch immer Kompiler Error auf.
Delphi-Quelltext
1:
| procedure FormV.CloseMe(Sender: Tobject); |
Und zwar wenn ich die Procedure FormV.CloseMe() innerhalb der procedure 'procedure ShowMyFormV;' und oder ausserhalb der procedure 'procedure ShowMyFormV;' einsätze.
Der Error ist:
1.Undeclared identifier 'CloseMe' at line ...(für → FormV.OnClick := CloseMe;)
2.Unit1 doeas not contain a member named 'closeMe' at line … (für → procedure FormV.CloseMe(Sender: Tobject);)
Welchen Vorschlag kannst du mir noch geben?
WasWeißDennIch - Mo 04.03.13 11:44
Hast Du die Methode denn auch in der Formulardeklaration (interface-Abschnitt) eingefügt?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| type TForm1 = class(TForm) ... private procedure CloseMe(Sender: TObject; var Action: TCloseAction); ... end; |
Wenn man nun STRG-SHIFT-C drückt, fügt Delphi (allerdings nicht Starter) automatisch den entsprechenden Methodenrumpf in den Quelltext (implementation-Abschnitt) ein.
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.CloseMe(Sender: TObject; var Action: TCloseAction); begin
end; |
Damit ist die Methode syntaktisch korrekt angelegt und kann zugewiesen werden.
ardely - Mo 04.03.13 12:19
Danke für Ihre Antwort, habe manches ausprobiert, leider bekomme ich das noch nicht hin!
So sieht die Unit aus, was könnte ich hier falsch gemacht habe?
Bekomme Kompiler Error : Incompatible types: method pointer and regular procedure (für-> FormV.OnClick := CloseMe; )
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:
| type TFormV = class(TForm) private public published
end;
type TForm1 = class(TForm) private procedure CloseMe(Sender: TObject; var Action: TCloseAction); procedure ShowMyFormV; public end; implementation
procedure Tform1.ShowMyFormV; var FormV: TForm;
begin
FormV := TForm.Create(nil); try FormV.BorderStyle := bsDialog; FormV.Caption := 'My Dynamic Form!'; FormV.Position := poScreenCenter; FormV.BorderStyle := bsNone; FormV.ClientWidth := 500; FormV.ClientHeight := 100; FormV.OnClick := CloseMe; <-- Kompiler error FormV.ShowModal; finally FormV.Free; end; end;
procedure Tform1.CloseMe(Sender: TObject); begin close; end; |
WasWeißDennIch - Mo 04.03.13 12:25
Delphi-Quelltext
1:
| procedure CloseMe(Sender: TObject; var Action: TCloseAction); |
So muss es auch implementiert sein.
ardely - Mo 04.03.13 12:53
Danke für deine Empfehlung, habe auch vorher so ausprobiert aber bekomme immer noch,
Kompiler Error: E2009 Incompatible type: Parameter lists differ.
Danke für Ihre Unterstützung.
WasWeißDennIch - Mo 04.03.13 13:00
Zitat: |
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure Tform1.CloseMe(Sender: TObject); begin close; end; | |
Wo ist da der Action-Parameter? Oder wie sieht der aktuelle Code jetzt aus?
ardely - Mo 04.03.13 13:17
So sieht die aktuelle Unit-code aus.
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: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;
type TFormV = class(TForm) private public published
end; type TForm1 = class(TForm) private procedure CloseMe(Sender: TObject; var Action: TCloseAction); procedure ShowMyFormV; public end;
var Form1: TForm1; implementation
{$R *.dfm}
procedure Tform1.ShowMyFormV; var FormV: TForm;
begin
FormV := TForm.Create(nil); try FormV.BorderStyle := bsDialog; FormV.Caption := 'My Dynamic Form!'; FormV.Position := poScreenCenter; FormV.BorderStyle := bsNone; FormV.ClientWidth := 400; FormV.ClientHeight := 200; FormV.OnClick := CloseMe; <-- Kompiler error: E2009 Incompatible type: Parameter lists differ. FormV.ShowModal; finally FormV.Free; end;
end;
procedure Tform1.CloseMe(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;
end. |
WasWeißDennIch - Mo 04.03.13 14:02
*Aaahhhh* sry, mein Fehler :autsch: . Es geht ja um OnClick, nicht um OnClose, das sind unterschiedliche Event-Typen. Also, FormV soll bei Click geschlossen werden, richtig?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type TForm1 = class(TForm) ... private procedure CloseMe(Sender: TObject); ... end;
procedure TForm1.CloseMe(Sender: TObject); begin if Sender is TForm then TForm(Sender).Close; end; |
So sollte sich das auch zuweisen lassen.
ardely - Mo 04.03.13 15:22
Schade, dass du mein Jubel nicht gesehen hast, dass es genau so funktioniert wie ich mir das gewünscht habe, vielen Dank.
Mein procedure Name war vielleicht auch ein bisschen verwirrend...
Ich hätte nur noch eine letzte Frage um meine Erkenntnisse noch zu vertiefen.
Ist es möglich die 'procedure Tform1.CloseMe(Sender: Tobject);'
innen im Procedure ShowMyFormV einzubauen.
So etwas.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure Tform1.ShowMyFormV; var FormV: TForm;
procedure CloseMe(Sender: TObject); begin if Sender is TForm then TForm(Sender).Close; end;
begin
FormV := TForm.Create(nil); try FormV.OnClick := CloseMe; FormV.ShowModal; finally FormV.Free; end; end; |
Ich habe verschiedene Möglichkeit ausprobiert ohne erfolg, aber ich bin nicht sicher, ob es überhaupt möglich ist!
Noch einmal großen Dank für deine vorherige Hilfe.
WasWeißDennIch - Mo 04.03.13 15:38
Nein, das geht so leider nicht. Eventhandlern können i.A. nur Methoden zugewiesen werden, d.h. sie müssen zu einer Klasse gehören.
bummi - Mo 04.03.13 17:53
Du kannst trotzdem in die Nähe des gewünschten gelangen
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TDummyClass=Class(TObject) Class Procedure OnClose(Sender: TObject; var Action: TCloseAction); End;
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); begin OnClose := TDummyClass.OnClose; end;
class procedure TDummyClass.OnClose(Sender: TObject; var Action: TCloseAction); begin Showmessage(TForm(Sender).Caption); Action := caFree;
end;
end. |
WasWeißDennIch - Mo 04.03.13 18:34
Was der Code mit dem gewünschten zu tun haben soll, kann ich leider nicht erkennen. Dazu müsste man die Klasse samt Klassenmethode innerhalb der ShowMyFormV-Methode deklarieren und implementieren.
bummi - Mo 04.03.13 19:01
Ich will nicht schon wieder Haare zählen und Erbsen spalten ....
TDummyClass würde sich in einer Tools Unit befinden und die Class Procedure instanzlos wie eine "Prozedur" zugewiesen werden können, mit einem einheitlichen Verhalten, aber lassen wir eine eine weitere Vertiefung ....
WasWeißDennIch - Mo 04.03.13 19:13
Das war aber nicht die Frage ;)
Zitat: |
Ist es möglich die 'procedure Tform1.CloseMe(Sender: Tobject);' innen im Procedure ShowMyFormV einzubauen. |
Hat nun gar nix mit Erbsenzählerei zu tun, die kann ich nämlich auch nicht leiden.
bummi - Mo 04.03.13 19:48
OKOKOK, das hätte ich noch anzubieten ...
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:
| procedure TForm1.Button1Click(Sender: TObject); begin ShowMyFormV; end;
procedure Tform1.ShowMyFormV; var FormV: TForm; Meth: TMethod; procedure CloseMe(DoNotUseSelf_ItsInvalid:Pointer;Sender: TObject); begin Showmessage(Sender.ClassName); if Sender is TForm then TForm(Sender).Close; end;
begin Meth.Data := nil; Meth.Code := @CloseMe; FormV := TForm.Create(nil); try FormV.OnClick := TNotifyEvent(Meth); FormV.ShowModal;
finally FormV.Free; end; end; |
ardely - Mo 04.03.13 23:30
Hallo,
Genial, supergut deine Lösung, ich habe es sofort noch mit zusätzlich 'FormV.OnPaint :=' ausprobiert und es funktioniert sehr gut.
Und wollte noch als letzte hinzufügen 'FormV.OnMouseDown :=' und konfigurieren, das habe ich leider nicht hin bekommen.
Wie soll ich diese procedure FormMouseDown() umändern.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure FormMouseDown( ???? Pointer; Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Sender is TForm then TForm(Sender).Close; end; begin MethC.Data := nil; MethC.Code := @FormMouseDown; FormV.OnMouseDown:= TNotifyEvent(MethC); |
Ihr seid wirklich super, noch einmal vielen Dank.
Grüss
bummi - Mo 04.03.13 23:40
der Eventtyp passt nicht
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:
| procedure Tform2.ShowMyFormV; var FormV: TForm; Meth: TMethod; procedure MouseDown(DoNotUseSelf_ItsInvalid:Pointer;Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Showmessage(Format('%s x:%d y:%d',[Sender.ClassName,x,y])); if Sender is TForm then TForm(Sender).Close; end;
begin Meth.Data := nil; Meth.Code := @MouseDown; FormV := TForm.Create(nil); try FormV.OnMouseDown := TMouseEvent(Meth); FormV.ShowModal;
finally FormV.Free; end; end; |
WasWeißDennIch - Di 05.03.13 09:07
Ich frage mich ernsthaft nach dem Sinn des Ganzen, aber wenn der TE damit zufrieden ist, soll es mir auch egal sein.
ardely - Di 05.03.13 11:16
Echt klasse, an euch alle, für die Schnelle supergute hilfreiche Lösungen, bin jetzt gut vorwärtsgekommen, DANKE.
Grüss
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!