Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - eigenes objekt->procedure zuweisen


covel - Mi 12.07.06 11:11
Titel: eigenes objekt->procedure zuweisen
Moin, komme mal wieder nicht weiter!!


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
btn_close:= TButton.Create(form1);
with btn_close do
  begin
    parent:=test;
    width:=10;
    height:=10;
    top:=0;
    left:=90;
    OnClick:=Close;    <- Hier möchte ich dem btn_close eine procedure zuweisen!! Wird auch gemacht nur es wird kein Parameter übergeben! 
  end;


Hoffe es kann mir jemand helfen!



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:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
unit objekte;

interface

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

type
  //TOnClickEvent = procedure (Sender:TObject) of object;

  TAuto= class(TObject)
    //FOnClick: TOnClickEvent;
    fx:Integer;
    fy:Integer;
    test:TPanel;
    btn_close:TButton;
    constructor Create;
    destructor  destroy;


    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure close(Sender:TObject);
    //procedure anzeigen(xpos,ypos:Integer);
end;

implementation
var

  inReposition : boolean;
  oldPos : TPoint;
  Sender:TPanel;

constructor TAuto.Create;
begin
inherited;
test := TPanel.Create(form1);
with test do
  begin
    Visible :=true;
    Parent:=form1;
    Width :=100;
    Height :=100;
    onMouseDown:=ControlMouseDown;
    OnMouseUp:=ControlMouseUp;
    OnMouseMove:=ControlMouseMove;
  end;
inherited;
btn_close:= TButton.Create(form1);
with btn_close do
  begin
    parent:=test;
    width:=10;
    height:=10;
    top:=0;
    left:=90;
    OnClick:=Close;
  end;

end;

destructor TAuto.Destroy;
begin
btn_close.Free;
test.free;
inherited;
end;

procedure TAuto.close(Sender:TObject);
begin
TPanel(sender).Caption :='test';
//inherited;
end;

