2017-03-17 34 views
4

我有一個正在移植到FireMonkey的VCL應用程序。我遇到的其中一個問題是FireMonkey中不推薦使用MessageDlg(...)。進一步挖掘,我明白我必須使用FMX.DialogService.MessageDialog方法。所以,我創建了一個函數來顯示一個對話框:德爾福 - 在FireMonkey中正確顯示消息對話框並返回模態結果

function TfMain.GetDeleteConfirmation(AMessage: String): String; 
var 
    lResult: String; 
begin 
    lResult:=''; 
    TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform; 
    TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation, 
    [ TMsgDlgBtn.mbYes, TMsgDlgBtn.mbCancel ], TMsgDlgBtn.mbCancel, 0, 
    procedure(const AResult: TModalResult) 
    begin 
     case AResult of 
     mrYes: lResult:='Y'; 
     mrCancel: lResult:='C'; 
     end; 
    end); 

    Result:=lResult; 
end; 

我不認爲,因爲我不知道我可以設置一個匿名方法中的局部變量,我這樣做的權利,但它仍然編譯。

我叫它像這樣:

if GetDeleteConfirmation('Are you sure you want to delete this entry?')<>'Y' then 
    exit; 

當我運行它,顯示的消息對話框是這樣的:

enter image description here

它不顯示2個按鈕(是的,取消) 。有人可以幫我解決這個問題 - 即用2個按鈕正確顯示消息對話框,並將消息對話框的模態結果作爲功能的結果發回。

我正在使用Delphi 10.1柏林更新2.

非常感謝提前!

編輯20170320:我糾正了我的下面@LURD正確答案的基礎上的代碼和我在這裏,包括它的完整性:

function TfMain.GetDeleteConfirmation(AMessage: String): String; 
var 
    lResultStr: String; 
begin 
    lResultStr:=''; 
    TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform; 
    TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation, 
    FMX.Dialogs.mbYesNo, TMsgDlgBtn.mbNo, 0, 
    procedure(const AResult: TModalResult) 
    begin 
     case AResult of 
     mrYes: lResultStr:='Y'; 
     mrNo: lResultStr:='N'; 
     end; 
    end); 

    Result:=lResultStr; 
end; 
+0

您可以在匿名方法中設置局部變量,以便該位正常。其餘的我都看不出有什麼問題。 – Dsm

回答

1

問:

它不顯示2個按鈕(是的,取消)。有人可以幫我解決這個問題 - 即用2個按鈕正確顯示消息對話框,並將消息對話框的模態結果作爲功能的結果發回。

Fmx.TDialogService.MessageDialog不支持任意組合的對話框按鈕。

調查源代碼(Fmx.Dialogs.Win。PAS)揭示了這些有效組合(mbHelp可以包括在全部的組合):

  • MBOK
  • MBOK,mbCancel
  • mbYes,mbNo,mbCancel
  • mbYes,mbYesToAll,mbNo, mbNoToAll ,mbCancel
  • mbAbort,mbRetry,mbIgnore
  • mbAbort,mbIgnore
  • mbYes,mbNo
  • mbAbort,mbCancel

這意味着[mbYes,mbCancel]不是有效的組合,使用[mbOk,mbCancel]代替例如。


關於Fmx.TDialogService.MessageDialog的最後一項說明。它通常是桌面應用程序的同步對話框,但在移動平臺上是異步的。根據這些條件,用例看起來有點不同,因此對於多平臺應用程序,請檢查TDialogService.PreferredMode的值。

+0

謝謝@LURD - 這樣做 - 我現在得到正確的對話框,也是正確的模態結果!僅供參考,FMX.Dialogs有以下適當選擇:mbYesNo,mbYesNoCancel,mbYesAllNoAllCancel,mbOKCancel,mbAbortRetryIgnore,mbAbortIgnore。 – Rohit

0

朋友你好試試這個代碼:

function myMessageDialog(const AMessage: string; const ADialogType: TMsgDlgType; 
    const AButtons: TMsgDlgButtons; const ADefaultButton: TMsgDlgBtn): Integer; 
var 
    mr: TModalResult; 
begin 
    mr:=mrNone; 
    // standart call with callback anonimous method 
    TDialogService.MessageDialog(AMessage, ADialogType, AButtons, 
    ADefaultButton, 0, 
    procedure (const AResult: TModalResult) 
    begin 
     mr:=AResult 
    end); 

    while mr = mrNone do // wait for modal result 
    Application.ProcessMessages; 
    Result:=mr; 
end; 

或者這樣:

function MsgBox(const AMessage: string; const ADialogType: TMsgDlgType; const AButtons: TMsgDlgButtons; 
    const ADefaultButton: TMsgDlgBtn): Integer; 
var 
    myAns: Integer; 
    IsDisplayed: Boolean; 
begin 
    myAns := -1; 
    IsDisplayed := False; 

While myAns = -1 do 
Begin 
    if IsDisplayed = False then 
    TDialogService.MessageDialog(AMessage, ADialogType, AButtons, ADefaultButton, 0, 
      procedure (const AResult: TModalResult) 
      begin 
       myAns := AResult; 
       IsDisplayed := True; 
      end); 

    IsDisplayed := True; 
    Application.ProcessMessages; 
End; 

Result := myAns; 

end; 

享受吧!

+0

感謝您的代碼。你的第一個例子似乎(概念上)與我的代碼相同(除了while循環)。我將它併入我的代碼中,但我仍然看到問題中概述的消息框。我仍然看不到2個按鈕。只是FYI - 我在Windows 10上測試了這個。有什麼想法? – Rohit

+1

「TDialogService」的行爲取決於[PreferredMode](http://docwiki.embarcadero.com/Libraries/en/FMX.DialogService.TDialogService.PreferredMode)。它可以是同步的,異步的或取決於平臺。你的答案似乎假定異步模式,但調用「Application.ProcessMessages」是一種憎惡。 –

+0

@LURD - 如果我沒有指定'PreferredMode',它是否默認爲'Platform'(我認爲它是)。由於我在Windows 10上測試了這個,因此它應該將該方法視爲「同步」 - 正確? – Rohit

相關問題