![]() |
Android procedure auf ShowModal warten
Hi Leute,
ich habe eine Frage zu ShowModal auf Android. Wie verwende ich es wenn ich auf eine Benutzereingabe warten möchte? Wenn ich ein Dialog in einer Procedure aufrufe, wird nicht darauf gewartet bis das Modale Fenster wieder geschlossen wurde. Ich habe mal eine Beispiel Procedure geschrieben. In der function GetRot() sollte solange gewartet werden, bis sich das Modale Fenster wieder schließt und einen Rückgabewert hat, da sonst immer ein leerer String übergeben wird. Wie löst man das am Besten?
Delphi-Quellcode:
procedure TfrmMain.CreateFarbe();
var Rot, Gruen, Blau: String; begin // Buttonindex holen Index := (Sender as TButton).Tag; Rot := ''; Gruen := ''; Blau := ''; l := Length('RGB'); for i := 1 to l do begin ch := Copy('RGB', i,i); if ch = 'R' then begin Rot := GetRot; if Rot = '' then Exit; end else if ch = 'G' then begin Gruen := GetGruen; if Gruen = '' then Exit; end else if ch = 'B' then begin Blau := GetBlau; if Blau = '' then Exit; end; end; FarbeZusammenstellen(Rot, Gruen, Blau) end; function TfrmMain.GetRot: String; var dlgRot: TfrmFarbauswahl; sRot: String; begin dlgRot := TfrmFarbauswahl.Create(nil); dlgRot.ShowModal( procedure(ModalResult: TModalResult) begin if ModalResult = mrOk then begin sRot := dlgRot.lbRot.Items[dlgRot.lbRot.ItemIndex]; end; if ModalResult = mrCancel then begin sRot := ''; end; dlgRot.Close; end ); Result := sRot; end; |
AW: Android procedure auf ShowModal warten
Unter Android ist ein ShowModal ein "Don't do"...
Mavarik |
AW: Android procedure auf ShowModal warten
Zitat:
|
AW: Android procedure auf ShowModal warten
Ja das habe ich mir schon gedacht.. Gibt es andere Möglichkeiten in einer procedure auf eine Benutzereingabe aus einem anderen Formular zu warten?
|
AW: Android procedure auf ShowModal warten
Zitat:
|
AW: Android procedure auf ShowModal warten
Zitat:
Zitat:
|
AW: Android procedure auf ShowModal warten
Ich persönlich halte nichts von den Callbacks nur für Unterformulare oder Messageboxen, ist mir einfach zu aufwendig.
Du kannst eine globale Variable definieren die von der Unterform gefüllt wird. Das Hauptformular muss nun einfach nur solange warten, bis die Variable gefüllt ist. Beispiel:
Code:
var MsgDlgResult: Integer;
function MessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer; begin MsgDlgResult := -1; FMX.Dialogs.MessageDlg(Msg, DlgType, Buttons, HelpCtx, procedure(const AResult: TModalResult) begin MsgDlgResult:= AResult; end ); while MsgDlgResult<0 do Delay(10); Result := MsgDlgResult; end; |
AW: Android procedure auf ShowModal warten
Zitat:
Richtig ist, dass die Methode/Prozedur, die dieses ShowModal aufruft, erst dann weiter läuft, wenn diese modale Form geschlossen wurde. Die Anwendung selber läuft einwandfrei weiter. @greenmile Bitte nicht ... es gibt einen guten Grund, warum die modalen Formulare auf den Mobile Devices eben nicht mehr blockierend sind. |
AW: Android procedure auf ShowModal warten
Zitat:
Delphi-Quellcode:
:stupid:
while MsgDlgResult<0 do Delay(10); // Töte den Akku
Spass bei Seite... Bitte nicht.. Es gibt bessere Wege Das war mal ein Post... Als XE6 raus gekommen ist, oder? Ich hatte das auch so "abgetippt" [EDIT] Habs gefunden... Original Post war:
Delphi-Quellcode:
function MyMessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer;
{$IFDEF ANDROID} var MsgDlgResult : Integer; {$ENDIF} begin {$IFDEF ANDROID} MsgDlgResult := -1; FMX.Dialogs.MessageDlg(Msg, DlgType, Buttons, HelpCtx, procedure(const AResult: TModalResult) begin MsgDlgResult:= AResult; end); while MsgDlgResult<0 do begin Application.Processmessages; // Makes Android Happy... Sleep(10); end; Result := MsgDlgResult; {$ELSE} Result := FMX.Dialogs.MessageDlg(Msg, DlgType, Buttons, HelpCtx); {$ENDIF} end; |
AW: Android procedure auf ShowModal warten
Application.Processmessages ist eine ganz schlechte Idee unter Android/iOS...
|
AW: Android procedure auf ShowModal warten
Zitat:
Dieses
Delphi-Quellcode:
beim
Application.ProcessMessages
Delphi-Quellcode:
ist extra für die Mobile Plattformen herausgenommen worden. Da hat sich doch bestimmt keiner etwas bei gedacht. Das ist nur um alle zu ärgern. :mrgreen:
ShowModal
|
AW: Android procedure auf ShowModal warten
Ich habe gerade das Gefühl in dieser Situation gibt es kein "Richtig", kann das sein? :)
@SirRufo: Würde mich über ein bisschen Quellcode bezogen auf mein Beispiel freuen, so ganz komme ich mit den Callbacks nicht klar :? @Mavarik: Wenn ich es so versuche hängt sich die komplette App auf.. |
AW: Android procedure auf ShowModal warten
Zitat:
In unserer App haben die Application.ProcessMessages jedenfalls zu massiven Problemen geführt (besonders im Zusammenhang mit Threads). Inzwischen haben wir alle bis auf eine Stelle eliminieren können und seitdem damit keine Probleme mehr. Ist ja nicht so, dass es sonst nicht schon genug Stolpersteine gäbe ^^ |
AW: Android procedure auf ShowModal warten
Um zur Ausgangsfrage zurückzukehren:
Man macht das so, dass man auf die Events des zweiten Formulars reagiert und gar nicht wartet. Sprich der Ablauf ist so:
|
AW: Android procedure auf ShowModal warten
Da macht es ja vielleicht Sinn. Aber was ist mit einer Messagebox wie "Möchten Sie beenden"? Extra Callback für jede erdenkliche Messagebox, Inputquery und co ist doch wirklich Overkill, oder?
|
AW: Android procedure auf ShowModal warten
Dafür aber sauber...
Und wenn man von Anfang an so denkt, ist das auch überhaupt kein Problem... Problematisch ist nur die Umstellung von altem Code. |
AW: Android procedure auf ShowModal warten
Zitat:
|
AW: Android procedure auf ShowModal warten
Wir haben uns eine eigene Unit für Standard-MessageBoxes erstellt, läuft mit Windows, iOS und Android:
Code:
unit uMessageDialogs;
interface uses System.UITypes, System.SysUtils, System.Types, System.Generics.Defaults, FMX.Dialogs; type TDialogButtons = (dbOk, dbOkCancel, dbYesNo); TMessageDialogs = class private class procedure PlatformDialog(const AMessage: String; const ADialogType: TMsgDlgType; const ADialogButtons: TDialogButtons; const AProcedure: TInputCloseDialogProc); public class procedure Info(const AMessage: String); class procedure Warn(const AMessage: String); class procedure Error(const AMessage: String); class procedure ConfirmYesNo(const AMessage: String; const ADialogType: TMsgDlgType; const AProcedureOnYes: TProc; const AProcedureOnNo: TProc = nil); class procedure ConfirmOkCancel(const AMessage: String; const ADialogType: TMsgDlgType; const AProcedureOnOk: TProc; const AProcedureOnCancel: TProc = nil); class procedure Custom(const AMessage: String; const ADialogType: TMsgDlgType; const ADialogButtons: TDialogButtons; const AProcedure: TInputCloseDialogProc); end; implementation uses {$IFDEF MSWINDOWS} Windows, FMX.Platform.Win, {$ENDIF} fRISApp, uFormSupport, uSupport, uConsts; class procedure TMessageDialogs.PlatformDialog(const AMessage: String; const ADialogType: TMsgDlgType; const ADialogButtons: TDialogButtons; const AProcedure: TInputCloseDialogProc); {$IFDEF MSWINDOWS} var uType: Cardinal; caption: String; res: Integer; begin // Dialoge werden sonst unter Windows nicht Modal angezeigt, lassen sich also in den Hintergrund legen uType := MB_OK; case ADialogButtons of dbOk: uType := MB_OK; dbOkCancel: uType := MB_OKCANCEL; dbYesNo: uType := MB_YESNO; end; uType := uType or MB_TASKMODAL; case ADialogType of TMsgDlgType.mtWarning: begin caption := 'Warnung'; uType := uType or MB_ICONWARNING; end; TMsgDlgType.mtError: begin caption := 'Fehler'; uType := uType or MB_ICONERROR; end; TMsgDlgType.mtInformation: begin caption := 'Information'; uType := uType or MB_ICONINFORMATION; end; TMsgDlgType.mtConfirmation: begin caption := 'Bestätigung'; uType := uType or MB_ICONQUESTION; end; else Assert(True); end; if GetMainForm = nil then res := Windows.MessageBox(0, PWideChar(AMessage), PWideChar(caption), uType) else res := Windows.MessageBox(FMX.Platform.Win.WindowHandleToPlatform(GetMainForm.Handle).Wnd, PWideChar(AMessage), PWideChar(caption), uType); if Assigned(AProcedure) then AProcedure(res); end; {$ELSE} var dlgButtons: TMsgDlgButtons; begin case ADialogButtons of dbOk: dlgButtons := [TMsgDlgBtn.mbOK]; dbOkCancel: dlgButtons := [TMsgDlgBtn.mbOK, TMsgDlgBtn.mbCancel]; dbYesNo: dlgButtons := [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo]; end; FMX.Dialogs.MessageDlg(AMessage, ADialogType, dlgButtons, 0, AProcedure); end; {$ENDIF} class procedure TMessageDialogs.Info(const AMessage: String); begin PlatformDialog(AMessage, TMsgDlgType.mtInformation, dbOk, nil); end; class procedure TMessageDialogs.Warn(const AMessage: String); begin PlatformDialog(AMessage, TMsgDlgType.mtWarning, dbOk, nil); end; class procedure TMessageDialogs.Error(const AMessage: String); begin PlatformDialog(AMessage, TMsgDlgType.mtError, dbOk, nil); end; class procedure TMessageDialogs.Custom(const AMessage: String; const ADialogType: TMsgDlgType; const ADialogButtons: TDialogButtons; const AProcedure: TInputCloseDialogProc); begin PlatformDialog(AMessage, ADialogType, ADialogButtons, AProcedure); end; class procedure TMessageDialogs.ConfirmOkCancel(const AMessage: String; const ADialogType: TMsgDlgType; const AProcedureOnOk, AProcedureOnCancel: TProc); begin PlatformDialog(AMessage, ADialogType, dbOkCancel, procedure(const AResult: TModalResult) begin if GetMainForm <> nil then GetMainForm.Status(Format('Dialog-Result: %d, Dialog: %s', [AResult, AMessage]), TStatusType.stDebug); if AResult = mrOK then begin if Assigned(AProcedureOnOK) then AProcedureOnOK; end // Alternativ-Prozedur wird immer ausgeführt, wenn vorhanden. // Damit wird ein Problem unter Android behoben, wo sich Dialoge durch Klicken außerhalb abbrechen lassen else if Assigned(AProcedureOnCancel) then AProcedureOnCancel; end ); end; class procedure TMessageDialogs.ConfirmYesNo(const AMessage: String; const ADialogType: TMsgDlgType; const AProcedureOnYes: TProc; const AProcedureOnNo: TProc); begin PlatformDialog(AMessage, ADialogType, dbYesNo, procedure(const AResult: TModalResult) begin if GetMainForm <> nil then GetMainForm.Status(Format('Dialog-Result: %d, Dialog: %s', [AResult, AMessage]), TStatusType.stDebug); if AResult = mrYes then begin if Assigned(AProcedureOnYes) then AProcedureOnYes; end // Alternativ-Prozedur wird immer ausgeführt, wenn vorhanden // Damit wird ein Problem unter Android behoben, wo sich Dialoge durch Klicken außerhalb abbrechen lassen else if Assigned(AProcedureOnNo) then AProcedureOnNo; end ); end; end. |
AW: Android procedure auf ShowModal warten
Zitat:
|
AW: Android procedure auf ShowModal warten
Keine gute, weil das unter Android nicht so gemacht werden soll.
Und warum sollte auch eine Prozedur fortgesetzt werden? Du brauchst den Code nach dem Aufruf des Fensters doch nur in das Event zu schreiben, dass das zweite Fenster bestätigt oder abgebrochen wurde. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:34 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