//////////////////MOUSEMOVE///////////////////////
procedure TAuto.ControlMouseUp(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if inReposition then
  begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
    inReposition := False;
  end;
end;

procedure Tauto.ControlMouseMove(
  Sender: TObject;
  Shift: TShiftState;
  X, Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if inReposition then
  begin
    with TWinControl(Sender) do
    begin
      GetCursorPos(newPos);

      if ssShift in Shift then
      begin //resize
        Screen.Cursor := crSizeNWSE;
        frmPoint := ScreenToClient(Mouse.CursorPos);
        if frmPoint.X > minWidth then
          Width := frmPoint.X;
        if frmPoint.Y > minHeight then
          Height := frmPoint.Y;
      end
      else //move
      begin
        Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X;
        Top := Top - oldPos.Y + newPos.Y;
        oldPos := newPos;
      end;
    end;
  end;
end(*ControlMouseMove*)

procedure TAuto.ControlMouseDown(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState;
  X, Y: Integer);
begin
  if(Sender is TWinControl) then
  begin
    inReposition:=True;
    SetCapture(TWinControl(Sender).Handle);
    GetCursorPos(oldPos);
  end;
end;
//////////////////////////////////////////////////

end.


Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt


crowley - Mi 12.07.06 11:35

schau dir noch mal deine Close-Procedure an:

du weist einem Button die Close-Procedure für das OnClick- Event zu... in der Procedure selber greifst du aber auf TPanel(Sender) zu, das kann nicht funktionieren, da der Sender dein Button ist. Wenn, muss es an der Stelle entweder TButton(Sender).Caption oder test.Caption heissen, je nachdem, in welches Caption du nun was schreiben willst.


covel - Mi 12.07.06 11:48

ohh, da habe ich was übersehen, es funkt. nun. besten dank


crowley - Mi 12.07.06 11:59

vielleicht täusche ich mich ja, aber hatten wir nicht in einem ähnlichen Thread von dir schon mal gesagt, dass du deine Klasse vielleicht von TPanel und nicht von TObject ableiten solltest?

desweiteren solltest du vermeiden, ggf. zentral vorbelegte Procedure- Namen zu mißbrauchen (Close ist quasi mehrfach vorbelegt... nenne es vielleicht besser: BtnClose oder noch besser BtnCloseClick).

Wird dein ButtonClick eigentlich überhaupt aufgerufen? Habe die Befürchtung, dass du mit deinem
ControlMouseDown bzw. ControlMouseUp das schon abfängst bzw. nicht entsprechend weiterleitest.

Was soll eigentlich deine globale Variable Sender? Schmeiss die mal lieber weg... kann sein, dass die die Wurzel allen Übels ist und anstatt auf den Parameter Sender im Close greift dein Close auf die nicht initialisierte Variable Sender zu.


covel - Mi 12.07.06 14:08

Jo, habe vor ein paar tagen etwas ähnliches gepostet!!! Habe deine Tips bis auf das Objekt als TPanel zudeklarieren befolgt!

Habe jedoch wieder ein Problem :-( Wenn ich zwei Instanzen erzeugt habe, kann ich das erste Objekt also Auto1 löschen ohne Fehlermeldung wenn ich aber Auto2 per btncloseclick löschen will kommt immer eine EAccessViolation Exeption!!!


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:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
unit objekte;

interface

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

type
  //TOnClickEvent = procedure (Sender:TObject) of object;

  TAuto= class(TObject)
    //FOnClick: TOnClickEvent;
    fx:Integer;
    fy:Integer;
    test:TPanel;
    btn_close:TButton;
    constructor Create(AOwner: TComponent);
    destructor  destroy;


    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure BtnCloseClick(Sender:TObject);
    //procedure anzeigen(xpos,ypos:Integer);
end;

implementation
var

  inReposition : boolean;
  oldPos : TPoint;
  //Sender:TPanel;

constructor TAuto.Create;
begin
//inherited;
test := TPanel.Create(form1);
with test do
  begin
    Visible :=true;
    Parent:=form1;
    Width :=100;
    Height :=100;
    onMouseDown:=ControlMouseDown;
    OnMouseUp:=ControlMouseUp;
    OnMouseMove:=ControlMouseMove;
  end;
//inherited;
btn_close:= TButton.Create(form1);
with btn_close do
  begin
    parent:=test;
    width:=10;
    height:=10;
    caption:= 'x';
    top:=0;
    left:=90;
    OnClick:=BtnCloseClick;
  end;

end;

destructor TAuto.Destroy;
begin
btn_close.Free;
//test.free;
inherited;
end;

procedure TAuto.BtnCloseClick(Sender:TObject);
begin
TButton(sender).parent.free;
//TButton(sender).Caption :='x';
inherited;
end;

//////////////////MOUSEMOVE///////////////////////
procedure TAuto.ControlMouseUp(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if inReposition then
  begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
    inReposition := False;
  end;
end;

procedure Tauto.ControlMouseMove(
  Sender: TObject;
  Shift: TShiftState;
  X, Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if inReposition then
  begin
    with TWinControl(Sender) do
    begin
      GetCursorPos(newPos);

      if ssShift in Shift then
      begin //resize
        Screen.Cursor := crSizeNWSE;
        frmPoint := ScreenToClient(Mouse.CursorPos);
        if frmPoint.X > minWidth then
          Width := frmPoint.X;
        if frmPoint.Y > minHeight then
          Height := frmPoint.Y;
      end
      else //move
      begin
        Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X;
        Top := Top - oldPos.Y + newPos.Y;
        oldPos := newPos;
      end;
    end;
  end;
end(*ControlMouseMove*)

procedure TAuto.ControlMouseDown(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState;
  X, Y: Integer);
begin
  if(Sender is TWinControl) then
  begin
    inReposition:=True;
    SetCapture(TWinControl(Sender).Handle);
    GetCursorPos(oldPos);
  end;
end;
//////////////////////////////////////////////////

end.


jakobwenzel - Mi 12.07.06 14:11

Kanns sein, dass du Auto2 als

Delphi-Quelltext
1:
Auto2:=Auto1;                    

initialisierst?


covel - Mi 12.07.06 14:23

nein, sodern mit


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
uses objekte;
{$R *.dfm}

var
auto1,auto2:Tauto;

procedure TForm1.Panel1Click(Sender: TObject);
begin
Auto1:=TAuto.Create(self);//(120,120);
Auto2:=TAuto.Create(self);
end;


oder ist das dass gleiche wie auto2:=auto1;?


crowley - Mi 12.07.06 14:28

nein... die wurzel des bösen ist, dass du nur EINEN button erzeugst...

du erzeugst ihn ja immer mit


Delphi-Quelltext
1:
  btn_close := TButton.Create(form1);                    


Dabei soll der Owner des Buttons nicht das Form sondern dein Auto sein, oder ? dadurch erzeugst du eine Instanz deines btn_close nach der anderen, aber du hast immer nur den zuletzt erzeugten... gibst du diesen frei, hast du keinen button mehr, auf den du zugreifen kannst... dafür aber noch viele im speicher!

desweiteren... kann ich anfangen zu schreien, wenn ich in einem constructor eines Objektes sowas lese

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:
constructor TAuto.Create;  
begin  
  //inherited;  
  test := TPanel.Create(form1);  { <--- DAS HIER MEINE ICH}
  with test do  
  begin  
    Visible :=true;  
    Parent:=form1;  
    Width :=100;  
    Height :=100;  
    onMouseDown:=ControlMouseDown;  
    OnMouseUp:=ControlMouseUp;  
    OnMouseMove:=ControlMouseMove;  
  end;  
//inherited;  
  btn_close:= TButton.Create(form1);  
  with btn_close do  
  begin  
    parent:=test;  
    width:=10;  
    height:=10;  
    caption:= 'x';  
    top:=0;  
    left:=90;  
    OnClick:=BtnCloseClick;  
  end;  
end;


Du setzt damit voraus, dass bei der Verwendung von der Klasse TAuto IMMER ein form1 vorhanden ist! lass das form1 da weg! entweder packst du da nil rein... oder Self... oder du solltest da definitiv ein Panel draus machen, dann brauchst du auch dein test nicht mehr! Im constructor solltest du als ERSTES immer das inherited Create; aufrufen.

Desweiteren solltest du auch im destructor auch test freigeben...


_frank_ - Mi 12.07.06 14:32

nein, ist nicht das gleiche...hast es schon richtig gemacht.
bei Auto2:=auto1; kopierst du nur den Pointer, d.h. es zeigen beide variablen auf 1 Objekt. wenn du es freigibst, sind beide Pointer (da gleich) ungültig.
Create erstellt ein neues Objekt und gibt den Pointer zurück, welchen du deiner variablen zuweist.

Gruß Frank


covel - Mo 17.07.06 09:51

So ich erzeuge nun die Buttons als Array, kann die einzelnen Panels aber immer noch nicht über Btn_close löschen.


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:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
unit objekte;

interface

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

type

  TAuto= class(TObject)
    fx:Integer;
    fy:Integer;
    test:Array[0..10of TPanel;
    btn_close:Array [0..10of TButton;
    constructor Create(AOwner: TComponent);
    //destructor  destroy;


    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure BtnCloseClick(Sender:TObject);
    //procedure anzeigen(xpos,ypos:Integer);
end;

implementation
var
  inReposition : boolean;
  oldPos : TPoint;
  x,y: integer;

constructor TAuto.Create;
begin
test[x] := TPanel.Create(nil);
with test[x] do
  begin
    Visible :=true;
    Parent:=form1;
    Width :=100;
    Height :=100;
    onMouseDown:=ControlMouseDown;
    OnMouseUp:=ControlMouseUp;
    OnMouseMove:=ControlMouseMove;
    caption:= inttostr(x);
  end;

btn_close[y]:= TButton.Create(nil);
with btn_close[y] do
  begin
    parent:=test[x];
    width:=10;
    height:=10;
    caption:= 'x';
    top:=0;
    left:=90;
    OnClick:=BtnCloseClick;
  end;
inc(x);
inc(y);
end;

//destructor TAuto.Destroy;
//begin
//inherited;
//end;

procedure TAuto.BtnCloseClick(Sender:TObject);
begin
//TButton(sender).Free;
//TButton(sender).parent.free;
TButton(sender).destroy;
inherited;
end;

//////////////////MOUSEMOVE///////////////////////
procedure TAuto.ControlMouseUp(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if inReposition then
  begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
    inReposition := False;
  end;
end;

procedure Tauto.ControlMouseMove(
  Sender: TObject;
  Shift: TShiftState;
  X, Y: Integer);
const
  minWidth = 20;
  minHeight = 20;
var
  newPos: TPoint;
  frmPoint : TPoint;
begin
  if inReposition then
  begin
    with TWinControl(Sender) do
    begin
      GetCursorPos(newPos);

      if ssShift in Shift then
      begin //resize
        Screen.Cursor := crSizeNWSE;
        frmPoint := ScreenToClient(Mouse.CursorPos);
        if frmPoint.X > minWidth then
          Width := frmPoint.X;
        if frmPoint.Y > minHeight then
          Height := frmPoint.Y;
      end
      else //move
      begin
        Screen.Cursor := crSize;
        Left := Left - oldPos.X + newPos.X;
        Top := Top - oldPos.Y + newPos.Y;
        oldPos := newPos;
      end;
    end;
  end;
end(*ControlMouseMove*)

procedure TAuto.ControlMouseDown(
  Sender: TObject;
  Button: TMouseButton;
  Shift: TShiftState;
  X, Y: Integer);
begin
  if(Sender is TWinControl) then
  begin
    inReposition:=True;
    SetCapture(TWinControl(Sender).Handle);
    GetCursorPos(oldPos);
  end;
end;
//////////////////////////////////////////////////

end.


crowley - Mo 17.07.06 10:10

Was hältst du davon ?


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 objekte;

interface

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

type

  TAuto= class(TObject)
    fx:Integer;
    fy:Integer;
    test:TPanel;
    btn_close:TButton;
    constructor Create(AOwner: TComponent);
    destructor  destroy;
    procedure BtnCloseClick(Sender:TObject);
  end;

implementation
var
  inReposition : boolean;
  oldPos : TPoint;

constructor TAuto.Create(AOwner: TComponent);
begin
  inherited Create;

  test := TPanel.Create(Self); // oder TPanel.Create(nil);
  with test do
  begin
    Visible := true;
    Parent  := AOwner;   // <-- WICHTIG: Hier kein statisches Form angeben
    Width   := 100;
    Height  := 100;
    onMouseDown:=ControlMouseDown;
    OnMouseUp:=ControlMouseUp;
    OnMouseMove:=ControlMouseMove;
  end;

  btn_close := TButton.Create(test);
  with btn_close do
  begin
    parent:=test;
    width:=10;
    height:=10;
    caption:='x';
    top:=0;
    left:=90;
    OnClick:=BtnCloseClick;
  end;
end;

destructor TAuto.Destroy;
begin
  test.free;
  btn_close.free;

  inherited;
end;

procedure TAuto.BtnCloseClick(Sender:TObject);
begin
  Close;
end;

end.


Noch einmal: Leite dir TAuto von TPanel ab. Desweiteren kannst du in einer Ereignis-Routine die aufrufende Komponente nicht freigeben. Das gibt dir immer einen Zugriffsfehler, da diese Komponente ja quasi "noch in Benutzung" ist. Dein Code ist seeeehr fehleranfällig, so wie du ihn da zusammenbaust... und noch etwas: benutze den destructor, da solltest du ALLE im Panel integrierten Komponenten frei geben.


covel - Mo 17.07.06 11:01

wie leite ich TAuto den von TPanel genau ab?? Bei deinem Quellcode bekommen ich ne fehlermeldung


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
 test := TPanel.Create(self); // <----Funkt. nur mit nil
  with test do
  begin
    Visible := true;
    Parent  := AOwner;   // <--[Fehler] objekte.pas(81): Inkompatible Typen: 'TWinControl' und 'TComponent' 
    Width   := 100;
    Height  := 100;
    onMouseDown:=ControlMouseDown;
    OnMouseUp:=ControlMouseUp;
    OnMouseMove:=ControlMouseMove;
  end;


crowley - Mo 17.07.06 11:10

Ist gar nicht mal so schwer ;)


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:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
unit objekte;  
 
interface  

uses  
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  Dialogs, ExtCtrls, StdCtrls;  
 
type  
  TAuto= class(TPanel)  
    fx:Integer;  
    fy:Integer;  
    btn_close:TButton;  
    constructor Create(AOwner: TComponent);  
    destructor destroy;  
    procedure BtnCloseClick(Sender:TObject);  
    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);  
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);  
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);  
  end;  

 
implementation  
var  
  inReposition : boolean;  
  oldPos : TPoint;  
 
constructor TAuto.Create(AOwner: TComponent);  
begin  
  inherited Create(AOwner);  

  Visible := true;  
  Width   := 100;  
  Height  := 100;  
  OnMouseDown:=ControlMouseDown;  
  OnMouseUp:=ControlMouseUp;  
  OnMouseMove:=ControlMouseMove;  

 
  btn_close := TButton.Create(Self);  
  with btn_close do  
  begin  
    parent:=Self;  
    width:=10;  
    height:=10;  
    caption:='x';  
    top:=0;  
    left:=90;  
    OnClick:=BtnCloseClick;  
  end;  
end;  

 
destructor TAuto.Destroy;  
begin  
  btn_close.free;  
  inherited;  
end;  
 
procedure TAuto.BtnCloseClick(Sender:TObject);  
begin  
  Self.Free; {Befürchte aber nach wie vor, dass du das Free so nicht aufrufen kannst, da du in einer Ereignis-Routine eines Objektes dieses nicht freigeben kannst}
end;  

//////////////////MOUSEMOVE///////////////////////  
procedure TAuto.ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);  
begin  
  if inReposition then  
  begin  
    Screen.Cursor := crDefault;  
    ReleaseCapture;  
    inReposition := False;  
  end;  
end;  

procedure TAuto.ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);  
const  
  minWidth = 20;  
  minHeight = 20;  
var  
  newPos: TPoint;  
  frmPoint : TPoint;  
begin  
  if inReposition then  
  begin  
    with TWinControl(Sender) do  
    begin  
      GetCursorPos(newPos);  

 
      if ssShift in Shift then  
      begin //resize  
        Screen.Cursor := crSizeNWSE;  
        frmPoint := ScreenToClient(Mouse.CursorPos);  
        if frmPoint.X > minWidth then  
          Width := frmPoint.X;  
        if frmPoint.Y > minHeight then  
          Height := frmPoint.Y;  
      end  
      else //move  
      begin  
        Screen.Cursor := crSize;  
        Left := Left - oldPos.X + newPos.X;  
        Top := Top - oldPos.Y + newPos.Y;  
        oldPos := newPos;  
      end;  
    end;  
  end;  
end(*ControlMouseMove*)  
 
procedure TAuto.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);  
begin  
  if(Sender is TWinControl) then  
  begin  
    inReposition:=True;  
    SetCapture(TWinControl(Sender).Handle);  
    GetCursorPos(oldPos);  
  end;  
end;  
//////////////////////////////////////////////////  
 
end.


covel - Mo 17.07.06 11:30

bekomme ne fehlermeldung bei


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
TAuto= class(TPanel)  
    fx:Integer;  <---[Fehler] objekte.pas(193): Das Published-Feld 'fx' ist weder vom Typ class noch interface
    fy:Integer;  <---[Fehler] objekte.pas(194): Das Published-Feld 'fy' ist weder vom Typ class noch interface
    btn_close:TButton;  
    constructor Create(AOwner: TComponent);  
    destructor destroy;


habe die zeilen gelöscht!

Jedoch wenn ich nun mit

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Panel1Click(Sender: TObject);
begin
Auto1:=TAuto.Create(self);
end;


Auto1 erzeugen will wird es mir auf der Form1 nicht angezeigt!! Muss ich nen parent setzen?ß

Grüße Michael


crowley - Mo 17.07.06 11:40

Mein Fehler:

du solltest in einem Objekt/Klasse/Komponente immer zwischen private/public/published- properties/procedure etc differenzieren. fx, fy hattest du ja gar nicht benutzt, warum somit sowieso überflüssig.



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:
{...}   
type    
  TAuto= class(TPanel)
  private
    btn_close:TButton;    
    procedure BtnCloseClick(Sender:TObject);    
    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);    
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);    
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);    
  public
    constructor Create(AOwner: TComponent);    
    destructor destroy;    
  end;    

