Modal Android Dialog using Delphi 10.2.1 Tokyo

左心房为你撑大大i 提交于 2019-12-10 20:23:50

问题


I have the following Delphi code for showing a modal message on Android which worked fine on 10.1 Berlin, but stopped working on Delphi 10.2.1 Tokyo. This procedure now hangs the Android app.

procedure customShowMessage(AMessage: string);
//good idea to have our own procedure that we can tweak, as even for VCL and windows, we have done show message differently over the years due to all sorts of funny problems
var
  LModalWindowOpen: boolean;
begin
  LModalWindowOpen := true;

  TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbOK], TMsgDlgBtn.mbOK, 0,
         procedure(const AResult: TModalResult)
         begin
           LModalWindowOpen := false;
         end);

  while LModalWindowOpen do
    begin
      Application.ProcessMessages; //since 10.2 Tokyo, popup never shows and this loops forever
    end;
end;

I suspect it possibly has something to do with the change in Tokyo as to how the app runs in the main thread. Not sure what I can replace Application.ProcessMessages with that will let the dialog show, so that the user can click on something.

I have a lot of places this is used, so changing it to work using a callback is going to be a lot of work, and restructuring.


回答1:


On Android we have only asynchronous dialog boxes. If we want they act as modal dialog box, we have to do ourself.

The solution with a ProcessMessage loop is an idea, but I don't think it's the best approach.

An other one is to add a transparent (or opaque) layout (or rectangle) on your form before displaying the dialog box and when you have an answer, you can remove the blockin layout.

You can also use TFrameStand from Andrea Magni (downloadable directly from GetIt) how propose to use a TFrame as a dialog box. https://github.com/andrea-magni/TFrameStand




回答2:


I think the following code should work:

function ShowMessageOKCancel(AMessage: String): String;
var
  lResultStr: String;
begin
  lResultStr:='';
  TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform;
  TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation,
    FMX.Dialogs.mbOKCancel, TMsgDlgBtn.mbOK, 0,
    procedure(const AResult: TModalResult)
    begin
      case AResult of
        mrOK: lResultStr:='O';
        mrCancel:  lResultStr:='C';
      end;
    end);

  Result:=lResultStr;
end;

When you call this function, it should show a dialog with your message and the two buttons OK and Cancel. The return value will indicate which button was clicked.




回答3:


I have restructured a lot of code to use asynchronous callbacks, but where callback hell ensues (especially on large existing projects), I have found the following works:

Instead of just using Application.ProcessMessages, I am now calling CheckSynchronize as well.

procedure TfrmStock.WaitForModalWindowToClose;
begin
  while FModalWindowOpen do
    begin
       Sleep(40);
       Application.ProcessMessages;
       CheckSynchronize;
    end;
end;


来源:https://stackoverflow.com/questions/45836330/modal-android-dialog-using-delphi-10-2-1-tokyo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!