Reputation: 5166
I know this issue have been up since before (ex. Best way to show customized message dialogs), but I still don't find what I want.
I started like this:
class function TAttracsForm.MessageDlg(const aMsg: string; aDlgType: TMsgDlgType; Buttons: TMsgDlgButtons; aCaptions: array of String; aDefault: TMsgDlgBtn): TModalResult;
var
vDlg: TForm;
i: Integer;
begin
if aButtons.Count = aCaptions.Count then
begin
vDlg := CreateMessageDialog(aMsg, aDlgType, Buttons);
try
for i := 0 aCaptions.Count - 1 do
TButton(vDlg.FindComponent(Buttons[i].Caption)).Caption := aCaptions[i];
vDlg.Position := poDefaultPosOnly;
Result := vDlg.ShowModal;
finally
vDlg.Free;
end;
end;
end;
And the call would look like:
if (MessageDlg('Really quit application ?', mtWarning,
[mbNo, mbCancel, mbYes], {'No save', 'Cancel', 'Save'}) = mrYes) then
But the above code of course don't compile. I don't know how to get one item of an set in the loop and how to get the total count of it in the beginning.
Upvotes: 12
Views: 25274
Reputation: 850
To follow up my comment in the Accepted Answer of the critical bug due to attempting to match buttons in a set to an array of strings, here is the complete working version (as my comment had few clues on how to implement).
function MyMessageDlg(const dlgCaption, dlgMessage : string; dlgType : TmsgDlgType;
captions : array of string) : integer;
var
aMsgdlg : TForm;
i, captionIndex : integer;
dlgButton : Tbutton;
buttons : TMsgDlgButtons; //a set, so can't associate with captions array
begin
buttons := []; //load this set with mb Buttons, 1 per captions array element
for i := 0 to High(captions) do //get all the enums up to the number of buttons
if i <= Ord(High(TMsgDlgBtn)) then //check we haven't blown the set count
buttons := buttons + [TMsgDlgBtn(i)]; //add the mb Buttons to our set
aMsgdlg := createMessageDialog(dlgMessage, dlgType, buttons);
try
aMsgdlg.Caption := dlgCaption;
captionIndex := 0;
for i := 0 to aMsgdlg.ComponentCount-1 do //find our buttons to change labels
begin
if aMsgdlg.Components[i] is TButton then
Begin
dlgButton := aMsgdlg.Components[i] as TButton;
dlgButton.caption := captions[captionIndex];
dlgButton.ModalResult := captionIndex + 1; //override the mrOK etc with our index, +1 as mrNone is 0
inc(captionIndex);
end;
end;
result := aMsgdlg.ShowModal - 1; //back to zero based index
finally
aMsgdlg.free;
end;
end;
I renamed variables to be more obvious, reordered the parameters to match the typical dialog call and to be more logical.
Usage: -
MyMessageDlg('Confirm', 'Yes, No or Maybe?', mtConfirmation, ['Yes','No','Maybe']);
Where the return value will be 0
for Yes
, 1
for No
& 2
for Maybe
.
Cheers :)
Upvotes: 0
Reputation: 31
I write this code: (I am from Croatia, so the texts are in Croatian)
function MojDijalog(const Msg, Capt: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons;
DefaultButton: TMsgDlgBtn): TModalResult;
var
dlg : TForm;
begin
dlg := CreateMessageDialog(Msg, DlgType, Buttons, DefaultButton) ;
with dlg do begin
Caption := Capt;
FormStyle := fsStayOnTop;
( FindComponent( 'OK' ) as TButton ).Caption := 'U redu' ;
( FindComponent( 'Cancel' ) as TButton ).Caption := 'Odustani' ;
( FindComponent( 'Yes' ) as TButton ).Caption := 'Da' ;
( FindComponent( 'No' ) as TButton ).Caption := 'Ne' ;
( FindComponent( 'Help' ) as TButton ).Caption := 'Pomoć' ;
( FindComponent( 'Close' ) as TButton ).Caption := 'Zatvori' ;
( FindComponent( 'Ignore' ) as TButton ).Caption := 'Zanemari' ;
( FindComponent( 'Retry' ) as TButton ).Caption := 'Pokušaj ponovo' ;
( FindComponent( 'Abort' ) as TButton ).Caption := 'Prekini' ;
( FindComponent( 'All' ) as TButton ).Caption := 'Sve' ;
end;
Result := dlg.ShowModal;
end;
Example of use :
if MojDijalog('Obrisati zapis ?','Upit za brisanje',mtConfirmation,mbYesNo,mbNo) = mrNo then
begin
Abort;
end;
Upvotes: 3
Reputation: 613511
How about something like this:
type
TButtonInfo = record
MsgDlgBtn: TMsgDlgBtn;
Caption: string;
end;
function ButtonInfo(MsgDlgBtn: TMsgDlgBtn; const Caption: string): TButtonInfo;
begin
Result.MsgDlgBtn := MsgDlgBtn;
Result.Caption := Caption;
end;
const
ModalResults: array[TMsgDlgBtn] of Integer = (
mrYes, mrNo, mrOk, mrCancel, mrAbort, mrRetry, mrIgnore, mrAll, mrNoToAll,
mrYesToAll, 0, mrClose);
function FindDialogButton(Form: TForm; MsgDlgBtn: TMsgDlgBtn): TButton;
var
i: Integer;
Component: TComponent;
begin
for i := 0 to Form.ComponentCount-1 do begin
Component := Form.Components[i];
if Component is TButton then begin
if TButton(Component).ModalResult=ModalResults[MsgDlgBtn] then begin
Result := TButton(Component);
exit;
end;
end;
end;
Result := nil;
end;
function MessageDlg(
const aMsg: string;
aDlgType: TMsgDlgType;
const Buttons: array of TButtonInfo;
aDefault: TMsgDlgBtn
): TModalResult;
var
i: Integer;
MsgDlgButtons: TMsgDlgButtons;
vDlg: TForm;
begin
MsgDlgButtons := [];
for i := low(Buttons) to high(Buttons) do begin
Assert(not (Buttons[i].MsgDlgBtn in MsgDlgButtons));//assert uniqueness
Include(MsgDlgButtons, Buttons[i].MsgDlgBtn);
end;
vDlg := CreateMessageDialog(aMsg, aDlgType, MsgDlgButtons, aDefault);
try
for i := low(Buttons) to high(Buttons) do begin
FindDialogButton(vDlg, Buttons[i].MsgDlgBtn).Caption := Buttons[i].Caption;
end;
vDlg.Position := poDefaultPosOnly;
Result := vDlg.ShowModal;
finally
vDlg.Free;
end;
end;
procedure Test;
begin
MessageDlg(
'Really quit application ?',
mtWarning,
[ButtonInfo(mbNo, 'Do&n''t save'), ButtonInfo(mbCancel, '&Cancel'), ButtonInfo(mbYes,'&Save')],
mbYes
);
end;
Upvotes: 8
Reputation: 337
you can use this code:
function MyMessageDlg(CONST Msg: string; DlgTypt: TmsgDlgType; button: TMsgDlgButtons;
Caption: ARRAY OF string; dlgcaption: string): Integer;
var
aMsgdlg: TForm;
i: Integer;
Dlgbutton: Tbutton;
Captionindex: Integer;
begin
aMsgdlg := createMessageDialog(Msg, DlgTypt, button);
aMsgdlg.Caption := dlgcaption;
aMsgdlg.BiDiMode := bdRightToLeft;
Captionindex := 0;
for i := 0 to aMsgdlg.componentcount - 1 Do
begin
if (aMsgdlg.components[i] is Tbutton) then
Begin
Dlgbutton := Tbutton(aMsgdlg.components[i]);
if Captionindex <= High(Caption) then
Dlgbutton.Caption := Caption[Captionindex];
inc(Captionindex);
end;
end;
Result := aMsgdlg.Showmodal;
end;
For example:
MyMessageDlg('Hello World!', mtInformation, [mbYes, mbNo],
['Yessss','Noooo'], 'New MessageDlg Box'):
Upvotes: 22