{...}
implementation    

constructor TAuto.Create(AOwner: TComponent);    
begin    
  inherited Create(AOwner);    

  Parent := AOwner;
  Visible := true;    
  Width   := 100;    
  Height  := 100;    
  OnMouseDown:=ControlMouseDown;    
  OnMouseUp:=ControlMouseUp;    
  OnMouseMove:=ControlMouseMove;    
{...}


covel - Mo 17.07.06 11:44

Noch nen Fehler :-(


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
constructor TAuto.Create(AOwner: TComponent);  
begin
  inherited Create(AOwner);
  Parent := AOwner;   <---[Fehler] objekte.pas(214): Inkompatible Typen: 'TWinControl' und 'TComponent'
  Visible := true;
  left:=10;
  top:=10;
  Width   := 100;
  Height  := 100;
  OnMouseDown:=ControlMouseDown;
  OnMouseUp:=ControlMouseUp;
  OnMouseMove:=ControlMouseMove;


crowley - Mo 17.07.06 12:09

tu mir mal einen gefallen und poste mal deine ganze unit (oder pack mir das ganze projekt mal in eine zip datei)... mit dieser flickenarbeit kommen wir ja nicht wirklich voran ;)

C.


covel - Mo 17.07.06 12:16

here it is!! Erstmal besten dank das du dir so viel mühe gibst!!!!


