Solved

MessageDlg buttons not in right order

Posted on 2014-01-20
3
740 Views
Last Modified: 2014-01-21
Hi Experts, I have a 3-button MessageDlg like this:


MsgVar := MessageDlg('Problem found!'+#13#10+#13#10+
                        'Click YES to proceed and display each occurence of this.'+#13#10+
                        'Click IGNORE to proceed without showing any more occurrences.'+#13#10+
                        'Click ABORT to abort this process altogether.', mtWarning, [mbYes,mbIgnore,mbAbort], 0);

if MsgVar = mrYes then FoundDiscrepancy[i] := FALSE
else if MsgVar = mrIgnore then FoundDiscrepancy[i] := TRUE
else EXIT;

Open in new window



When it displays, it shows the 3 buttons in the wrong order. It shows them as
YES   ABORT   IGNORE

when it should be:

YES   IGNORE  ABORT

However, when I do click a button, it does seem to perform the appropriate action - it's just the order that's wrong. Any idea what would be going on?

Thanks!
    Shawn
0
Comment
Question by:shawn857
3 Comments
 
LVL 24

Assisted Solution

by:jimyX
jimyX earned 250 total points
ID: 39796156
That's normal. Delphi set that order and logic, even if you tried to change them, Delphi will revert back.
Because the buttons are not actually placed in the MsgForm by the logic you think of. What Delphi does actually is looping through the array of ButtonNames and if the button is present in you MsgDlg assigned Buttons it's placed first and then proceed to the next and when found another button it will be placed until finishing the array. That's why when you put two YESes you do not get two buttons like [mbyes, mbAbort,mbIgnore,mbYes].

You have two options here, either to change "Dialogs.pas" and set that order to suit your requirement, or change the caption of the MsgDlg's Buttons in order to show the preferred order, but your buttons' actions will be different and perform different, they will perform same as in Delphi's order so 1st btn will be 'Yes' and will return "mrYes", 2nd btn will be 'Ignore' but will return "mrAbort", and finally 3rd btn 'Abort' will return "mrIgnore" so it will be confusing (very confusing) to interpret the result of the MsgDlg.

In case you want to change the Dialog's Source, here is the part you want to work with, but make sure to work on a local copy at your project folder of "Dialogs.pas" file:
Here is the order that Delphi uses:
{ Message dialog }

type
  TMsgDlgBtn = (mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore,
    mbAll, mbNoToAll, mbYesToAll, mbHelp);
  TMsgDlgButtons = set of TMsgDlgBtn;
...
var
  ButtonNames: array[TMsgDlgBtn] of string = (
    'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', 'All', 'NoToAll',
    'YesToAll', 'Help');
  ButtonCaptions: array[TMsgDlgBtn] of Pointer = (
    @SMsgDlgYes, @SMsgDlgNo, @SMsgDlgOK, @SMsgDlgCancel, @SMsgDlgAbort,
    @SMsgDlgRetry, @SMsgDlgIgnore, @SMsgDlgAll, @SMsgDlgNoToAll, @SMsgDlgYesToAll,
    @SMsgDlgHelp);
  ModalResults: array[TMsgDlgBtn] of Integer = (
    mrYes, mrNo, mrOk, mrCancel, mrAbort, mrRetry, mrIgnore, mrAll, mrNoToAll,
    mrYesToAll, 0);

Open in new window





And here is what you want it to be:
{ Message dialog }
// Make sure to put them all in the same order
                 // mbYes, mbNo, mbOK,....
//should parallel
               // Yes, No, OK,...
//and parallel
              // mrYes, mrNo, mrOK,...
// and so on.
type
  TMsgDlgBtn = (mbYes, mbNo, mbOK, mbCancel, mbRetry, mbIgnore, mbAbort,
    mbAll, mbNoToAll, mbYesToAll, mbHelp);
  TMsgDlgButtons = set of TMsgDlgBtn;
...
var
  ButtonNames: array[TMsgDlgBtn] of string = (
    'Yes', 'No', 'OK', 'Cancel', 'Retry', 'Ignore', 'Abort', 'All', 'NoToAll',
    'YesToAll', 'Help');
  ButtonCaptions: array[TMsgDlgBtn] of Pointer = (
    @SMsgDlgYes, @SMsgDlgNo, @SMsgDlgOK, @SMsgDlgCancel, @SMsgDlgRetry, @SMsgDlgIgnore,
    @SMsgDlgAbort, @SMsgDlgAll, @SMsgDlgNoToAll, @SMsgDlgYesToAll,
    @SMsgDlgHelp);
  ModalResults: array[TMsgDlgBtn] of Integer = (
    mrYes, mrNo, mrOk, mrCancel, mrRetry, mrIgnore, mrAbort, mrAll, mrNoToAll,
    mrYesToAll, 0);

Open in new window


If you prefer to work over the MsgBtns' caption then use this function.

The third option is to create your own MsgForm from scratch.

It is better to leave it the way it is. I am sure Delphi has got a good reason to set the order in that way. In anyways the user will eventually find those buttons and will be able to pick the suitable one to click for the action no matter what was the order of the buttons.
0
 
LVL 36

Accepted Solution

by:
Geert Gruwez earned 250 total points
ID: 39796289
it processes them like this in the source of CreateMessageDialog

   for B := Low(TMsgDlgBtn) to High(TMsgDlgBtn) do
      if B in Buttons then
      begin
        LButton := TButton.Create(Result);
        with LButton do
        begin
          Name := ButtonNames[B];
          Parent := Result;

Open in new window


you could call your own function switching the button positions as you need
unit uTestEE;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure SwitchPos(Button1, Button2: TButton);
var P: TPoint;
begin
  P := Point(Button1.Left, Button1.Top);
  Button1.Left := Button2.Left;
  Button1.Top := Button2.Top;
  Button2.Left := P.X;
  Button2.Top := P.Y;
end;

function MessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; DoSwitchPos: Boolean = False): Integer;
const
  ButtonNames: array[TMsgDlgBtn] of string = (
    'Yes', 'No', 'OK', 'Cancel', 'Abort', 'Retry', 'Ignore', 'All', 'NoToAll',
    'YesToAll', 'Help', 'Close');
var D: TForm;
  B1, B2, B3: TButton;
begin
  D := CreateMessageDialog(Msg, DlgType, Buttons);
  try
    if DoSwitchPos then
    begin
      B1 := TButton(D.FindComponent(ButtonNames[mbYes]));
      B2 := TButton(D.FindComponent(ButtonNames[mbNo]));
      B3 := TButton(D.FindComponent(ButtonNames[mbIgnore]));
      SwitchPos(B1, B2);
      SwitchPos(B3, B1);
    end;
    Result := D.ShowModal;
  finally
    D.Free;
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  // Original position
  MessageDlg('Yes, No, Ignore', mtWarning, [mbYes, mbNo, mbIgnore]);
  // Switched posses
  MessageDlg('No, Ignore, Yes', mtWarning, [mbNo, mbIgnore, mbYes], True);
end;

end.

Open in new window

0
 

Author Closing Comment

by:shawn857
ID: 39798430
Thanks for the info guys, sounds like too much bother really and I just used the constant mbYesNoCancel option instead and that works okay for me.

Thanks!
   Shawn
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now