[delphi] AV bij vrijgeven TFrame

Pagina: 1
Acties:

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik heb een TFrame die ik de gebruiker wel of niet kan laten weergeven met een switch. Prima, dus als de gebruiker em aanzet, dan maak ik dat frame aan, zet de Parent property en hij werkt:
Delphi:
1
2
3
Preview := TPreviewPaneFrame.Create(pnlPreviewPane, DB);
Preview.Align := alClient;
Preview.Parent := pnlPreviewPane;

Als de gebruiker em weer uitzet, dan zou je zeggen dat de Parent op nil zetten en Free-en genoeg moet zijn. Maar RemoveComponent is ook nodig, omdat ik em de volgende keer niet kan aanmaken dan (omdat ie dan al bestaat). Dus de volgende code...
Delphi:
1
2
3
Preview.Parent := nil;
pnlPreviewPane.RemoveComponent(Preview);
FreeAndNil(Preview);

...zou het moeten doen. En warempel, als ik erdoorheen stap, werkt dit perfect!
MAAR: nadat dit uitgevoerd is, en ik helemaal door alle "end;" heen stap, komt ie uiteindelijk met een AV bij TCanvas.TryLock. En dit gebeurt niet als ik het frame niet vrijgeef. Op het frame staat ook niets bijzonders, alleen 3 doodnormale componentjes.

日本!🎌


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 26-05 20:33

Tomatoman

Fulltime prutser

Je creëert Preview zodanig dat de owner pnlPreviewPane wordt - zie de constructor. Vervolgens vernietig je handmatig Preview. Als je programma gaat afsluiten en pnlPreviewPane wordt vernietigd, probeert pnlPreviewPane Preview te vernietigen. Uiteraard gaat dat niet meer en krijg je een access violation. Je kunt deze voorkomen door regel 1 te veranderen in
Delphi:
1
Preview := TPreviewPaneFrame.Create(nil);

Wat DB in jouw code doet weet ik trouwens niet.

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
DB is gewoon een extra parameter die ik aan de constructor van het frame togevoegd heb. Heel netjes gemaakt: declareerd als reintroduce en inherited wordt netjes aan het begin van de nieuwe constructor aangeroepen.

De AV krijg ik overigens niet bij het afsluiten van m'n programma, maar gewoon na de event handler (een OnExecute van een action) waarin ie vrijgegeven wordt...

Maargoed, als ik nil als owner opgeef, en die RemoveComponent call weghaal, houd ik dezelfde AV.

日本!🎌


  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Je creëert Preview zodanig dat de owner pnlPreviewPane wordt - zie de constructor. Vervolgens vernietig je handmatig Preview. Als je programma gaat afsluiten en pnlPreviewPane wordt vernietigd, probeert pnlPreviewPane Preview te vernietigen. Uiteraard gaat dat niet meer en krijg je een access violation.
Volgens mij klopt dit niet. TControl.SetParent(AParent: TWinControl); zorgt er nl voor dat FParent.RemoveControl(Self); wordt uitgevoerd. Maw als je zelf Free doet op een Component dan krijgt zn parent dit te horen en verwijderd zn child uit de lijst (dus ook als je parent expliciet op nil zet).
De AV krijg ik overigens niet bij het afsluiten van m'n programma, maar gewoon na de event handler (een OnExecute van een action) waarin ie vrijgegeven wordt...
Kan het zijn dat na het event er een ander event wordt uitgevoerd die gebruik maakt van je frame? Ik kan mij ook voostellen dat het niet toegestaan is een Free te doen op een child in een event-proc. Wat je zou kunnen proberen is om 'jezelf' een WM_USER+XX message te sturen en bij het afvangen van die message de frame te Free'en

Zie bijv. http://groups.google.com/...am.compuserve.com&rnum=22

[ Voor 9% gewijzigd door martijn_brinkers op 27-03-2004 17:04 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Wat TijnFlip zegt. Geef je niet het frame vrij in een stuk code van het frame? of naar aanleiding van een actie op het frame? Want dan zaag je je eigen poten onder je frame vandaan. Forms gebruiken hiervoor Release, maar controls hebben die functie niet. De message die TijnFlip voorstelt is hetzelfde als wat er in de Release van een form gebeurt.

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


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Nee, die OnExecute is gewoon het gevolg van een menu-item aanklikken. Daarna gebeurt er (in mijn code) niets meer. "Mezelf" een message sturen heb ik ook geprobeerd met CM_RELEASE en in het frame dit opvangen en in de message handler Free aan te roepen. Maar het mocht niet baten.

Ik weet niet of het zin heeft, maar de stack trace als de AV verschijnt:
Delphi:
1
2
3
4
5
6
7
TCanvas.TryLock
FreeDeviceContexts
TWinControl.MainWndProc(...)
StdWndProc(...)
TApplication.ProcessMessage(...)
TApplication.HandleMessage
TApplication.Run


Ohja, die OnExecute wordt vanaf het form aangeroepen. Het frame doet op dat moment niets.

[ Voor 9% gewijzigd door _Thanatos_ op 27-03-2004 17:14 ]

日本!🎌


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Klinkt idd niet of het dat probleem is. Toch: Heb je m wel gestuurd met PostMessage en niet met SendMessage? Ik zie ook niet helemaal waarom je RemoveControl en Parent := nil nodig zou hebben, want dat gebeurt allemaal in de Destroy als het goed is. Kan je die niet gewoon weghalen en kijken of het vrijgeven dan wel goed gaat?

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


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik had het idd met PostMessage gedaan, anders heeft het geen effect. Als ik RemoveComponent en Preview.Parent := nil; weghaal, blijf ik dezelfde AV houden...

Hmm, ik heb dus een RichEdit op die frame staan, en ik kom er dus net achter dat als ik die eraf haal, dat ik de AV dan niet meer krijg... How can :?

[ Voor 33% gewijzigd door _Thanatos_ op 27-03-2004 17:55 ]

日本!🎌


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Opgelost. Ik had een control die GetClientRect override om z'n ClientRect te bepalen, om z'n children te alignen. In de help staat dat je GetClientRect hiervoor moet gebruiken, maar als ik AdjustClientRect override ipv GetClientRect, dan heb ik die AV niet meer...

:? :? :?

日本!🎌

Pagina: 1