crowley - Mo 17.07.06 12:35

momentan ist unsere firmenfirewall auf "paranoid" eingestellt und ich kann die datei von hier aus nicht herunterladen. ich schau mir das heute abend mal von zuhause an.

hoffe, du kannst noch so lange warten ;)

C.


covel - Mo 17.07.06 12:38

alles klar ich warte :-)


crowley - Mo 17.07.06 21:11

ich habe ein paar kleine veränderungen an dem quelltext vorgenommen, aber nach wie vor gilt: du kannst eine komponente nicht in einer ihrer eigenen ereignisroutinen freigeben.

dafür müsstest du dir noch eine andere lösung einfallen lassen...


covel - Do 20.07.06 09:42

sry das ich mich erst so spät melde. funktioniert alles super!! aber wie kann ich die Panels wieder löschen?? Ich könnte es per timer oder über nen extra button realisieren! Denke mal die timer lösung ist nicht sehr elegant. Könnte ich das Problem auch mit Threads lösen?

grüße michael


crowley - Do 20.07.06 09:46

hm... du könntest deinem Auto ein eigenes Event spendieren (sowas wie "ButtonClick")... und das rufst du aus dem Programm heraus auf (nicht innerhalb der Komponente).

Da drin machst du dann dein "free".


covel - Fr 21.07.06 10:08

