Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Android: MessageDlg Logik (https://www.delphipraxis.net/183643-android-messagedlg-logik.html)

amigage 25. Jan 2015 14:47

Android: MessageDlg Logik
 
Hallo,

ich finde die Android Logik nicht ganz sinnvoll, keine blockierenden Meldungen zuzulassen:

Beispiel: Nachfrage, ob eine bestehende Datei überschrieben werden soll.

Windows:
Delphi-Quellcode:
if FileExists() then
begin
   Case MsgDlg('soll die Datei überschrieben werden') of
     mrNo: exit;
    end;
end;

// ab hier wird die Datei überschrieben
Android:
Delphi-Quellcode:
if FileExists() then
begin
  MsgDlg('soll die Datei überschrieben werden')
     procedure(const AResult: TModalResult)
     begin
       Case AResult of
          mrNo: exit;
          mrYes: begin
                 // ab hier wird die Datei überschrieben
                 exit;
                 end;
       end;
    end);
  exit;
end;

// ab hier wird die Datei überschrieben

Mich stört hierbei, dass ich die nach der Frage abzuarbeitenden Befehle in eine Funktion auslagern muss, da die Befehle entweder bei einer nicht vorhandenen Datei und bei einem "Ja, du darfst überschreiben" ausgeführt werden sollen.

Wie handhabt ihr diese Logik?

Amigage

himitsu 25. Jan 2015 15:06

AW: Android: MessageDlg Logik
 
Das Problem ist halt, daß es dort eigentlich nicht sowas wie "modale" Dialoge gibt, wie man sie aus den nicht-mobilen Plattformen kennt und Emba nicht in der Lage war etwas funktionell "gleichwertiges" hinzubekommen.
Eigentlich macht man ein neues Fenster auf und reagiert dort dann auf den Button-Klick ... und diese Syntax ist praktisch die gekapselte "Kurzfassung" davon, aber statt der anonymen Methode darfst du auch gern eine richtige Methode oder ein eigenes Fenster benutzen.

Sir Rufo 25. Jan 2015 15:34

AW: Android: MessageDlg Logik
 
Selbst bei der VCL gibt es eigentlich keine modalen Dialoge. Das was da als modal verkauft wird, ist eine Schleife, die ständig
Delphi-Quellcode:
Application.ProcessMessages
aufruft. Vorher wurden alle anderen Formulare abgeschaltet und werden nachher wieder eingeschaltet, bzw. auf den gespeicherten Zustand zurückgesetzt.

Dieses modal soll ja eigentlich nur weitere Eingaben in den anderen Formularen verhindern und nur in diesem einzigen zulassen. Darum wird bei den Mobil-Plattformen quasi ein Vorhang (Rectangle, Opacity 50%, HitTest True) davorgelegt und dann kommt der Dialog. Am Ende wird der wieder entfernt.

Allerdings würde mich so eine Exit-Orgie in deinem Code auch stören:
Delphi-Quellcode:
if FileExists() then
begin
  MsgDlg('soll die Datei überschrieben werden',
     procedure(const AResult: TModalResult)
     begin
       if AResult = mrYes then
          begin
                 // ab hier wird die Datei überschrieben
          end;
     end);
end;

himitsu 25. Jan 2015 15:47

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Sir Rufo (Beitrag 1287696)
Selbst bei der VCL gibt es eigentlich keine modalen Dialoge. ...

OK, ob das vom Windows so gemacht wird (z.B. MessageBox) oder manuell von der VCL ... sowas Ähnliches hätte man doch bestimmt auch hier hinbekommen.
(z.B. Android ist auch auch "nur" ein Linux)

Und die zusätzliche Schleife ist nichts Besonderes, denn das ist der Normalfall ... siehe Application.Run

amigage 26. Jan 2015 12:22

AW: Android: MessageDlg Logik
 
Zitat:

Allerdings würde mich so eine Exit-Orgie in deinem Code auch stören:
Das stimmt, da ja bei der Frage nur die anonyme Methode durchlaufen wird, kann man sich die zusätzlichen exit sparen.

eddie11 26. Jan 2015 13:24

AW: Android: MessageDlg Logik
 
Wie wärs denn damit?

Delphi-Quellcode:
procedure TForm1.Button16Click(Sender: TObject);
begin
  if not Confirm('Willst Du?') then
    Exit
  // Weiter gehts erst nach Click
end;

function TForm1.Confirm(const AText:String):Boolean;
var
  geklickt: Boolean;
  Ergebnis: Boolean;
