With VCL you can use CreateMessageDialog
to generate a message dialog with custom button captions.
With FMX CreateMessageDialog
does not seem to exist anymore (since XE3).
Is there a way to customize the button captions with FireMonkey other than rebuilding the message dialog from scratch?
What I would like to be able is to call a function as described here:
MessageDlg(
'Really quit application ?', mtWarning,
[ButtonInfo(mbNo, 'Do&n''t save'),
ButtonInfo(mbCancel, '&Cancel'),
ButtonInfo(mbYes,'&Save')],
mbYes
);
In short, no. You don't have access to the actual dialog, like you do in VCL. Like DadisX said in comment, you can only change the resource string values, but not touch the dialog itself.
However, with that said, FMX uses a platform abstraction layer to handle the actual dialog, and that you can tweak a bit. On each supported platform, FMX has a class that implement's FMX's 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()
.
Refer to Embarcadero's documentation for more details:
FireMonkey Platform Services
I found SynTaskDialog for Lazarus and FireMonkey, a port of SynTaskDialog to FireMonkey. SynTaskDialog uses the Windows TaskDialog API natively on newer Windows versions and emulates it on other platforms.
With this Open Source library I can define:
/// 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;
With this you can call:
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;