![]() |
Formular korrekt Freigeben
Hallo.
Ich gebe ein Firemonkey Formular frei, ausgelöst durch eine Benutzer aktion auf dem selbigen. Irgendwo innerhalb von TListview.OnChange kommt dieser Code.
Delphi-Quellcode:
Meist funktioniert das.
Form.Close;
Form.Release; Application.processmessages; Form := nil; Seltsamer weise nicht immer. Ich kann eine Zugriffverletzung provozieren, wenn ich im TListview.DoChange einen Breakpoint hinterlege. Die Zugriffsverletzung passiert dann in der Mousdown Behandlung.
Delphi-Quellcode:
Eigentlich sollte es vermutlich immer schiefgehen. Seltsamer weise ist das nicht der Fall.
procedure TCommonCustomForm.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var P: TPointF; Obj: IControl; SG: ISizeGrip; NewCursor: TCursor; begin Engage; try { translate coord } FMousePos := PointF(X, Y); FDownPos := FMousePos; NewCursor := Cursor; // use the form cursor only if no control has been clicked Obj := ObjectAtPoint(ClientToScreen(FMousePos)); if Obj <> nil then if (IInterface(Obj).QueryInterface(ISizeGrip, SG) = 0) then StartWindowResize else begin P := Obj.ScreenToLocal(ClientToScreen(FMousePos)); if (Obj.DragMode = TDragMode.dmAutomatic) and (Button = TMouseButton.mbLeft) then Obj.BeginAutoDrag else Obj.MouseDown(Button, Shift, P.X, P.Y); NewCursor := Obj.Cursor; //<<< hier passiert die Zugriffsverletzung end else DoMouseDown(Button, Shift, X, Y); if FCursorService <> nil then FCursorService.SetCursor(NewCursor); finally Disengage; end; end; TListview verwendet einen DelayedIncidentTimer vielleicht liegt es daran, dass es in 99% der Fälle klappt. Muss ich das Formular über einen eigenen DelayTimer freigeben oder gibts eine vorgefertigte Methode die das leistet? |
AW: Formular korrekt Freigeben
"Release" und "Nil" sollte doch eigentlich reichen?
Warum schickst du dir nicht 'ne Message an das Hauptfenster und wenn das Hauptfenster diese empfängt, dann wird freigegeben? |
AW: Formular korrekt Freigeben
Auch mit Release und nil ohne close
kommt es (wenn ich es mit breakpoint provoziere) zu besagter zugriffsverletzung. Ich habe das bisher so gemacht wie es ist, weil der Fehler in Android scheinbar nicht auftritt und in Windows nur sehr sehr selten. Bin halt gerade eben erst auf die Ursache gestoßen. Das Release findet im Navigations Befehl statt. Ich könnte das also per PosMessage auslösen. PostMessage mag ich nur nicht so gerne, weil man nie weiß wo ein Processmessages einem die Reihenfolge der Queue wieder durcheinander bringt. Macht ihr das auch so? Es müsste ein Timer sein in dem
Delphi-Quellcode:
abgefragt wird.
TFmxFormState.Engaged in self.Formstate
Ist das korrekt? |
AW: Formular korrekt Freigeben
Aus dem Event heraus das Fenster freizugeben sieht für mich nicht gut aus...
Wenn du Postmessage nicht magst dann versuch doch irgendwo Sendmessage einzubauen oder gibt es in FMX QueueAsyncCall bzw. etwas ähnliches? "IAsyncCall" ??? oder so... Da muß es doch noch was geben was man nehmen kann... |
AW: Formular korrekt Freigeben
Delphi-Quellcode:
Wenn die Form freigegeben wird, wird die Variable automatisch auf NIL gesetzt.
var
[WEAK] Form: TForm; Form.Free; // oder Form.Close, wenn FireMonkes auch sowas wie caFree hat Aber nur, in NextGen-Compilern. :? |
AW: Formular korrekt Freigeben
@FarAndBeyond:
Ja die Lazarus Leute haben da genau das was ich jetzt bräuchte. Ich weiß auch nicht ob WindowsMessages so eine tolle Sache sind wenn die App in Android läuft. @himitsu: Ich habe probleme damit dass nach dem DoChange ereignis von TListview noch
Delphi-Quellcode:
passiert.
newcursor := Obj.cursor
Es findet noch Verarbeitung des "Mouseereignesses" statt. Ich bräuchte ein Ereignis das feuert wenn der Formstate kein "Engaged" mehr enthält. So das dann dort die Navigation und die implizite Freigabe des Formulars stattfinden kann. Oder ich bräuchte ne möglichkeit die Navigation delayed zu feuern. Ich kann mir das bauen mit nem Timer...es wäre halt nur schöner wenn es was fertiges gäbe. |
AW: Formular korrekt Freigeben
Gutes Argument... :-)
Stimmt, da hängt Android echt hinterher... sie kriegen es einfach nicht hin die WINApi zu integrieren... |
AW: Formular korrekt Freigeben
Hab den Fehler....
ohne Processmessages nach Release funktioniert alles wie es soll. Release zerstört es verzögert, via Messagequeue. |
AW: Formular korrekt Freigeben
Zitat:
Delphi-Quellcode:
Aber zumindestens im Windows ist das so blöd implementiert, dass es eben nicht verzögert ausgeführt wird, wenn man das im VCL-MainThread ausführt.
TThread.Queue(procedure
begin // machwas, aber nicht gleich end); ![]() |
AW: Formular korrekt Freigeben
Zitat:
Und ich wollte gerade fragen wo du dann den Timer wieder freigibst, den sollte man ja auch nicht aus seinem eigenen Event freigeben... |
AW: Formular korrekt Freigeben
Man kann Objekte in den eigenen Events freigeben, allerdings nur dann, wenn in den aufrufenden Funktionen nicht nochmal auf das Objekt zugegriffen wird und man das nicht irgendwie unterbinden kann.
Also nach dem END deiner Event-Methode darf nicht nochmal auf das Objekt zugegriffen werden, dann kann man sowas machen. Close bei der Form kann man überall aufrufen, da es die Form nicht sofort frei gibt, sondern der Form eine Message sendet, in der die Form freigegeben wird. PS: Da gibt die Form sich dann auch in einer eigenen Methode selber frei. :zwinker: Zitat:
Delphi-Quellcode:
Neben der Message für CM_RELEASE können/werden hier auch noch viele andere Messages ausgeführt.
Form.Caption := 'blubb';
Form.Close; Application.ProcessMessages; // oder ShowMessage('Hallo'); ShowMessage(Form.Caption); // peng... Es braucht also nichtmal Form.Close, wenn du z.B. vorher auf das [X] der Form klickst, aber das Ereignis/die Message erst jetzt verarbeitet würde.
Delphi-Quellcode:
Knopf drücken und nach über 15 Sekunden nochmal drücken
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer; begin Button1.Tag := 1; // eine globale Variable for i := 1 to 15 do begin Sleep(1000); Application.ProcessMessages; Memo1.Lines.Add(Format('%d %d', [i, Button1.Tag])); Button1.Tag := Button1.Tag + 1; end; end; und dann auch einmal Knopf drücken und innerhalb der 15 Sekunden nochmal drücken. |
AW: Formular korrekt Freigeben
@himitsu
Danke für die Info... Ich hab' auch schon aus 'nem Event Objekte freigegeben... hab' dafür aber auch schon Prügel bezogen in 'nem anderen Forum. Auch wenn das in dem Fall gefunzt hat. Zitat:
Ja, manchmal sieht man das Fenster nicht, weil es zu sehr in der Mitte des Monitors direkt vor der Nase angezeigt wird... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:45 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