begin
  Ergebnis := false;
  geklickt := false;
  MsgDialog(AText,TMsgDlgType.mtConfirmation,[TMsgDlgBtn.mbYes,TMsgDlgBtn.mbNo],TMsgDlgBtn.mbYes,
     procedure(const AResult: TModalResult)
     begin
       Ergebnis := (AResult=mrYes);
       geklickt := true;
     end);
  repeat
    Application.ProcessMessages();
  until geklickt;
  Result := Ergebnis;

end;
Gruß
Eddie

Hwfa 13. Feb 2015 06:59

AW: Android: MessageDlg Logik
 
Dieses modal soll ja eigentlich nur weitere Eingaben in den anderen Formularen verhindern und nur in diesem einzigen zulassen. Darum wird bei den Mobil-Plattformen quasi ein Vorhang (Rectangle, Opacity 50%, HitTest True) davorgelegt und dann kommt der Dialog. Am Ende wird der wieder entfernt.

eddie11 13. Feb 2015 07:40

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Hwfa (Beitrag 1289707)
Dieses modal soll ja eigentlich nur weitere Eingaben in den anderen Formularen verhindern und nur in diesem einzigen zulassen. Darum wird bei den Mobil-Plattformen quasi ein Vorhang (Rectangle, Opacity 50%, HitTest True) davorgelegt und dann kommt der Dialog. Am Ende wird der wieder entfernt.

Das stimmt, weitere Eingaben werden geblockt - aber die Programmausführung wartet nicht. Wenn nach dem Dialog noch weiterer Code folgt, dann wird dieser ausgeführt ohne auf die Antwort des Dialogs zu warten - jedenfalls ist das bei Android so.

Sir Rufo 13. Feb 2015 07:57

AW: Android: MessageDlg Logik
 
Dann programmiere deine Anwendung doch einfach besser lesbar
Delphi-Quellcode:
procedure ConfirmAction( const AText : string; const AProc : TProc );
begin
  MsgDialog(AText,TMsgDlgType.mtConfirmation,[TMsgDlgBtn.mbYes,TMsgDlgBtn.mbNo],TMsgDlgBtn.mbYes,
     procedure(const AResult: TModalResult)
     begin
       if (AResult=mrYes) then
         AProc();
     end);
end;

procedure TForm1.Button6Click( Sender : TObject );
begin
  ConfirmAction( 'Willst du Drucken?', PrintFoo );
end;

procedure TForm1.PrintFoo;
begin
  // Hier der Code zum drucken
end;
Wow, schon wird aus einem ominösen und unleserlichem
Delphi-Quellcode:
Button6Click
eine dokumentierte Methode. Auf einem Blick sieht man nun, dass hier nach Rückfrage ein Druck ausgelöst wird.

Ja, dass mit diesem komischen Dialog-Gedöns ist richtig ekelig: Man muss sich ja richtig Gedanken machen :roll:

eddie11 13. Feb 2015 08:18

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289716)
Dann programmiere deine Anwendung doch einfach besser lesbar

Wow, schon wird aus einem ominösen und unleserlichem
Delphi-Quellcode:
Button6Click
eine dokumentierte Methode. Auf einem Blick sieht man nun, dass hier nach Rückfrage ein Druck ausgelöst wird.
:

Wow, wer abstrahieren kann ist besser dran!

Üblichweise heißt ein Button bei mir nicht Button16 (manchmal auch Button17 oder ..18 :-D:-D,), das macht die IDE halt so, wenn man mal schell was ausprobieren will....
Und "willst Du" scheint mir auch nicht unbedingt aussage(frage)kräftig, steht üblicherweise nicht in meinen Dialogboxen. Könnt es vielleicht sein, dass das mal Q&D hingeklickt ist um die Funktionalität auszuprobieren / zu zeigen......?

Aber im Ernst. Wer für Desktop programmiert, der ist gewöhnt, dass "modal" bedeutet, dass die Anwendung erst weiterläuft, wenn das modale Fenster geschlossen wurde,
Darum geht's hier. Nicht um Namenskonventionen oder Programmlesbarkeit.

Sir Rufo 13. Feb 2015 08:37

AW: Android: MessageDlg Logik
 
Es gibt zwei Aussagen, wo ich reflexartig einen Würgereiz bekomme:
  • Das haben wir schon immer so gemacht
  • Das haben wir noch nie gemacht
Was möchte man mir damit mitteilen?

Dass man eine Lobotomie hinter sich hat und darum nicht mehr denken kann?