könntest du mir noch nen tip geben?? weiß nicht so recht wie ich anfangen soll.


freak4fun - Fr 21.07.06 10:40

Hallo,
ich hab auch mal mein Glück versucht. Du hast noch einige sehr unschöne Sachen drin, wie globale Variablen. *schüttel* Aber das wird schon. ;)

Ich hoffe das hilft dir weiter.

MfG
freak 8)


covel - Fr 21.07.06 10:46

leider hilft mir das nicht weiter, da beim löschen des Panels immer noch eine Fehlermeldung kommt.


freak4fun - Fr 21.07.06 11:05

Welche Fehlermelfung bekommst du denn? Ich hatte mit meinem Code keine Probleme. Wäre auch noch interessant an welcher Stelle. ;)

MfG
freak


covel - Fr 21.07.06 11:30

Der Fehler: ist eine Exception der Klasse EAccessViolation aufgetreten.
Der Fehler passiert in folgendem Quellcode. Denke mal es liegt daran das ich das Panel und den Button löschen will während dieser die Lösch-Aktion noch ausführt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
destructor TAuto.Destroy;
begin
  btn_close.free;
  inherited;
end;

procedure TAuto.BtnCloseClick(Sender:TObject);
begin
  Self.Free;
end;


Ich müßte beim BtnCloseClick nen timer aufrufen, welcher als Parameter den namen des PAnel übergibt. Weiß aber nicht wie das gehen soll.


