Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Komponenten freigeben - Invalid pointer operation (https://www.delphipraxis.net/78863-komponenten-freigeben-invalid-pointer-operation.html)

roth 12. Okt 2006 10:01


Komponenten freigeben - Invalid pointer operation
 
Guten Tag!

Ich mache per laufzeit ein paar TComboBox - Komponenten. Diese möchte ich wenn die Anwendung geschossen wird freigeben. Und zwar so:

Delphi-Quellcode:
for i := 1  to anz_bedingungen do
  begin
    mybox1[i][1].Free;
    mybox1[i][2].Free;
    mybox1[i][3].Free;
  end;

  for i := 1  to anz_links do
  begin
    mybox2[i][1].Free;
    mybox2[i][2].Free;

  end;
Folgender Fehler kommt dann:
Zitat:

Project DBExplorer.exe raised exception class EInvalidPointer with message 'Invalid pointer operation'. Process stopped. Use Step or Run to continue.

könnt ihr mir helfen!?

vielen dank! mroth

mkinzler 12. Okt 2006 10:12

Re: Komponenten freigeben - Invalid pointer operation
 
Könnte es sein, daß es eher
Delphi-Quellcode:
for i := 0  to anz_links-1 do
heißen müßte?

dizzy 12. Okt 2006 10:15

Re: Komponenten freigeben - Invalid pointer operation
 
Setzt du die Owner (oder Parent - weiss nicht mehr 100%ig welcher der 2 fürs Freigeben relevant war) der Comboboxes auf dein Formular? Wenn ja, dann gibt dieses die bereits frei, so dass entweder du oder das Formular (je nach dem wo das inherited steht) auf ungültige Adressen stößt.

Luckie 12. Okt 2006 10:16

Re: Komponenten freigeben - Invalid pointer operation
 
Haben die Comboboxen einen Owner, der beim Beenden automatisch freigegebn wird? Dann brauchst du sie nicht freigeben.

roth 12. Okt 2006 10:22

Re: Komponenten freigeben - Invalid pointer operation
 
Vielen Dank für die raschen Antworten!


Zitat:

Zitat von mkinzler
Könnte es sein, daß es eher
Delphi-Quellcode:
for i := 0  to anz_links-1 do
heißen müßte?

Nein habe bei 1 angefangen reinzuschreiben!


Zitat:

Zitat von dizzy
Setzt du die Owner (oder Parent - weiss nicht mehr 100%ig welcher der 2 fürs Freigeben relevant war) der Comboboxes auf dein Formular? Wenn ja, dann gibt dieses die bereits frei, so dass entweder du oder das Formular (je nach dem wo das inherited steht) auf ungültige Adressen stößt.

Setze den .parent auf mybox1[i][countCombobox].Parent := Form1.PageControl1.ActivePage;



Zitat:

Zitat von Luckie
Haben die Comboboxen einen Owner, der beim Beenden automatisch freigegebn wird? Dann brauchst du sie nicht freigeben.

Das weis ich nicht! Habe gerade bemerkt das der Fehler auch auftritt wenn ich die Anwendung sonst einfach schliesse....

????

Luckie 12. Okt 2006 10:25

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von roth
Zitat:

Zitat von Luckie
Haben die Comboboxen einen Owner, der beim Beenden automatisch freigegebn wird? Dann brauchst du sie nicht freigeben.

Das weis ich nicht!

Dann zeig uns dochmal, wie du die Comboboxen erstellst. :?

roth 12. Okt 2006 10:31

Re: Komponenten freigeben - Invalid pointer operation
 
Delphi-Quellcode:
 if countCombobox = 0 then
          countCombobox := 1;
        i := anz_bedingungen;
        SetLength(mybox1, i+1);
        SetLength(mybox1[i],3);
        mybox1[i][countCombobox] := TComboBox.Create(Self);
        mybox1[i][countCombobox].Parent := Form1.PageControl1.ActivePage;
        mybox1[i][countCombobox].Text := titel;
        mybox1[i][countCombobox].Left := left;
        mybox1[i][countCombobox].Top := 38+(mybox1[i][countCombobox].Height+10)*i;
        mybox1[i][countCombobox].Width := breite;
        mybox1[i][countCombobox].Items := inhalt;

        countCombobox := countCombobox +1;

        if countCombobox > 3 then
          countCombobox := 1;
anz_bedingungen wird natürlich raufgezählt

Luckie 12. Okt 2006 10:36

Re: Komponenten freigeben - Invalid pointer operation
 
Delphi-Quellcode:
mybox1[i][countCombobox] := TComboBox.Create(Self);
Frage an roth: Haben die Comboboxen nun einen Besitzer oder nicht?

roth 12. Okt 2006 10:39

Re: Komponenten freigeben - Invalid pointer operation
 
Wie nur einen Besitzer!? Habe das erste mal so gearbeitet!

Luckie 12. Okt 2006 10:40

Re: Komponenten freigeben - Invalid pointer operation
 
Frage an roth: was ist das für ein Parameter den du bei Create übergibst?

roth 12. Okt 2006 10:47

Re: Komponenten freigeben - Invalid pointer operation
 
JA der besitzer!
Habe ihn mal geändert auf Form1.PageControl1.ActivePage weil die Boxen da drauf liegen!

das Problem beim schliessen bleibt aber trotzdem!

Luckie 12. Okt 2006 10:50

Re: Komponenten freigeben - Invalid pointer operation
 
OK, das haben wir also rausgefunden. Und jetzt guck dir noch mal Beitrag #4 in diesem Thread von mir an.

roth 12. Okt 2006 10:54

Re: Komponenten freigeben - Invalid pointer operation
 
ist ja schön und gut!
möchte jetzt aber nicht erst beim beenden die komponenten freigeben, sondern auch mal wenn ich sonst auf einen button klicke weil ich dan alles reseten möchte!

Zudem kommt auch beim beenden immer noch dieser Invalid pointer operation!!!!!!!!!!!!!!!!!!!!!!!!!

Luckie 12. Okt 2006 11:08

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von roth
Zudem kommt auch beim beenden immer noch dieser Invalid pointer operation!!!!!!!!!!!!!!!!!!!!!!!!!

Auch wenn du beim Beenden nichts machst?

PS: Ein Ausrufezeichen reicht.

Muetze1 12. Okt 2006 11:22

Re: Komponenten freigeben - Invalid pointer operation
 
... und warum lässt du den Index 0 in der der 2. Dimension deines Arrays mybox1 ungenutzt?

pertzschc 12. Okt 2006 11:26

Re: Komponenten freigeben - Invalid pointer operation
 
Hallo Michael,

wenn ich unter einem Owner (z.B. eine Groupbox) dynamisch 5 Komponenten erstelle
(z.B. Labels) die ich mit Wegwerfnamen versehe, wie kann ich dann diese 5 Labels
wieder freigeben um sie eventuell nach einen Datenrefesh wieder ebenso neu zu erstellen?

Gruß,
Christoph

Muetze1 12. Okt 2006 11:30

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von pertzschc
wenn ich unter einem Owner (z.B. eine Groupbox) dynamisch 5 Komponenten erstelle
(z.B. Labels) die ich mit Wegwerfnamen versehe, wie kann ich dann diese 5 Labels
wieder freigeben um sie eventuell nach einen Datenrefesh wieder ebenso neu zu erstellen?

Ohne die Frage zu beantworten würde ich gerne eine Gegenfrage stellen, weil es vllt. eine performantere Lösung gibt:
Warum Labels freigeben um sie dann wieder zu erzeugen? Warum nicht einfach den Labels den neuen Inhalt zuweisen? Dies könntest du sogar in deinem Akualisierungscode einbringen. Dieser müsste die Labels nur dann erzeugen, wenn er noch keine Instanzen hat. Wenn er sie erzeugt vermerkt er sie sich einfach.

Ein Label freigeben und neu erzeugen macht die Anwendung nur unnlötig langsamer. Wenn du mir den Code zeigst wo du die Labels erstellst und mit Datenbankwerten füllst (die Datenbank dinge kannste weglassen), dann könnte ich dir den Code wahrscheinlich umstellen um es nach meinem Vorschlag abzuarbeiten.

pertzschc 12. Okt 2006 11:40

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von Muetze1
Ohne die Frage zu beantworten würde ich gerne eine Gegenfrage stellen, weil es vllt. eine performantere Lösung gibt:

Danke für Deine Antwort.

Das mit den Labels war beispielhaft gemeint. Mein Programm macht etwas anderes: Ich habe eine Liste von Objekten deren Id eine Guid ist. Initial erzeuge ich aus der Liste mehrere Buttons innerhalb einer Groupbox, in den Namen des Buttons arbeite ich die Guid ein und der Button zeigt einen Namen (Str) des Objektes an. Wenn ein Button gedrückt wird, soll eine bestimmte Aktion ausgelöst werden, zu der es aber notwendig ist, das inhaltlich zum Button gehörende Objekte zu wissen (löse ich über den Buttonnamen anhand der Guid).

Hier mal der Code zu Erzeugen der Buttons:
Delphi-Quellcode:
procedure TMainForm.Create_Selection_Buttons;
var
 _Button: TButton;
  i, ypos, xpos: integer;
  _Activity:TActivity;
begin
  ypos := 15;
  xpos := 10;
  for i := 0 to self.fObjManager.ActivityList.Count-1 do begin
    _Activity:=TActivity(self.fObjManager.ActivityList.Objects[i]);
    // neuer button
    _Button:=TButton.Create(Self);
    with _Button do begin
      Parent:=MainForm.gbActivitySelection;
      Caption:=_Activity.Name;
      Left:=xpos;
      Top:=ypos;
      Width:= MainForm.gbActivitySelection.Width - xpos - xpos;
      Name:=_Activity.GUID_ComponentName;
      OnClick:=Selection_Buttons_Click;
    end;
    ypos := ypos + _Button.Height + 5;
  end;
end;
und hier die Click-Behandlung:

Delphi-Quellcode:
procedure TMainForm.Selection_Buttons_Click(Sender: TObject);
var
  guid, name: string;
  _Activity: TActivity;
  pos: integer;
begin
  if Sender is TButton then begin
    name:=TButton(Sender).Caption;
    guid:=Get_GuidStr_From_ComponentName(TButton(Sender).Name);
    pos:=self.fObjManager.ActivityList.IndexOf(guid);
    _Activity:=TActivity(self.fObjManager.ActivityList.Objects[pos]);
    self.fObjManager.CurrentActivity := _Activity;
  end;
end;
Mein Problem besteht nun darin, das die Objektliste sich zur Laufzeit verändern kann, d.h. neue Objekte hinzukommen oder gelöscht werden. Wie kann ich dann die Buttons entsprechend neu aufbauen.

Gruß,
Christoph

OldGrumpy 12. Okt 2006 11:48

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von roth
!!!!!!!!!!!!!!!!!!!!!!!!!

Ich halte es, was mehrfache Satzzeichen angeht, eher mit Terry Pratchett... :mrgreen:

Muetze1 12. Okt 2006 11:53

Re: Komponenten freigeben - Invalid pointer operation
 
Ok, da würde ich eine andere herangehensweise vorschlagen. Zum einen widerstrebt es mir grundsätzlich irgendwelche Dinge in irgendwelchen Strings abzulegen um dann nachher wieder aus einem String wieder was zu ermitteln. In deinem Falle würde ich einfach folgendes machen:

1. Eine Klasse anlegen die nix weiter hat als 2 Öffentliche Member-Variablen: Einen TButton und eine TActivity. Diese sorgt nachher für die Zuordnung
2. Eine Objektliste welche die Instanzen dieser Klasse enthält
3. Eine Funktion die immer aufgerufen wird, wenn sich irgendwas bei der Liste ändert bzw. besser: geändert hat.

Vorgehensweise:

1. Liste der Miniklasse aktualisieren
- Wenn du in der Objectlist mit der Miniklasse keine Instanz für eine Activity Instanz hast, dann eine Miniklasseninstanz erzeugen, die Activity Instanz zuweisen und der Miniklasse hinzufügen
- Wenn du in der Miniklassenliste eine Instanz einer Miniklasse hast, dessen Activity Instanz du nicht mehr in der Liste deiner Activities findest, dann den vermerkten Button freigeben und den Eintrag aus der Miniklassenliste löschen (was die Miniklasseninstanz gleich mit freigibt)

Damit hättest du alle Änderungen von der Activityliste übernommen. Einfacher wäre das ganze, wenn du in der grossen Verwaltung direkt an den beiden möglichen Punkten ansetzen kannst: Also wenn eine Activity hinzugefügt bzw. gelöscht wird. Dann kannst du dir das durchlaufen der Miniklassenliste ersparen.

Als letztes nun noch die Buttons aktualisieren. Durchlaufe die Miniklassenliste und erzeuge einen Button, wo die Instanz Nil ist. Ansonsten übernehme die Caption von der Activity (falls sie sich geändert hat) und positioniere die Buttons anhand der Position in der Miniklassenliste. Der Name der Buttons ist somit egal, da alles über die Instanzen geregelt wird.

pertzschc 12. Okt 2006 12:06

Re: Komponenten freigeben - Invalid pointer operation
 
Danke für den Tipp!
So werde ich das umsetzen.

Gruß,
Christoph

roth 12. Okt 2006 12:39

Re: Komponenten freigeben - Invalid pointer operation
 
ich lasse den index [0] frei damit ich bessere übersicht habe...sollte ja nichts machen oder!?

und ja der fehler kommt auch wenn ich nichts mache beim beenden!?

:wall:

Luckie 12. Okt 2006 12:44

Re: Komponenten freigeben - Invalid pointer operation
 
Dann liegt der Fehler wo anders.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  edttest: TEdit;
begin
  edtTest := TEdit.Create(self);
  edtTest.Parent := Form1;
end;
Geht wunderbar ohne Absturz beim Beenden.

roth 12. Okt 2006 12:51

Re: Komponenten freigeben - Invalid pointer operation
 
okey! trotzdem vielen dank für eure mühe!

pertzschc 17. Okt 2006 11:45

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von Muetze1
Als letztes nun noch die Buttons aktualisieren. Durchlaufe die Miniklassenliste und erzeuge einen Button, wo die Instanz Nil ist. Ansonsten übernehme die Caption von der Activity (falls sie sich geändert hat) und positioniere die Buttons anhand der Position in der Miniklassenliste. Der Name der Buttons ist somit egal, da alles über die Instanzen geregelt wird.

Nun habe ich noch 2 Fragen:
- welchen (eindeutigen) Namen würdest Du den Buttons geben?
- Wie bekomme ich am einfachsten die Activity-Instanz des gedrückten Buttons heraus?

Gruß,
Christoph

Muetze1 17. Okt 2006 12:18

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von pertzschc
- welchen (eindeutigen) Namen würdest Du den Buttons geben?

Gar keinen. Du hast eine Liste mit allen Instanzen, daher kannst du auch immer wieder in dieser nachschauen wenn du einen brauchst bzw. ansprechen willst. Daher ist der Name Schall und Rauch.

Zitat:

Zitat von pertzschc
- Wie bekomme ich am einfachsten die Activity-Instanz des gedrückten Buttons heraus?

Sender beim Click gibt dir die Instanz des auslösenden Objektes mit, in deinem Fall also die Instanz des Buttons. Daher kannst du einfach durch deine Miniklassenliste laufen und vergleichen ob Sender = Buttoninstanz in deiner Miniklasse ist. Wenn dem so ist, dann hast du in der Miniklasse auch die Activity Instanz parat.

pertzschc 17. Okt 2006 12:55

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von Muetze1
Sender beim Click gibt dir die Instanz des auslösenden Objektes mit, in deinem Fall also die Instanz des Buttons. Daher kannst du einfach durch deine Miniklassenliste laufen und vergleichen ob Sender = Buttoninstanz in deiner Miniklasse ist. Wenn dem so ist, dann hast du in der Miniklasse auch die Activity Instanz parat.

Ja, okay soweit verstanden. Gib mir bitte noch eine Zeile Coding wie ich die Instanzen vergleichen kann, ich blicke es gerade nicht.

Danke,
Christoph

Muetze1 17. Okt 2006 13:01

Re: Komponenten freigeben - Invalid pointer operation
 
Delphi-Quellcode:
Procedure TFormX.ButtonXClick(Sender: TObject);
Var
  i: Integer;
  lActivity: TActivity;
Begin
  lActivity := Nil;

  For i := 0 To Pred(Miniklassenlist.Count) Do
    If ( Miniklassenliste[i] As TMiniklasse ).Button = Sender Then
    Begin
      lActivity := ( Miniklassenliste[i] As TMiniklasse ).Activity;
      Break; // Weiter brauchen wir nicht zu suchen, haben es ja gefunden
    End;

  If Assigned(lActivity) Then
    ShowMessage('Die Activity war ' + lActivity.Blubb ); // was du auch immer von den Daten der Klasse anzeigen lassen könntest...
End;

pertzschc 17. Okt 2006 13:49

Re: Komponenten freigeben - Invalid pointer operation
 
Danke!!!

Sidorion 17. Okt 2006 14:06

Re: Komponenten freigeben - Invalid pointer operation
 
Das schaut mir verdächtig nach ner ActionList aus.
Schau mal in der IDE nach, da gibt es eine Komponente namens TActionList. In diese TActionList kannst Du TActions einfügen. Diese sind sozusagen Deine Applikationsereignisse. Hier gibt es vorgefertigte, wie FileIO, aber auch die Möglichkeit, eigene Events an die Actions zu knüpfen.
Nun zu den Knöpfen. Diese haben eine Property namens Action. Falls Du eine deiner Actions in der ActionList dem Knopf zuweist, ruft dieser dann die execute-Methode dieser Action. Um die Freigabe musst Du Dich überhaupt nicht kümmern. Entweder der Knopf geht bei der Freigabe der Form flöten (vorrausgesetzt Du hast diese als Owner anggegeben) oder Du gibst ihn von Hand frei. Hier würde ich nicht empfehlen, die Knöpfe separtat nochmal zu speichern, sondern die Controls-Liste des jeweiligen Parents durchzugehen, bis der entsprechende Knopf gefunden ist und den hier freizugeben.
Die Sache mit den Actions hat folgenden Vorteil: Du kannst diese Actions auch als Menü darstellen lassen bzw. die execute-Methode direkt aus dem Programm rufen. Ausserdem bietet Delphi die Möglichkeit, die Anordnung des Menüs usw. auch vom Nutzer vornehmen zu lassen und speichert diese auf Platte.

pertzschc 17. Okt 2006 14:17

Re: Komponenten freigeben - Invalid pointer operation
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Sidorion
Das schaut mir verdächtig nach ner ActionList aus.

Danke für Deinen Tipp. Aber das trifft es nicht.
Mein Programm bietet Optionen für eine Zeiterfassung durch einen User an.
Dazu sind Aktitäten des Benutzers erfassbar und werden dann als Buttons dargestellt.
Je nachdem drückt dann der Benutzer den Button der Aktivität, welcher er gerade nachgeht.
Die Zeitprofile werden pro Tag gespeichert und sind dann auswertbar (Chart, Summen etc.)

Gruß,
Christoph

Sidorion 17. Okt 2006 15:20

Re: Komponenten freigeben - Invalid pointer operation
 
Also Doch ne ActionList. Hierzu baust Du Dir nen Definitionsdialog (den Du acuh wieder übern ne Action rufen kannst), der ne neue Action anlegt, und zwar mit der eingegebenen Aktion als Name. Ausserdem kriegt jede Aktion den gleichen Callback. Diese Action-Objekte werden dann in die Action-List gespeichert.
Jetzt kann der Nutzer die so erstellten Aktionen im ActionManager in eine TActionToolBar einfügen und sobald er einen davon klickt, wechselt die Zeiterfassung in den entsprechenden Modus. Dazu fragst Du im callback nur den Namen der aktuellen Aktion ab.

Muetze1 17. Okt 2006 15:34

Re: Komponenten freigeben - Invalid pointer operation
 
Zitat:

Zitat von Sidorion
Dazu fragst Du im callback nur den Namen der aktuellen Aktion ab.

Ich hasse unsichere Stringvergleiche als Programmiermittel. Aber das sagte ich bereits zuvor in diesem Thread...

Und ich sehe bei seiner Anwendung keine Besserung durch die Anwendung von Actions bei dem Problem der Zuordnung von der TActivity Instanz zu der, diesmal Action anstatt Button, Instanz. Und dein Vorschlag an der wichtigen Stelle wieder auf einen Stringvergleich zurück zu fallen, ist genau die Lösung die wir zuvor schon hatten.

pertzschc 17. Okt 2006 15:40

Re: Komponenten freigeben - Invalid pointer operation
 
Ich habe es jetzt so impl. wie von Muetze1 vorgeschlagen. Das funktioniert sehr gut.
Danke Euch beiden für die Hinweise & Tipps.

Gruß,
Christoph

Sidorion 17. Okt 2006 16:13

Re: Komponenten freigeben - Invalid pointer operation
 
Das war vielleicht etwas unglücklich formuliert, aber so wie ichs verstanden habe, wird bei jedem Klick auf einen Knopf ein Zeitstempel geholt und mit dem Namen der aktuellen Aktion verknüpft.
Was ich meinte, war nicht per Namensvergleich rauskriegen, welche Aktion grade den callback ruft, das ist klar, namlich der Sender. Ich meinte, dass man den Namen der Aktion gleich verwenden kann, um ihn mit dem Zeitstempel zu verheiraten. Hier findet also kein Stringvergleich statt.

hoika 17. Okt 2006 22:32

Re: Komponenten freigeben - Invalid pointer operation
 
Hallo,

1.
schmeiss das Teil aus der Components-List des Forms raus,
bevor Form.Destroy aufgerufen wird.

2.
nimm NIL als Parameter statt Self
dann musst du dich aber auch selbst um die Freigabe kümmern.


Heiko


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

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