Is there a Firemonkey equivalent for Windows' MessageBox(), i.e. where the dialog's caption/title can be set? I know I can make one myself but prefer to use an existing solution, but I can't seem to find it.
-
1I dont think there is one. I ended up writing a wrapper class, which uses MessageBox on Windows and NSAlert on OSX. The build in MessageDlg also had issues with localisation. – DA. Jan 31 '14 at 05:29
-
Ah, yet another piece of code I will be writing twice. I started out using FMX thinking I could write all code once, but I find myself learning more and more about coding for the Mac :). Thanks, I'll look up NSAlert. – Mike Versteeg Jan 31 '14 at 09:46
-
What header file do I need to include to be able to use NSAlert? I cannot seem to find it, and the help does not help much (as usual). – Mike Versteeg Jan 31 '14 at 13:46
3 Answers
ok here is my example how I am using NSAlert:
unit DAMessageBox;
interface
uses
System.SysUtils,
System.IOUtils,
FMX.Dialogs,
System.UITypes,
{$IFDEF MSWINDOWS}
Winapi.ShellAPI, Winapi.Windows, Vcl.Forms;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
Macapi.CocoaTypes, Macapi.Foundation, Macapi.AppKit,
Posix.Stdlib;
{$ENDIF POSIX}
type
TDAMessageBox = class
class function MessageDialog(const Title: String; const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint) : integer;
end;
implementation
class function TDAMessageBox.MessageDialog(const Title: String; const Msg: string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Integer): integer;
var
{$IFDEF MSWINDOWS}
WinButtons : Cardinal;
WinType : Cardinal;
{$ENDIF WINDOWS}
{$IFDEF POSIX}
Alert: NSAlert;
Style: NSAlertStyle;
DlgRes : Integer;
{$ENDIF POSIX}
begin
{$IFDEF MSWINDOWS}
case DlgType of
TMsgDlgType.mtWarning: WinType:= MB_ICONWARNING;
TMsgDlgType.mtError: WinType:= MB_ICONSTOP;
TMsgDlgType.mtInformation: WinType:= MB_ICONINFORMATION;
TMsgDlgType.mtConfirmation: WinType:= MB_ICONQUESTION;
TMsgDlgType.mtCustom: WinType:= MB_ICONINFORMATION;
end;
if Buttons = mbOKCancel then begin
WinButtons:= MB_OKCANCEL;
end;
if Buttons = mbYesNo then begin
WinButtons:= MB_YESNO;
end;
if Buttons = mbYesNoCancel then begin
WinButtons:= MB_YESNOCANCEL;
end;
Result:= MessageBox(Application.Handle, PChar(Msg), PChar(Title), WinType or WinButtons);
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
Alert:= TNSAlert.Create;
//map the configurations:
//mtWarning, mtError, mtInformation, mtConfirmation
case DlgType of
TMsgDlgType.mtWarning: Style:= NSWarningAlertStyle;
TMsgDlgType.mtError: Style:= NSCriticalAlertStyle;
TMsgDlgType.mtInformation: Style:= NSInformationalAlertStyle;
TMsgDlgType.mtConfirmation: Style:= NSInformationalAlertStyle;
TMsgDlgType.mtCustom: Style:= NSInformationalAlertStyle;
end;
try
Alert.setMessageText(NSSTR(Title));
Alert.setInformativeText(NSSTR(Msg));
Alert.setAlertStyle(Style);
//add dialog buttons, note: there are only 3 buttons allowed:
//mbAbortIgnore, mbAbortRetryIgnore, *mbOKCancel,mbYesAllNoAllCancel, mbYesAllNoAllCancel, *mbYesNo, *mbYesNoCancel
//currently I only map the ones I need here
if Buttons = mbOKCancel then begin
//Writeln('mbOKCancel');
Alert.addButtonWithTitle(NSSTR('OK'));
Alert.addButtonWithTitle(NSSTR('Cancel'));
end;
if Buttons = mbYesNo then begin
//Writeln('mbYesNo');
Alert.addButtonWithTitle(NSSTR('Yes'));
Alert.addButtonWithTitle(NSSTR('No'));
end;
if Buttons = mbYesNoCancel then begin
//Writeln('mbYesNoCancel');
Alert.addButtonWithTitle(NSSTR('Yes'));
Alert.addButtonWithTitle(NSSTR('No'));
Alert.addButtonWithTitle(NSSTR('Cancel'));
end;
DlgRes := Alert.runModal;
//map the result to Delphi Consts
//NSAlertFirstButtonReturn = 1000,
//NSAlertSecondButtonReturn = 1001,
//NSAlertThirdButtonReturn = 1002
if Buttons = mbOKCancel then begin
if DlgRes = NSAlertFirstButtonReturn then Result := idYes;
if DlgRes = NSAlertSecondButtonReturn then Result := idNo;
end;
if (Buttons = mbYesNo) or (Buttons = mbYesNoCancel) then begin
if DlgRes = NSAlertFirstButtonReturn then Result := idYes;
if DlgRes = NSAlertSecondButtonReturn then Result := idNo;
if DlgRes = NSAlertThirdButtonReturn then Result := idCancel;
end;
finally
Alert.release;
end;
{$ENDIF POSIX}
end;
end.
The MessagBox call is similar to the MessageDlg call in FireMonkey:
TDAMessageBox.MessageDialog('Title', 'Message Text', TMsgDlgType.mtError, mbYesNoCancel, 0);
The result looks like that:

- 849
- 6
- 19
-
Did not even try this code as I notice there is no way to set the title, which was the reason for my post. Also, having seen NSAlert (ShowMessage translates to it) it looks like a real alert box while I need a common dialog to show some information. – Mike Versteeg Feb 03 '14 at 13:59
-
Yes you are right. I added the "title" to the example. For NSAlert you can add two texts: Alert.setMessageText(NSSTR(Title)); and Alert.setInformativeText(NSSTR(Msg));. Its not really a Window title as on Window, its showing two texts in the dialog. – DA. Feb 03 '14 at 22:39
-
Sorry for commenting on an old message. I found this solution recently and have been using it in FMX with Delphi 10.4. It gives a very annoying issue in the following way. After the message box appears click a window in another application, then click the message box again somewhere on the form (not the title bar). The main form immediately gains focus and the message box is hidden behind. The message box is still active so you can't move the main form or do anything with it to get the message box back. The only thing left to do is close the application from task manager. Any ideas so solve? – XylemFlow Jul 28 '21 at 08:36
-
Have a look at this answer. Using the Open Source SynTaskDialog for Lazarus and FireMonkey, you can define a custom message box or a message box replacement where the dialog caption can be set.
It does work on Firemonkey in Windows, but I haven't tested it under OSX until now.
Another method, that works on all OS, takes almost the same time to write, and is much more flexible : Create a new Form, say with name "fmDialog1", put the Title and Text(s) you want (and possibly some images), and Buttons such as OK, Cancel, Yes, No, etc. Give each button a different value, non zero, to its ModalResult property
Then in the code where the dialog is needed, write (in C++) aa=fmDialog1->ShowModal(); or (in Pascal/Delphi) aa:=fmDialog1.ShowModal(); and test aa to see which button was selected by the user.
In Android apps, you may have to add a loop to overcome the asynchronous character of ShowModal.

- 21
- 3