freak4fun - Fr 21.07.06 12:18

Vielleicht hilft dir das [http://www.delphipraxis.net/topic29732_controls+die+sich+selbst+zerstoeren.html&highlight=free+self+self+free] weiter.

MfG
freak


covel - Fr 21.07.06 13:55

das hat sehr geholfen!!! Nur wird das Panel auf dem der Button erstellt worde ist nicht mitgelöscht. Ist klar warum!! Wie kann ich aber das problem lösen ??

Rufe den Code wie folgt auf :


Delphi-Quelltext
1:
2:
3:
4:
procedure TAuto.BtnCloseClick(Sender:TObject);
begin
  PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer(Sender));
end;


erstellt wird das objekt wie folgt:

Delphi-Quelltext
1:
2:
3:
Auto1 := TAuto.Create(self);
Auto2 := TAuto.Create(self);
Auto3 := TAuto.Create(self);



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
  TAuto= class(TPanel)
  private
    btn_close:TButton;
    procedure BtnCloseClick(Sender:TObject);
    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

  public
    procedure WMKillControl(var msg:TMessage); message WM_KILL_CONTROL;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;


freak4fun - Fr 21.07.06 15:27

Ich hab es mit

Delphi-Quelltext
1:
PostMessage(Parent.Handle, WM_KILL_CONTROL, 0, Integer(Sender));                    


versucht, aber das gibt wieder eine Exception. :( Kannst du nicht auf den Schließen-Button verzichten und den Code direkt für das Panel benutzen? Oder ist das onClick schon belegt?

//edt: Versuch mal:

Delphi-Quelltext
1:
PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer((Sender as TButton).Parent));                    


MfG
freak


covel - Mo 24.07.06 08:21

So das mit:


Delphi-Quelltext
1:
 PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer((Sender as TButton).Parent));                    

hat geklappt. Jedoch werden die Variablen Auto1, Auto2... nicht wieder freigegeben. Wie kann ich diese nun mit freigeben?? Habe es mit FreeAndNil(self) versucht, bekomme jedoch eine Exception.


freak4fun - Mo 24.07.06 09:21

Wenn du das Auto.Create(Self); aufrifst wird als owner das Form gesetzt. Also wird das Objekt Auto freiigegegeben, wenn das Formular freigegeben wird. Bei FreeAndNil(); würde ich Auto als Parameter übergeben. Denn wenn du FreeAndNil(Self); in den Destructor von Autoschreibst wird dadurch der Destructor wieder aufgerufen. ;) Das ist sowieso recht tricky, was du da machst. An welcher Stelle steht dein FreeAndNil(Self);?

MfG
freak


covel - Mo 24.07.06 10:00


Delphi-Quelltext
1:
2:
3:
4:
5:
destructor TAuto.Destroy;
begin
  //FreeAndNil(Self);  <---- Hier würde ich das FreeAndNil aufrufen,jedoch kommt dann eine Fehlermeldung   
  inherited Destroy;
end;





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:
81:
82:
unit objekte;

interface

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

const
   WM_KILL_CONTROL = WM_USER+ 66;

type
  TAuto= class(TPanel)
  private
    btn_close:TButton;
    procedure BtnCloseClick(Sender:TObject);
    procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
    procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

  public
    procedure WMKillControl(var msg:TMessage); message WM_KILL_CONTROL;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;



implementation
var
  inReposition : boolean;
  oldPos : TPoint;

procedure TAuto.WMKillControl(var msg: TMessage);
var
   c : TControl;
   i : Integer;
begin
   c := TControl(msg.LParam);
   if not Assigned(c) then
      Exit;
   c.Free;
   windows.MessageBeep($FFFFFFFF);
end;

constructor TAuto.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Parent := TWinControl(AOwner);
  Visible := true;
  left:=10;
  top:=10;
  Width   := 100;
  Height  := 100;
  OnMouseDown:=ControlMouseDown;
  OnMouseUp:=ControlMouseUp;
  OnMouseMove:=ControlMouseMove;

  btn_close := TButton.Create(Self);
  with btn_close do
  begin
    parent:=Self;
    width:=10;
    height:=10;
    caption:='x';
    top:=0;
    left:=90;
    OnClick:=BtnCloseClick;
  end;
end;


destructor TAuto.Destroy;
begin
  //FreeAndNil(Self);  <---- Hier würde ich das FreeAndNil   
  inherited Destroy;
end;

