![]() |
Frames auf PageControl oder Form ! Ich werd verrückt
Hi Leute,
ich habe eine Frame-Klasse, die ich je nach Einstellungen dynamisch auf eine Form oder auf eien Tab-Sheet eines PageControls setze. Das ganze funktioniert eigentlich auch wunderbar, aber : Zu Verwaltung der einzelnen Frames, habe ich diese in einem TList Objekt gespeichert mit diversen Zusatz-Information, so sieht meine KLasse aus die ich in der TLIst speichere :
Code:
An dieser Klasse ist ja nicht besonders dran, ich brauche sie nur zur Verwaltung der einzelnen Frames !
TChatWindowData = class
private // Optische Darstellungselemente fFreeInProgress : Boolean; // SChalter, ob dieses Element sich gerade schon in der Freigabe befindet fFrame : TfraChatWindow; // Der Frame selber fForm : TfrmChatWindow; // Falls der Frame auf einer Form sitzt, dann ist es diese fTabSheet : TTabsheetes; // Falls der Frame auf einem Tab sitzt, dann dieser fMultiChat : TfrmMultiChat; // Form auf dem sich die Tabshetts befinden // Daten von Chat-Partner fID : Longint; protected {} public Constructor Create; Destructor Destroy; override; property FreeInProgress : Boolean read fFreeInProgress write fFreeInProgress; property Frame : TfraChatWindow read fFrame write fFrame; property Form : TfrmChatWindow read fForm write fForm; property Tab : TTabSheetes read fTabSheet write fTabSheet; property MultiChat : TfrmMultiChat read fMultiCHat write fMultiCHat; property ID : Longint read fID write fID; function FrameIsOnTab : Boolean; function FrameIsinForm : Boolean; end; constructor TChatWindowData.Create; begin inherited; fFreeInProgress := false; fFrame := Nil; fForm := Nil; fTabSheet := Nil; fMultiChat:= Nil; fID := 0; //fLastMsg := 0; end; destructor TChatWindowData.Destroy; begin fForm := nil; fTabSheet := nil; fFrame := nil; fMultiChat := nil; inherited; end; Jetzt habe ich das Problem, das meine TChatWindowData-Objekte in meiner T-List ja auch wieder sauber entfernt werden müssen. Jetzt ist aber die Frage wann und wo meine Einträge aus der Liste entfernen ? Den Destructor meines Frames habe ich überschrieben, und versuche dann im Destroy des Frames in meinem T-List Objekt den entsprechenden Frame zu finden und den Eintrag zu entfernen. Da aber das schliessen bzw. die Freigabe der Form von verschiedenen Stellen aufgerufen werden kann, beißt die Katze sich immer wieder selber in den Schwanz, damit meine ich : Sitzt der Frame auf einer Form können folgende Varianten auftreten : 1. Main-Form wird geschlossen, d.h. in Close der Main-Form rufe ich Clear meiner Liste auf, dieses geht hin und gibt alle geöffneten Form und Ihre Frames frei, dabei wird dann aber auch wieder der Destructor des Frames aufgerufen. Der widerum auch versucht die Forms freizugeben und seinen Frame-Eintrag aus der Liste zu entfernen. 2. Eine bestimmte Form wird geschlossen, im OnClose setzte ich die OnCloseACtion auf caFree, so das der FRame auch wieder mit freigegeben wird, und dann destructor von frame .... 3. Das Close kommt aus dem Frame(Button) selber, jetzt kann ich nicht einfach meinen Frame-Eintrag mit aus der Liste entfernen, sondern muss die Form auf der der Frame sitzt ja auch mit schliessen/Freigeben, wodurch sich wieder alles überschneidet. Ich weiß nicht, on aus meiner ERklärung mein Problem ersichtlich wird, aber das ganze ist wie ein Teufelskreis, behabe ich einen Fehler, tritt dieser Fehler wird an anderer Stelle auf und so bekomme ich immer Zugriffsverletzungen oder "Abstrakte Fehler". Jetzt bitte nicht sagen, "debug das ganze doch mal", denn das tue ich schon seit einem Tag :wall: Der Fehler ist mit Debuggen leider nicht zu finden, ich habe z.B. meine Procedure meines Close Buttons auf meinem Frame, es werden alle Anweisungen und DEstructoren sauber aufgerufen, gehe ich dann mit F8 ans Ende der Procedure gibt halt die oben genannten Fehlermeldungen. Benutze ich F7 dann lade ich sporadisch in diversen überschriebenen WncProc von diversen Komponenten. Bei plazieren der Frames auf Forms habe ich mittlerweile ne total buggy Lösung gefunden, aber nur durch Try and Error, aber bei den Tabsheets komme ich echt nicht weiter. |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Ich würde das Problem versuchen einzugrenzen. Ersetze doch Free durch FreeAndNil. Dann kannst Du mit Assigned die Existenz Deiner Objekte prüfen und Zugriffsverletzungen bleiben aus. Dann wäre es auch möglich, an mehreren Stellen die Freigabe vorzunehmen.
Delphi-Quellcode:
if Assigned(MyObj) then FreeAndNil(MyObj);
|
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Hi,
leider hilft mir das nicht weiter, ich verwende meistens sowieso FreeAndNil !!! Ich hab jetzt auch schonmal testweise, meine PageControl(modifizierte KOmponente) gegen ein STandard-Page-Control ausgetauscht, aber der gleiche Effekt. ich habe ne Procedure oder einen Event(z.B. Button Click), innerhalb dieser Procedure rufe ich folgende auf :
Code:
Wenn ich am Ende der Procedure angekommen bin, und dann F7 drücke springt er zu dem letzten End meine Action.OnExecute und bei erneutem F7 gibt es meine Schutzverletzung, aber leider keinen Hinweis wo :(
procedure TfraChatWindow.FreeFromTab;
Var Data : TChatWindowData; Idx : Longint; RemoveTab : TTabSheet; begin idx := ChatWindows.IndexOfFrame(self); if idx > -1 then begin Data := ChatWindows.Items[Idx]; if Data <> Nil then begin Data.FreeInProgress := true; ChatWindows[idx] := Nil; Data.Frame.free; (* if (Data.Tab.PageIndex < (Data.Tab.PageControl.PageCount -1)) then Data.Tab.PageControl.ActivePageIndex := Data.Tab.PageIndex + 1 else Data.Tab.PageControl.ActivePageIndex := Data.Tab.PageIndex -1; *) DAta.Tab.TabVisible := false; // egal, ob diese ZEile aktiviert ist oder nicht RemoveTab := Data.Tab; FreeAndNil(RemoveTab); FreeAndNil(Data); //ChatWindows.Pack; end; end; end; Im CPU Fenster stellen nur lauter ???? Es handelt sich bei der Exception um eine EAcessViolation, aber mit ner gültigen Zeiger-Adresse nicht 00000000000000000. |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Hi,
vielleicht solltest du mal versuchen mit Debug-DCUs zu kompilieren (Projekt -> Optionen -> Compiler). Dann kannst du auch mit F7 / F8 in die Borland Quelltexte reinkommen. Vielleicht hilft dir das ja. mfG mirage228 |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Hi Mirage,
habe ich gerade gemacht, dann hangelt er sich von der Action hoch bis zum TControl.WMLButtonUp
Code:
In dem DoMouseUp, sprint er dann von der ZEile with Message do MouseUp(Button, KeysToShiftState(Keys), XPos, YPos); in die System.pas
procedure TControl.DoMouseUp(var Message: TWMMouse; Button: TMouseButton);
begin if not (csNoStdEvents in ControlStyle) then with Message do MouseUp(Button, KeysToShiftState(Keys), XPos, YPos); end; procedure TControl.WMLButtonUp(var Message: TWMLButtonUp); begin inherited; if csCaptureMouse in ControlStyle then MouseCapture := False; if csClicked in ControlState then begin Exclude(FControlState, csClicked); if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click; end; DoMouseUp(Message, mbLeft); end;
Code:
MOVZX ECX,word ptr [EDI] ist die Zeile wo er crashed :shock:
procedure GetDynaMethod;
{ function GetDynaMethod(vmt: TClass; selector: Smallint) : Pointer; } asm { -> EAX vmt of class } { SI dynamic method index } { <- ESI pointer to routine } { ZF = 0 if found } { trashes: EAX, ECX } PUSH EDI XCHG EAX,ESI JMP @@haveVMT @@outerLoop: MOV ESI,[ESI] @@haveVMT: MOV EDI,[ESI].vmtDynamicTable TEST EDI,EDI JE @@parent MOVZX ECX,word ptr [EDI] PUSH ECX ADD EDI,2 REPNE SCASW JE @@found POP ECX @@parent: MOV ESI,[ESI].vmtParent TEST ESI,ESI JNE @@outerLoop JMP @@exit @@found: POP EAX ADD EAX,EAX SUB EAX,ECX { this will always clear the Z-flag ! } MOV ESI,[EDI+EAX*2-4] @@exit: POP EDI end; |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Im Create wird fFrame nicht erzeugt, genausowenig im Destroy freigegeben!
Zitat:
Delphi-Quellcode:
... absichtlich eine ungültige Adresse.
fFrame := Nil;
Eine AV @00000000000000000 gibt's IMHO nur bei Zeigern, die auf nichts zeigen (also 00000000000000000 ;) ). |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Zitat:
Parent-Control oder sein Parent-Frame zerstören. (Weil die VCL noch nicht ganz fertig mit dem Control ist) Schau dir mal meinen Artikel ![]() |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
hi Robert,
der Frame wird an einer anderen Stelle erzeugt, weil er ja wahlweise auf einen Tabsheet oder einer Form plaziert wird. Genauso wird er an einer anderen Stelle freigegeben. Die Klasse wo der Frame auf Nil gesetzt wird, wird nur als Zugriffs-Container gebraucht. |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Hi Shmia,
und wie schliesse ich jetzt aus einer ACtion des Frames jetzt das übergeordnete Control(Form oder Tabsheet) ? Ich denke auch das da irgentwo der Hund begraben liegt, den bei der Form hatte ich ein ähnliches Problem, was ich dadurch gelöst habe, das ich das OnClick EReignis des Close-Buttons der Form aufgerufen habe :zwinker: Aber wie mache ich das jetzt bei Tab ? Erschwerend kommt hinzu, das wenn nur noch ein Tab aktiv ist, natürlich auch die Form auf der die Tabs liegen geschlossen werden soll. |
Re: Frames auf PageControl oder Form ! Ich werd verrückt
Zitat:
Einscheidend ist, ob ein Control auf dem Frame (z.B. ein Button oder ein Popup-Menu) der Ausgangspunkt für das Zerstören des Frames ist. Wenn der Lösch-Button (oder was auch immer) beim Klicken selbst zerstört wird, dann -> Zugriffsverletzung. PS: Hast du das Beispiel zu meinem Artikel angeschaut ? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:37 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