Delphi FireMonkey 中带有自定义按钮标题的 MessageDlg

MessageDlg with custom button captions in Delphi FireMonkey

您可以使用 VCL CreateMessageDialog to generate a message dialog with custom button captions

使用 FMX CreateMessageDialog 似乎不再存在(自 XE3 起)。

除了从头开始重建消息对话框之外,还有其他方法可以使用 FireMonkey 自定义按钮标题吗?

我希望能够将函数调用为 described here:

MessageDlg(
    'Really quit application ?', mtWarning,
    [ButtonInfo(mbNo, 'Do&n''t save'), 
     ButtonInfo(mbCancel, '&Cancel'),
     ButtonInfo(mbYes,'&Save')],
    mbYes
  );

简而言之,没有。您无权访问实际对话框,就像您在 VCL 中所做的那样。正如 DadisX 在评论中所说,您只能更改资源字符串值,而不能触摸对话框本身。

然而,话虽如此,FMX 使用平台抽象层来处理实际对话,您可以稍微调整一下。在每个支持的平台上,FMX 都有一个 class 来实现 FMX 的 IFMXDialogService interface to provide platform-appropriate dialogs. You can write your own class that implements IFMXDialogService and overrides its MessageDialog() method (amongst others) to do whatever you want with your own custom dialogs. Then you can unregister the default class for IFMXDialogService using TPlatformServices.RemovePlatformService() and register your class using TPlatformServices.AddPlatformService().

有关详细信息,请参阅 Embarcadero 的文档:

FireMonkey Platform Services

我发现 SynTaskDialog for Lazarus and FireMonkey, a port of SynTaskDialog 到 FireMonkey。 SynTaskDialog 在较新的 Windows 版本上原生使用 Windows TaskDialog API,并在其他平台上模拟它。

有了这个开源库我可以定义:

/// returns 100 if first button is pressed, 101 if second button is pressed, ...
function MessageDlgCustom(
  const MsgHeader: string; const MsgText: string; const DlgType: TMsgDlgType; 
  const Buttons: array of string; const DefaultButton: Integer = 0): TModalResult;
var
    Task: TTaskDialog;
    I: Integer;
    DlgIcon: TTaskDialogIcon;   
    Title: string;
begin
    case DlgType of
        TMsgDlgType.mtWarning:
            begin
                DlgIcon := tiWarning;
                Title := 'Warning';
            end;
        TMsgDlgType.mtError:
            begin
                DlgIcon := tiError;
                Title := 'Error';
            end;
        TMsgDlgType.mtInformation:
            begin
                DlgIcon := tiInformation;
                Title := 'Information';
            end;
        TMsgDlgType.mtConfirmation:
            begin
                DlgIcon := tiQuestion;
                Title := 'Confirm';
            end;
        else begin
            DlgIcon := tiBlank;
            Title := '';
        end;
    end;
    Task.Title := Title;
    Task.Inst := MsgHeader;
    Task.Content := MsgText;
    for I := Low(Buttons) to High(Buttons) do
    begin
        if I <> Low(Buttons) then
          Task.Buttons := Task.Buttons + #13#10;
        Task.Buttons := Task.Buttons + Buttons[I];
    end;

    //see docu: custom buttons will be identified with an ID number starting at 100
    Result := Task.Execute([], DefaultButton, [], DlgIcon) - BUTTON_START;
end;

有了这个你可以调用:

case MessageDlgCustom('Quit application', 'Really quit application?', mtWarning,
  ['Save', 'Don''t save', 'Cancel']) of
    100: Quit(SAVE_YES);
    101: Quit(SAVE_NO);
    102: Abort;
end;