procedure TAuto.BtnCloseClick(Sender:TObject);
begin
 PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer((Sender as TButton).Parent));
end;


freak4fun - Mo 24.07.06 10:08

Ich denke es reicht, wenn du deine Atoobjekte im Destructor des Formulars frei gibst. :)


covel - Mo 24.07.06 10:22

Wenn ich das richtig verstehe soll ich Auto1,Auto2... löschen wenn ich die Form1 schließe. Das ist jedoch nicht das was ich suche. ich will später beliebig viele Objekte (zb. Auto1,..Auto99) erstellen, die einzeln gelöscht werden können.


crowley - Mo 24.07.06 10:29

hallo covel...

da meld ich mich doch auch nochmal zu wort... dieses problem hast du seeehr oft bei allen möglichen klassen/komponenten/objekten...

und zwar legst du dir ein objekt/klasse/etc im hauptformular an... gibst es später frei... aber der zeiger des hauptformulars zeigt immer noch auf diese stelle im speicher (auch wenn er schon lange nicht mehr reserviert ist).

der ansatz von dir ist da nicht gut zu gebrauchen... wenn das objekt sich selber frei gibt, kriegt davon doch das hauptform nichts mit und kann folglich den zeiger auf das objekt nicht zurücksetzen.

besser wäre nun an dieser stelle, wenn du deinem Objekt zwar ein ButtonClick- Ereignis spendierst, dieses aber nach aussen hin sichtbar machst... dann kannst du im MainForm bei Auto.CloseButtonClick einfach dein


Delphi-Quelltext
1:
FreeAndNil(TAuto(Sender))                    


machen


freak4fun - Mo 24.07.06 10:31

Das kannst du ja auch machen. Du kannst aber nicht ein Objekt im Objekt selbst freigeben. Mir fehlt ehrlich gesagt das Gesamtbild. Wir reden hier über Einzelprobleme. Vielleicht gibt es ja eine andere Möglichkeit. KAnnst du mir vielleicht mal schreiben was du überhaupt machen willst? :)
Ansonsten bin ich mit meinem Wissen jetzt auch am Ende. :(


covel - Mo 24.07.06 10:37

So ich habe mal das Programm gepostet. Ich will beliebig viele Objekt erstellen, die ich dann einzeln löschen kann.


freak4fun - Mo 24.07.06 11:12


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:
var
  Autos: Array[0..10of TAuto;

//Erstellen der einzelnen Objekte
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := Low(Autos) to High(Autos) do
    if not Assigned(Autos[i]) then
      begin
        Autos[i] := TAuto.Create(Self);
        Autos[i].Tag := i;
        break;
      end;
end;

//Löschen aller Objekte
procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  for i := Low(Autos) to High(Autos) do
    FreeAndNil(Autos[i]);
end;

//Löschen des ausgewählten Objekts
procedure TForm1.Button3Click(Sender: TObject);
begin
  FreeAndNil(Autos[Self.Tag]);
end;

unit: objects

//Aktive Element setzen
procedure TAuto.ControlMouseClick(Sender: TObject);
begin
  (Self.Owner as TObject).Tag := Self.Tag;
end;


Ich würde das Array noch in den Public-Teil verschieben.

Ich hoffe das Hilft dir weiter. :)


covel - Mo 24.07.06 12:34

Das hat mir weiter geholfen. Aber der button3 war nur zu testzwecken. Den Button2 wird soll es später auch nicht geben.


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button3Click(Sender: TObject);
begin
  FreeAndNil(Autos[Self.Tag]);
end;


dieser Code sollte bei dem Btn_close der sich auf dem Panel befindet ausgelöst werden.

Ich weiß aber nicht wie ich den Namen des Panels übermitteln muss/soll.


freak4fun - Mo 24.07.06 12:50

Also:

Mit

Delphi-Quelltext
1:
2:
3:
4:
procedure TAuto.BtnCloseClick(Sender:TObject);
begin
 PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer((Sender as TButton).Parent));
end;


rufst du ja


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TAuto.WMKillControl(var msg: TMessage);
var
   c : TControl;
begin
   c := TControl(msg.LParam);
   if not Assigned(c) then
      Exit;

   c.Free;
   windows.MessageBeep($FFFFFFFF);
end;


auf.

In msg.LParam steht das Handle (vermute ich mal, zumindest eine IdentifikationsID) des entsprechenden Autos. Also wird für das Auto Free aufgerufen. c.Free = Auto.Free. Das machen wir, weil sich ein Objekt nicht selbst zerstören und freigeben kann.

//Edit: (Sender as TButton).Parent) = Panel = Autos[i]


covel - Mo 24.07.06 13:42

So werde es nun wie folgt machen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TAuto.BtnCloseClick(Sender:TObject);
begin
 (Self.Owner as TObject).Tag := Self.Tag;
 form1.Button3.Visible :=true;

end;


