2014-12-26 129 views
0

随着XE7中非阻塞MessageDlg的出现,看起来现在不可能有​​条件地阻止该应用程序。从收盘像我们这样在Windows(或XE5所做的那样):阻止Android应用。关闭

procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
begin 
    CanClose := False; 
    FCanClose := False; 
    FMX.Dialogs.MessageDlg('Exit?' 
     , 
     TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0, 
      procedure(const AResult: TModalResult) 
      begin 
      if AResult = mrYes then 
       FCanClose := True; 
      end 
    ); 
    CanClose := FCanClose; 

end; 

的的MessageDlg(和匿名程序)后,方可形式已经关闭被调用,从而击败的对象。哦,如果你想知道为什么我要使用FCanclose,那是因为我在匿名程序中遇到了一个关于“无法捕获Canclose”的编译器错误。

现在我尝试的另一种可能性是将MessageDlg放在FormKeyUp事件处理程序中并捕获vkHardwareBack。

procedure TfrmMain.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char; 
    Shift: TShiftState); 
var 
    FService: IFMXVirtualKeyboardService; 
begin 
    if Key = vkHardwareBack then 
    begin 
    TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyBoardService, 
     IInterface(FService)); 
     if (FService <> nil) then 
     begin 
     if (TVirtualKeyBoardState.Visible in FService.VirtualKeyBoardState) then 

     else 
     begin 
      FMX.Dialogs.MessageDlg('Exit?' 
      , 
      TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0, 
      procedure(const AResult: TModalResult) 
      begin 
      if AResult = mrYes then 
       Key := 0; // prevent exit, if Key could be "captured" 
      end 
     ); 
     end; 
     end; 
end; 

但再次,经过FormKeyUp事件处理程序执行完毕后,再次渲染键设置无用的MessageDlg只调用! (如果它可以被“俘虏”,那是)

如何给用户的选项关闭应用程序,因为也许他们打后退按钮一旦过于频繁,或者是因为有一些他们所需要的任务在他们被允许退出之前完成?

+2

AFAIK,移动应用程序不应该被用户关闭。至少这就是iOS的工作原理。操作系统具有让用户远离应用程序并直接终止的功能。 –

+0

您不需要该类的字段来解决无法捕获var参数的问题。你可以捕捉本地。 –

+0

够公平的。虽然没有回答这个问题。 – nolaspeaker

回答

5

该字段FCanCloseFalse初始化。在CloseQueryCanClose的第一个呼叫将被设置为False并且MessageDialog将显示出来。确认对话框mrYesFCanClose将被设置为True并再次调用表单的Close方法。现在,虽然FCanCloseTrue将不会有对话框,CanClose设置为True,表单将关闭。

procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
begin 
    if not FCanClose then 
    FMX.Dialogs.MessageDlg(
     'Exit?', 
     TMsgDlgType.mtConfirmation, 
     [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 
     0, 
     procedure(const AResult: TModalResult) 
     begin 
     if AResult = mrYes then 
     begin 
      FCanClose := True; // set the field value 
      Close; // call close again 
     end; 
     end); 

    CanClose := FCanClose; 
end; 
+0

真棒解决方案!从我+1(没有足够的代表投票给你) – nolaspeaker