Und etwas an das man sich gewöhnt hat, muss nicht zwangsläufig richtig sein. Wenn man sich den Code anschaut, der dieses blockierende ShowModal verbricht (anders kann man es nicht beschreiben) und dieses mit dem Konzept einer GUI-Anwendung abgleicht, der versteht dann auch, dass dieses neue Verhalten nun endlich dem entspricht, was das GUI-Konzept vorgegeben hat.

Manchmal schmerzt die Erkenntnis, dass man sich jahrelang auf dem Holzweg befunden hat. Mir egal, ich schlage mir einmal beherzt vor die Stirn, schreie einmal laut "Mann, logisch!" und ab dann übernehme ich das.

Daniel 13. Feb 2015 08:39

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von eddie11 (Beitrag 1289724)
Wer für Desktop programmiert, der ist gewöhnt, dass "modal" bedeutet, dass die Anwendung erst weiterläuft, wenn das modale Fenster geschlossen wurde

Das ist richtig. Und auf den mobilen Geräten gibt es andere Spielregeln, mit denen man konfrontiert wird. Das ist am Anfang erstmal ein Kulturschock, ohne Zweifel.
Und manchmal muss man dann komplett umdenken - diese Dialoge und der komplett geänderte Ablauf sind ein schönes Beispiel dafür. Die Ausgangsfrage war, die andere diese Thematik behandeln und Ruf hat - wenn auch ein wenig ruppig - einen schönen Weg dafür aufgezeigt, der insbesondere auch ohne Exit auskommt.

Sir Rufo 13. Feb 2015 08:45

AW: Android: MessageDlg Logik
 
@Daniel

Ist es nicht eher so, dass dieses Konzept schon vom ersten Tag der Programmierung an so hätte laufen müssen? Nein auch ich habe diese "blockierenden" Dialoge eingesetzt, aber war es deswegen "richtig"?

mkinzler 13. Feb 2015 08:46

AW: Android: MessageDlg Logik
 
Ich würde modale Dialoge nuicht per se als falsch ansehen aber für mobilen Anwendungen sind sie sicherlich weniger geeignet.

eddie11 13. Feb 2015 08:51

AW: Android: MessageDlg Logik
 
also:

- das war schon immer so
- das war noch nie so

erzeugt bei mir auch einen Würgereiz dazu noch

- da könnt' ja jeder kommen

:):)

Die Lösung von SirRufo scheint ja wirklich besser..

Ich habe halt immer ein Problem damit, wenn ein Thread, in dem eine bestimmte Frage gestellt wurde ("MessageDlg Logik") abgleitet in "wer programmieren kann ist besser dran" oder so. Und dann lass' ich mich eben nicht gerne anmaulen... :oops::oops:

Sir Rufo 13. Feb 2015 08:51

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von mkinzler (Beitrag 1289738)
Ich würde modale Dialoge nuicht per se als falsch ansehen aber für mobilen Anwendungen sind sie sicherlich weniger geeignet.

Ähm, die Dialoge sind doch immer noch modal ... die blockieren nur nicht mehr.

Daniel 13. Feb 2015 09:18

AW: Android: MessageDlg Logik
 
@Rufo:
Ich stimme mir Dir überein, dass die jetzige Lösung sauberer ist. Zu der Aussage, dass die alte tatsächlich falsch war, würde ich mich nicht hinreißen lassen.
Was wollten wir denn - Beispiel MessageDialog() - erreichen? Dem Anwender eine Antwort abringen und dann entsprechend fortfahren. Das bisherige, blockierende, Verhalten kam mir als Entwickler schon sehr weit entgegen. Zumal es in der damals einzigen Zielplattform - Windows - ja auch in dessen API manifestiert war und somit kein Fremdkörper war.

Sir Rufo 13. Feb 2015 09:45

AW: Android: MessageDlg Logik
 
@Daniel

Den Begriff falsch habe ich (hoffentlich) in diesem Zusammenhang auch bewusst vermieden, denn es hat ja funktioniert. Und es war den Entwicklern von diesem ShowModal ja auch bewusst, denn dort wurde ja ganz bewusst mit
Delphi-Quellcode:
Application.ProcessMessages
gearbeitet und das wo jeder weiß, dass das Vorkommen von
Delphi-Quellcode:
Application.ProcessMessages
ein Design-Fehler ist.

Es wird funktionieren aber eben nicht richtig sein, aber eben auch nicht falsch.