button3:

Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button3Click(Sender: TObject);
begin
FreeAndNil(Autos[Self.Tag]);
button3.Visible := false;
end;


ist zwar nicht ganz das was ich machen wollte..aber nunja man kann nicht alles haben :-) Besten Dank @ freak4fun und crowley


freak4fun - Mo 24.07.06 13:56

Und was willst du mit dem Visible jetzt bewirken? Tut mir leid, kann ich nicht nachvollziehen. Aber du wirst schon wissen was du machst ... 8)

Ich würd dann am Ende auch gern mal das fertige Programm sehen, wenn du nichts dagegen hast. ;)

MfG
freak


covel - Mo 24.07.06 14:05

Die Panels und der dazu gehörige Name der Variable sollte per Btn_click gelöscht werden. Da dies nicht so einfach möglich ist, habe ich nun den Button3 zur hilfe genommen. Dieser Button wird nur sichtbar wenn der Btn_close gedrückt wird.

Wenn das Programm fertig ist, werde ich mich bei dir melden.

Grüße Michael


freak4fun - Mo 24.07.06 14:38

Aber es funktioniert doch, oder nicht. Wen man auf erstellen clickt kommt ein Panel und wenn man auf den 'x'-Button clickt verschwindet es wieder. Ist es nicht das was du wolltest? Wenn du jetzt mit dem butto3 arbeitest und damit das Panel löscht kannst du dir den 'x'-Button und das PostMessage + Anhang sparen. :roll:

MfG
freak


covel - Mo 24.07.06 14:42

genau das passiert das problem ist nur das dann die Variable Auto1 usw. nicht freigegeben werden.


freak4fun - Mo 24.07.06 14:45

user profile iconcovel hat folgendes geschrieben:
das problem ist nur das dann die Variable Auto1 usw. nicht freigegeben werden.


Was verstehtst du denn unter "freigegeben"? Weißt du was c.Free; in meinem/deinem Code macht? :) Ich würde dir gern weiterhelfen, aber ich seh dein Problem leider nicht. :(

MfG
freak


crowley - Mo 24.07.06 15:52

@freak
C.free bewirkt zwar, dass der Speicher freigegeben wird, aber Auto1 noch immer auf dieser Speicherbereich zeigt... da fehlt an der Stelle ein Auto1 := nil

@covel
ich habe gerade die große befürchtung, dass du dir damit überhaupt keinen gefallen tust, wie du das machst. von hinten durch die brust ins auge würd man dazu wohl sagen. bitte nimmer nicht wieder in deine auto-klasse das fixe form1 rein und mach es dir doch nicht so unnötig schwer...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
unit objekte;

type
  TAuto = class(TPanel)
  private
    FCloseClick: TNotifyEvent;
    procedure BtnCloseClick(Sender:TObject); 
  published
    property OnCloseClick: TNotifyEvent read FCloseClick write FCloseClick;
  end;

{...}
procedure TAuto.BtnCloseClick(Sender:TObject); 
begin
  if Assigned(FCloseClick) then
    FCloseClick(Self);
end;


das ist das, was du in deiner objekte.pas machen musst... nun noch Form1

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
type
  TForm1 = class(TForm)
    procedure CloseButtonClick(Sender:TObject);
  private
  public
  end;

{...}

{
 wo immer du ein Auto anlegst:
 Autos[x].OnCloseClick := CloseButtonClick;
}


procedure TForm1.CloseButtonClick(Sender:TObject);
begin
  FreeAndNil(Autos[TAuto(Sender).Tag)]); // müsste eigentlich so klappen
end;


ist in jedem falle eine "schönere" lösung...


crowley - Mo 24.07.06 15:53

aus versehen doppeltes posting


covel - Mi 26.07.06 11:17

Moin, leider klappt es noch immer nicht. Habe den Quellcode von crowley übernohmen. Jedoch tretten Fehler beim Löschen der einzelnen Panels auf.

Das Programm liegt als Anhang bei. Wäre schön wenn jemand mal drüber gucken könnte

Grüße Michael


Softchaos67 - Mi 26.07.06 11:30

Wann tritt denn ein Fehler auf?
Bei mir läuft das Proggi einwandfrei.


freak4fun - Mi 26.07.06 11:39

Wenn ich alle 3 Panels erstelle und dann das in der Mitte lösche bekomm ich ne AV. :oops:


covel - Mi 26.07.06 11:46

Der Fehler tritt beim löschen der Panels über den X-Button auf. Über den Löschen-Button werden bei mir auch alle panels wieder gelöscht.

Der Fehler tritt immer auf wenn die das zweite Panel löschen will, ebal wie viele ich erstelle...


Softchaos67 - Mi 26.07.06 11:55

Ok, hab den Fehler jetzt auch. Immer wenn man das Panel Nummer 1 löscht, aber nur einmal, dann klappts.
Vielleicht hat das was mit dem Harakiri deiner Komponente zu tun.