[Delphi] AV bij verwijderen treenode

Pagina: 1
Acties:

  • pelleke
  • Registratie: Maart 2003
  • Laatst online: 08-11-2024

pelleke

Aut viam inveniam aut faciam

Topicstarter
Hallo! Ik heb een project met een treeview en een controlbar. Als ik het project start gebeurt er het volgende:

1. Er wordt at runtime een button aangemaakt in de controlbar. Zijn onclick-event maakt een nieuwe treenode.
2. Ik klik op de button; er wordt een treenode aangemaakt met een data pointer erbij.
3. Ik klik op die nieuwe treenode. Daardoor wordt TreeViewChange aangeroepen.
4. TreeViewChange gooit alle buttons uit de controlbar, en maakt een nieuwe button. Zijn onclick-procedure verwijdert de treenode.
5. Ik klik op die button.
6. De treenode wordt verwijderd
7. Daardoor wordt TreeViewChange wederom aangeroepen, en worden de buttons weer verwijderd.
8. Als al deze processen zijn afgelopen, krijg ik een AV.

Na wat debuggen kwam ik erachter dat het probleem niet aanwezig is als ik zorg dat de buttons niet verwijderd worden, maar die buttons moeten echt wel weg hoor... :S

Dit klinkt allemaal misschien wat vaag, de sourcecode staat op
http://pelleke.servehttp.com/pelle/DirectContent.zip

Ik heb geprobeerd te debuggen, te steppen en te tracen maar het lijkt wel alsof de AV pas komt nadat alle procedures klaar zijn. Vandaar dat ik het ook zo raar vind...

  • whoami
  • Registratie: December 2000
  • Laatst online: 25-05 23:56
Ik heb gewoon even snel door je code gekeken (niet gerunned, want ik heb die TJv* componenten niet, en wat me zowiezo opviel, is dit:

code:
1
2
3
4
procedure TFrmMain.ToolButton2Click(Sender: TObject);
begin
Treeview.selected.delete;
end;


En dergelijke code kwam ik nu en dan wel eens tegen. Zowiezo is dit niet 'veilig' en 'errorprone'.
Wat als er nl. niets in je Treeview geselecteerd is? Dan is selected nil, en dan krijg je zowiezo een Access violation.
Je zou dat stukje (en overal eigenlijk waar je treeview.selected oid aanspreekt) dit moeten schrijven:
code:
1
2
3
if MyTreeview.Selected <> nil then begin
   MyTreeview.Selected.Delete ();
end;

https://fgheysels.github.io/


  • pelleke
  • Registratie: Maart 2003
  • Laatst online: 08-11-2024

pelleke

Aut viam inveniam aut faciam

Topicstarter
Dank!

Die toolbutton2 event had ik alleen maar ff toegevoegd om dan te kunnen zien dat het met een lossstaande button wel goed werkt, dat was dus alleen maar ff om te testen.

Kan je zien dat het misgaat? (of heb je hem nog niet gecompiled?)

Pel.

  • Domokoen
  • Registratie: Januari 2003
  • Laatst online: 11:01
var <> nil, daarvoor heb je de functie Assigned(var), staat iets netter.
Buttons verwijderen @ runtime heb je liever niet, ik weet niet precies hoe je het doet, maar bij het afsluiten probeert de parent ze waarschijnlijk ook te verwijderen, maar dan is dat al gebeurd... het is beter om ze onzichtbaar te maken (Visible:=False). Treeview nodes zou je wel gewoon moeten kunnen weghalen zonder crashes.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Je kan best componenten runtime vrijgeven. De Owner (niet de parent) wordt gemeld wanneer het component verwijderd wordt en zorgt er voor dat ie niet nogmaals wordt vrijgeven. Het project is mij te groot om voor je te gaan debuggen en bovendien bevat het componenten die ik niet heb en ook niet wil installeren hiervoor. Probeer zelf eens meer te debuggen. Zet 'Use Debug DCUs' aan in je project options, zet eens wat breakpoints, loop stap voor stap door je code en bekijk ondertussen de waardes van je variablen en de callstack. Sloop code uit je programma totdat je weet in welk deel het zit.

We adore chaos because we like to restore order - M.C. Escher


  • pelleke
  • Registratie: Maart 2003
  • Laatst online: 08-11-2024

pelleke

Aut viam inveniam aut faciam

Topicstarter
Na wat debuggen achter het volgende "fenomeen" gekomen:

De error treedt alleen op bij de volgende situatie:

Ik verwijder een treenode, EN ik free daarna meteen alle componenten uit de controlbar.

Zodra ik EEN van beide gebeurtenissen comment, gaat het gewoon goed. Buttons verwijderen mag, alleen dan blijft mijn node staan, OF enkel mijn node verwijderen gaat ook goed, alleen dan wordt mijn controlbar freaking vol...

Ik heb het project herschreven zonder JEDI-componenten, gewoon allemaal meegeleverde VCL trash, en ik heb de controlbar wegens vaag gedrag vervangen door een panel. Helaas mocht dat niet baten, die AV blijft er.

Soms geeft ie overigens een EAbstractError ipv. een AV, maar ik denk dat de oorzaak bij hetzelfde probleem ligt.

Mijn 'makkelijke' versie is te downloaden vanaf http://pelleke.servehttp.com/pelle/DirectContent2.zip

  • pelleke
  • Registratie: Maart 2003
  • Laatst online: 08-11-2024

pelleke

Aut viam inveniam aut faciam

Topicstarter
UPDATE:
Het laatste nieuws voor vandaag. (lees: gister.)

Na een leuke tip van iemand in de chat ben ik mijn VCL gaan doorlopen. Met Step Over bleek het laatste wat hij deed voordat hij de error gaf een aanroep te zijn van de procedure DoMouseup().

Daarop een breakpoint gezet, en dan F7. (Mocht niet baten, ikke kan geen asm lezen)

Wel op een idee gekomen: Geef de caption van 'Catagorie verwijderen' een '&' mee, en stuur 'm via het toetsenbord. En wat denken we: BINGO! Niks geen problemen, Niks geen AV!!! M.a.w. Het wordt dus veroorzaakt door de muishandeling.

Nu vraag ik me alleen af wat ik hier in vredesnaam voor conclusie uit mag trekken, en wat dit te maken mag hebben met de TREEVIEW! (Want die speelt er dus wel degelijk een rol in, als ik TreeView.Selected.Delete cpmment, is er geen enkel probleem)

Dat was het voor vandaag. Mocht iemand mij willen helpen (want verder dan dit kom ik denk ik niet) dan zou ik dat heeeel fijn vinden!

O, trouwens, voor diegenen die het nog niet wisten: De AV treedt op als je het volgende doet.

1. Ga op de eerste treenode staan
2. Klik op Nieuwe Catagorie
3. Klik in de treeview op de nieuwe treenode
4. Klik op Catagorie verwijderen.

Et voila, un AV.

Pel.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ik heb je code even bekeken en ik krijg idd de fout gereproduceerd.

Je probleem is dat je componenten gaat vrijgeven in een event van het component zelf. Met andere woorden: Je bent bezig met code in je button als je m vrij gaat geven. Je trekt je eigen poten onder je stoel vandaan. De oplossing voor Forms is de Release method, maar componenten hebben die niet. Toch kan je een soortgelijke oplossing maken voor alle componenten.

Je zal een windows message naar je jezelf moeten sturen met PostMessage en die message met een functie moeten afvangen. In die functie kan je dan veilig de tabsheet vrijgeven. De message komt namelijk in een message queue en zal pas worden afgehandeld wanneer je netjes uit alle code bent gegaan.

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1