Es ist nicht tragisch
Delphi-Quellcode:
Application.ProcessMessages
zu verwenden, wenn man sich des Workaround-Charakters dieses Ansatzes bewusst ist, der dann aus Zeitgründen oder aus (noch) fehlendem Know-How (wie denn sonst) bewusst gewählt wird. Wichtig ist die Erkenntnis, man ist dort eben noch nicht fertig und es auf die ToDo-Liste schreibt.

greenmile 13. Feb 2015 11:44

AW: Android: MessageDlg Logik
 
Also sorry, modale Messageboxen machen in meinen Augen fast immer Sinn, weil man zu 99% auf etwas wartet, was im Anschluss gemacht wird, ansonsten habe ich ja wieder eine weitere Prozedure, die ich ohne diesen Quatsch nicht hätte. In XE6 (oder XE5?) ging es doch auch. Es jetzt aber so kompliziert zu machen finde ich ekelig. Und fast jeder wird sich eine Funktion wie diese zusammenpfuschen, was ja eigentlich nicht im Sinne des Erfinders ist.

@Sir: Nichts für ungut, aber man kann sich alles neue auch einfach schön reden. Ist ja wie beim Mac/iPhone: Das macht Sinn, der Hersteller hat sich schon was dabei gedacht, worauf Du halt nicht kommst. Das hat nichts mit "War immer so" zu tun, sondern "Ich möchte eine Aufgabe möglichst schnell, einfach und effektiv erledigen."

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;

Olli73 13. Feb 2015 13:27

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von greenmile (Beitrag 1289778)
In XE6 (oder XE5?) ging es doch auch.

Ja, aber:

Wenn du während des Anzeigens eines solchen Dialoges in eine andere App und zurück gewechselt bist, dann war Schluss mit Lustig...

greenmile 13. Feb 2015 13:32

AW: Android: MessageDlg Logik
 
Da hatten die auch noch ganz andere Probleme. Naja, sei es wie es ist: MessageDlg's sind nicht mehr Modal, damit müssen wir leben. Hoffentlich bleibt diese Eigenschaft nur in FMX und kommt nicht in die Windows oder Mac Welt.

Sir Rufo 13. Feb 2015 13:46

AW: Android: MessageDlg Logik
 
Die Dialoge sind immer noch modal aber nicht mehr blockierend!

Jumpy 13. Feb 2015 13:58

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289808)
Die Dialoge sind immer noch modal aber nicht mehr blockierend!

Aber was ist denn da der Unterschied? Ich dachte das blockieren wäre das modale?

Code:
Modale Dialoge sperren den Rest der Anwendung, solange der Dialog angezeigt wird.
Nichtmodale Dialoge erlauben auch Eingaben außerhalb des Dialogs.
aus Wikipedia

Sir Rufo 13. Feb 2015 14:04

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Jumpy (Beitrag 1289810)
Zitat:

Zitat von Sir Rufo (Beitrag 1289808)
Die Dialoge sind immer noch modal aber nicht mehr blockierend!

Aber was ist denn da der Unterschied? Ich dachte das blockieren wäre das modale?

Code:
Modale Dialoge sperren den Rest der Anwendung, solange der Dialog angezeigt wird.
Nichtmodale Dialoge erlauben auch Eingaben außerhalb des Dialogs.
aus Wikipedia

Na dann versuche doch mal mit dem neuen nicht blockierendem Dialog in der Anwendung weiter zu arbeiten. Muss ja nach deinem Verständnis gehen.

Geht aber nicht, denn der Dialog ist modal und sperrt den Rest, aber er blockiert die Codeausführung nicht.

Vorher war der Dialog modal und blockierend, jetzt nur noch modal.

Jumpy 13. Feb 2015 15:16

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289812)
... der Dialog ist modal und sperrt den Rest, aber er blockiert die Codeausführung nicht.

Aha, so ist das gemeint. Die Codeausführung kann quasi schon mit was anderem weiter machen.


Nur aus Neugier (für nicht FMXler), wenn in der weiteren Codeausführung erneut ein modaler Dialog aufgerufen wird während der erste noch nicht geschlossen ist, wie ist das geregelt?

Sir Rufo 13. Feb 2015 19:01

AW: Android: MessageDlg Logik
 
Ohne es explizit ausprobiert zu haben, würde ich bei dieser Konstellation:
Delphi-Quellcode:
procedure foo;
begin
  ConfirmAction( 'Willst du Drucken?', PrintFoo );
  ConfirmAction( 'Willst du Speichern?', SaveFoo );
end;
erwarten, dass der Druck-Dialog erscheint und darüber der Speicher-Dialog.

