Autor Beitrag
fuulf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 17.12.09 13:12 
Hallo,

das Programm soll zur Laufzeit einen Button dynamisch erstellen. Dann soll unter definierten Bedingungen, wobei eine dieser Bedingungen ist, dass der Benutzer auf den Button geklickt hat, der Button wieder mit .free gelöscht und der zugehörige Speicher freigegeben werden. Wenn ich das versuche, gibt es eine Zugriffsverletzung, weil das Programm noch auf den Button zugreifen will, aber der Button sich ja schon selbst gelöscht hat.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 17.12.09 13:17 
Quellcode?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 17.12.09 13:33 
Moin!

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
das Programm soll zur Laufzeit einen Button dynamisch erstellen. Dann soll unter definierten Bedingungen, wobei eine dieser Bedingungen ist, dass der Benutzer auf den Button geklickt hat, der Button wieder mit .free gelöscht und der zugehörige Speicher freigegeben werden. Wenn ich das versuche, gibt es eine Zugriffsverletzung, weil das Programm noch auf den Button zugreifen will, aber der Button sich ja schon selbst gelöscht hat.
Man kann VCL-Controls (also auch Buttons) nicht in ihren Ereignissen freigeben, das wird immer mit einer Exception belohnt. :nixweiss:

Einfacher Lösungsansatz: Reicht es nicht, den Button einfach .Visible := FALSE zu setzen? Evtl. erzeugst du ja danach wieder einen, dann kannst du dir das sparen und den schon existierenden weiterverwenden. :idea: ;)

Komplexer: Eine private WindowsMessage definieren, einen Handler dazu schreiben, in diesem den Button freigeben, die Message im OnClick des Buttons an das eigene Handle posten.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
fuulf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 17.12.09 13:38 
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:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure Klick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Knopf: TButton;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Knopf := tbutton.create(form1);
  Knopf.parent := form1;
  Knopf.OnClick := Klick;
end;

procedure TForm1.Klick(Sender: TObject);
begin
  Knopf.Free;
end;

end.



Also visible := false reicht nicht. Wie genauer funktioniert denn der beschriebene komplexere Lösungsansatz?

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 17.12.09 13:47 
Moin!

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Also visible := false reicht nicht.
Darf ich mal so ganz nebenbei fragen, warum das nicht reicht? :gruebel:

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Wie genauer funktioniert denn der beschriebene komplexere Lösungsansatz?
Ich such dir einen passenden Thread dazu raus, das gibt´s hier schon mehrfach im Forum. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
fuulf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Do 17.12.09 13:58 
Weil zwar wieder neue Buttons erzeugt werden sollen, aber nicht unbedingt so viele, wie vorher da waren. Umgekehrt könnte es aber auch sein, dass mehr Buttons erzeugt werden sollen, als es vorher gab. Das hängt vom Benutzer ab.

Also bei www.delphi-forum.de/...light=windowsmessage scheint es im Prinzip ein ähnliches Problem zu sein, aber hat mir jetzt auch nicht so viel geholfen..
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 17.12.09 14:08 
Moin!

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Weil zwar wieder neue Buttons erzeugt werden sollen, aber nicht unbedingt so viele, wie vorher da waren. Umgekehrt könnte es aber auch sein, dass mehr Buttons erzeugt werden sollen, als es vorher gab. Das hängt vom Benutzer ab.
In diesem Fall würde ich zwei Listen empfehlen, eine mit sichtbaren und die andere mit den unsichtbaren Buttons. Direkt die Maximalanzahl erstellen (und das Formular als Eigentümer angeben, dann braucht man sich nicht um die Freigabe kümmern) und dann nur noch zwischen den Listen hin- und herschieben. :idea: ;) Ist nebenbei auch resourcenschonender. :think:

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Also bei www.delphi-forum.de/...light=windowsmessage scheint es im Prinzip ein ähnliches Problem zu sein, aber hat mir jetzt auch nicht so viel geholfen..
Dann schau mal hier. :les:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 17.12.09 14:29 
Man könnte es so machen:

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:
  private
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := AppMessage;
end;

procedure TForm1.ErstellterButtonClick(Sender: TObject);
begin
  PostMessage(Application.Handle, WM_USER + 551,0);
end;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if msg.message = wm_user + 55 then
    if msg.wParam = 1 then
    begin
      FreeAndNil(Knopf);
      Handled := true;
    end;
end;
fuulf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 24



BeitragVerfasst: Mo 28.12.09 17:15 
Könnte man es vielleicht auch unprofessioneller mit einem Timer machen, der über .ComponentState überprüft, ob der Button noch irgendeine Ereignisprozedur am laufen hat, bzw. ob der Button noch überhaupt irgendwas macht?

Würde es reichen csLoading zu überprüfen?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 02.01.10 02:27 
Moin!

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Könnte man es vielleicht auch unprofessioneller mit einem Timer machen, der über .ComponentState überprüft, ob der Button noch irgendeine Ereignisprozedur am laufen hat, bzw. ob der Button noch überhaupt irgendwas macht?
Man kann eine Menge Sachen machen, die Frage ist, wieviel Aufwand das ist und wie "sicher" sich diese Lösung verhält. Bei deinem zuletzt vorgeschlagenen Ansatz sehe ich für beide Kriterien keine Pluspunkte. :? Mein Tipp: Finger davon lassen. :idea:

user profile iconfuulf hat folgendes geschrieben Zum zitierten Posting springen:
Würde es reichen csLoading zu überprüfen?
Was sollte das bringen? :gruebel:

Du hast mittlerweile mehrere Ansätze vorgeschlagen bekommen, die mehr oder weniger sicher das Problem lösen. Warum einen fraglichen Ansatz verfolgen, wenn es schon bessere Lösungen gibt? :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 02.01.10 03:46 
Du kannst ja immer die noch fehlenden Buttons erzeugen und zu viel vorhandene freigeben:
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:
24:
25:
26:
27:
28:
private
  MyButtons: TList<TButton>;

// FormCreate
  MyButtons := TList<TButton>.Create(True);
// FormDestroy
  MyButtons.Free;

// Buttonliste aktualisieren:
var
  i: Integer;
  NewButton: TButton;
begin
  // fehlende Buttons erzeugen
  for i := MyButtons.Count to Pred(CurrentCount) do
  begin
    NewButton := TButton.Create(nil);
    NewButton.
    ...
    MyButtons.Add(NewButton);
  end;
  // überzählige Buttons entfernen
  for i := MyButtons.Count downto CurrentCount do
    MyButtons.Delete(i);
  // Werte zuweisen
  for i := 0 to Pred(MyButtons.Count) do
    MyButtons.Caption := IntToStr(i);
end;
Oder zwei Listen wie auch schon vorgeschlagen, oder, oder...

Es hängt auch sehr davon ab was mit den Buttons passiert und wodurch die Anzahl festgelegt wird, ob diese beliebig sein kann, ...
Du kannst dann die passende Variante benutzen.