2014-12-26 158 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