Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

MessageDlg buttons not in right order

Posted on 2014-01-20
3
Medium Priority
?
936 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 1000 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 38

Accepted Solution

by:
Geert Gruwez earned 1000 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month21 days, 1 hour left to enroll

810 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