Daniel 14. Feb 2015 13:00

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289828)
Ohne es explizit ausprobiert zu haben, würde ich bei dieser Konstellation:
Delphi-Quellcode:
procedure foo;
begin
  ConfirmAction( 'Willst du Drucken?', PrintFoo );
  ConfirmAction( 'Willst du Speichern?', SaveFoo );
end;
erwarten, dass der Druck-Dialog erscheint und darüber der Speicher-Dialog.

Ich habe - ohne zu fragen - Dein Beispiel genutzt. Es ist genau anders herum. Erst kommt der zweite Dialog (hier das Speichern), danach dann der erste Dialog (hier das Drucken).

Bernhard Geyer 14. Feb 2015 13:03

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Daniel (Beitrag 1289876)
Ich habe - ohne zu fragen - Dein Beispiel genutzt. Es ist genau anders herum. Erst kommt der zweite Dialog (hier das Speichern), danach dann der erste Dialog (hier das Drucken).

Es kommt aber aus gleiche raus. Erst muss der Speichern-Dialog bestätigt werden und dann der Druck-Dialog

Daniel 14. Feb 2015 13:20

AW: Android: MessageDlg Logik
 
Ich denke, ich würde stets versuchen, solche Szenarien zu vermeiden. Denn eventuell möchte ich ja mit den Daten noch etwas furchtbar aufregendes tun, bevor der zweite Dialog kommt. Wenn die Reihenfolge zur Laufzeit dann umgedreht ist, wäre ich unter Umständen ordentlich gef ... ähm .. ge ... ge ... gekniffen.

Sir Rufo 14. Feb 2015 13:22

AW: Android: MessageDlg Logik
 
Zitat:

Zitat von Daniel (Beitrag 1289876)
Zitat:

Zitat von Sir Rufo (Beitrag 1289828)
Ohne es explizit ausprobiert zu haben, würde ich bei dieser Konstellation:
Delphi-Quellcode:
procedure foo;
begin
  ConfirmAction( 'Willst du Drucken?', PrintFoo );
  ConfirmAction( 'Willst du Speichern?', SaveFoo );
end;
erwarten, dass der Druck-Dialog erscheint und darüber der Speicher-Dialog.

Ich habe - ohne zu fragen - Dein Beispiel genutzt. Es ist genau anders herum. Erst kommt der zweite Dialog (hier das Speichern), danach dann der erste Dialog (hier das Drucken).

Dann habe ich mich unglücklich ausgedrückt: Wenn der Speicher-Dialog über dem Drucken-Dialog liegt, dann muss erst der Speicher-Dialog und dann der Drucken-Dialog bearbeitet werden.

Das Handling ist also ein Stack (Last In First Out) und genau das ist auch zu erwarten gewesen.

Und ich wette dass zuerst der Drucken-Dialog erzeugt und angezeigt wird, dann der Speicher-Dialog erzeugt und angezeigt wird - da aber der Speicher-Dialog die gleiche Größe wie der Drucken-Dialog hat und der exakt an der gleichen Stelle liegt ist der Drucken-Dialog nicht sichtbar, denn der Speicher-Dialog liegt eben darüber. Er ist also da aber nicht sichtbar weil ja eben verdeckt.

Und da zwischen dem Anzeigen der beiden Dialoge eben keine Stunden vergehen, sondern eher Millisekunden ist das Auge einfach zu träge um dieses zu bemerken.

mkinzler 14. Feb 2015 13:23

AW: Android: MessageDlg Logik
 
im Besonderen, wenn der Code
Delphi-Quellcode:
procedure foo;
begin
  ConfirmAction( 'Willst du Speichern?', SaveFoo );
  ConfirmAction( 'Programm Schliessen?', ExitFoo );
end;
lauten würde

Sir Rufo 14. Feb 2015 13:26

AW: Android: MessageDlg Logik
 
Ähm, warum ich dieses Beispiel gebracht habe ist aber schon noch präsent?

Ich mache das nicht so, empfehle es niemandem so, sondern habe lediglich die Frage von Jumpy mit einem Codebeispiel beantwortet.

Anhand der Beschreibung kann jeder für sich selber entscheiden, ob er dieses Verhalten so haben möchte oder eben nicht.

Hätte ich evetuell in meiner Antwort vermerken sollen, dass sowas schwachsinning ist? Ich war kurz davor, habe es mir aber verkniffen ;)

Daniel 14. Feb 2015 13:30

AW: Android: MessageDlg Logik
 
Natürlich ist es absurd.
Ich wollte dennoch wissen, was passiert. :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:07 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