View Issue Details

IDProjectCategoryView StatusLast Update
0021801LazarusLCLpublic2012-04-30 07:20
ReporterMarkus Müller Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version1.1 (SVN) 
Target Version1.0.0 
Summary0021801: Clicking on mbClose button in a MessageDlg returns mrCancel instead of mrClose as result
DescriptionI have program this Message Box:

MessageDlg(Caption, 'buggy', mtInformation, [mbOK, mbClose], 0);

When I press the button mbClose, then the result must be mrClose but it is mrCancel.

I use this Version:
Lazarus-1.1-36568-fpc-2.6.0-20120405-win64.exe

Here the Demo-Code, take a Button and a Label1 in your Form:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Label1.Caption := IntToStr(MessageDlg(Caption, 'buggy', mtInformation, [mbOK, mbClose], 0));
end;

mrClose must = 11, mrCancel is 2.
TagsNo tags attached.
Fixed in Revisionr37065, r37066
LazTarget-
WidgetsetWin32/Win64
Attached Files

Relationships

related to 0021844 closedJuha Manninen Patches TBitBTn with Kind=bkClose and ModalResult=mrClose does not set ParentForm's ModalResult to mrClose 

Activities

Markus Müller

2012-04-19 07:18

reporter   ~0058742

When I press the button mbClose (not mnClose), then the result must be mrClose but it is mrCancel.

I cannot edit my Bugreport.

Markus Müller

2012-04-19 08:10

reporter   ~0058745

The thing is, I need a Close button for do something else. When I press the "X" on right top from the window, then comes a mrCancel, what is right.

Bart Broersma

2012-04-19 18:42

developer   ~0058766

I cannot reproduce this on Win7 (64-bit OS, 32-bit Lazarus/Fpc) with Lazarus 1.1 r36898.
MessageDlg with [mbOk, mbClose]
ModalResult = mrClose if I click on the button that says "Close".
If I close the dialog by clicking on the X-bordericon, ModalResult = mrOk

2012-04-19 19:09

 

TestMsg.zip (128,220 bytes)

Markus Müller

2012-04-19 19:10

reporter   ~0058770

Last edited: 2012-04-19 20:18

Sorry, it work not right.

I have Upload a example.

I have load the newest SVN snapshot:
Lazarus-1.1-36901-fpc-2.6.0-20120419-win32.exe

When you close the dialog by clicking on the X-bordericon must be ModalResult = mrCancel
Now this works right. Only the Close have not ModalResult = mrClose.

Markus Müller

2012-04-19 19:21

reporter   ~0058771

With the "Lazarus-1.1-36883-fpc-2.6.0-20120419-win64.exe", it works not good, like the same.

I use Win7/64

Maxim Ganetsky

2012-04-19 22:37

developer   ~0058775

Confirmed in Lazarus 1.1 r36911 FPC 2.6.1 i386-win32-win32/win64 (Windows XP SP3 32 bit).

Bart Broersma

2012-04-20 12:15

developer   ~0058787

Last edited: 2012-04-20 14:15

I'm getting a little confused.

MessageDlg('MessageDlg Test', 'Click any button', mtInformation, [mbOK, mbClose], 0);

Lazarus r36898/fpc 2.6.0 win64/win32

Click "OK": result = mrOK
Click "Close": result = mrClose
Click X-bordericon: result = mrOK

What exactly is wrong with these results?
Possibly the last one should be mrCancel?
(See also the discussion on the mailinglist: http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-August/066230.html )

Markus Müller

2012-04-20 14:18

reporter   ~0058790

With my Lazarus:

Click "OK": result = mrOK
Click "Close": result = mrCancel >> I want see mrClose
Click X-bordericon: result = mrCancel

When your "Click X-bordericon: result = mrOK" >> this is a bug, it MUST be mrCancel
When you use Delphi, the Click X-bordericon have mrCancel.

theo

2012-04-20 15:12

reporter   ~0058797

Lazarus 1.1 r36728M FPC 2.7.1 x86_64-linux-gtk 2

X-bordericon returns mrOK instead of mrCancel.

robson

2012-04-20 15:31

reporter   ~0058798

Lazarus 1.1 r36928 FPC 2.6.0 i386-linux-gtk 2

X-bordericon returns mrCancel (2)
Button "Cancel" click = mrCancel (2)
Alt+F4 = mrCancel (2)
Button "Ok" click = (1)
Button "Close" click = (11)

Bart Broersma

2012-04-20 17:30

developer   ~0058806

> X-bordericon returns mrOK instead of mrCancel.

Explanation for this behaviour:

On Windows Vista (and up) (using the new "Vista dialogs") the result will be "EscapeResult" (user presses Escape key: the result depends on the actual buttons in the dialog: it will be mrNo if you have [mbYes,mbNo] as buttons).
On lower Windows versions (XP, Win9x) it will be mrCancel always.

The cause lies in the WidgetSet.PromptUser() function:

In WidgetSet.PromptUser we do not correct for CancelValue

...
  if PromptDialogFunction <> nil then
    Result := PromptDialogFunction(DialogCaption, DialogMessage, DialogType,
       Buttons, ButtonCount, DefaultIndex, EscapeResult, True, 0, 0)


in TWin32WidgetSet.PromptUser we do correct for it:
...
      Result := IDCANCEL;
      TaskDialogIndirect(@TaskConfig, @Result, nil, nil);
      if Result = IDCANCEL then
        Result := EscapeResult;

This seems incompatible with Delphi (but someone should test with Delphi XE) and it is inconsistent across widgetsets.

This inconsistency will create unexpected bugs in userprograms for developers who only test on Vista and up.

I'll attach a patch for this part of the bugreport.



Still, original reporter states that clicking on mbClose button returns mrCancel??? Can anyone confirm this?

Bart Broersma

2012-04-20 17:39

developer   ~0058807

@Markus:
> Click "Close": result = mrCancel >> I want see mrClose

By "Close" you mean the Button with mbClose?

We are using almost the same revision and nothing relevant to this problem has changed from r36883 (your version) to r36898 (mine).

Markus Müller

2012-04-20 17:58

reporter   ~0058809

Last edited: 2012-04-20 18:01

Yes, the button mbClose.

The button mbClose and mbCancel have the same result, you can look at my demo program:

procedure TForm1.Button2Click(Sender: TObject);
begin
  Label1.Caption := IntToStr(MessageDlg(Caption, 'buggy', mtInformation, [mbOK, mbClose, mbCancel], 0));
end;

I have test it with two PC's, one Win7/64 and one XP/SP3.
Two diverent SVN installation, the same result.

Bart Broersma

2012-04-20 22:53

developer   ~0058817

@Markus: I can reproduce it on Win9x.

I think the problem is this.
When in TWin32WidgetSet.PromptUser
if (WindowsVersion >= wvVista) and ThemeServices.ThemesEnabled
evaluates to False then
inherited PromptUser is called.

This eventually builds an LCL form via TPromptDialog.CreateMessageDialog()
On this TBitBtns are created with the correct Kind and ModalResult (I tested this).

However, if you click on a TBitBtn with Kind = bkClose, then the form will close with ModalResult = mrCancel (it simply calls GetParentForm.Close and does not set ModalResult).

On Vista and Win7 (with themes enabled) Lazarus does not build it's own MessageDlg form but uses Windows built-in TaskDialogIndirect and mrClose is returned if you press mbClose button.

2012-04-20 23:11

 

modalres.zip (2,750 bytes)

Bart Broersma

2012-04-20 23:20

developer   ~0058819

Last edited: 2012-04-20 23:35

Attached sample program (in modalres.zip) shows the different behaviour in setting ModalResult for a TBitButton with Kind = bkClose.
Form2 hat 2 TBitButtons
1: Kind = bkClose, ModalResult = mrClose
2: Kind = bkCustom, Modalresult = mrClose

Clicking first button: ModalResult = mrCancel (wrong)
Clicking second button: ModalResult = mrClose (correct)

This is the piece of code that is resposable for this behaviour:

in lcl/include/bitbtn.inc

procedure TCustomBitBtn.Click;
var
  Form : TCustomForm;
begin
  if FKind = bkClose then begin
    Form := GetParentForm(Self);
    if Form <> nil then begin
      Form.Close;
      exit;
    end;
  end;
  inherited Click;
end;

inherited click calls (in lcl/include/buttons.inc)

procedure TCustomButton.Click;
var
  Form : TCustomForm;
Begin
  if ModalResult <> mrNone
  then begin
    Form := GetParentForm(Self);
    if Form <> nil then Form.ModalResult := ModalResult;
  end;
  inherited Click;
end;

So if Kind <> bkClose then ModalResult of parentform is set, otherwise not.
In TCustomForm.ShowModal, when ModalResult = 0 it will the set ModalResult to mrCancel.

My old delphi, that does not have mrClose, will also resturn mrCancel if a TBitBtn has Kid = bkClose.
So this behaviour is possibly for delphi compatibility?

Bart Broersma

2012-04-20 23:59

developer   ~0058822

Attached patch (promptdialog-mrclose.diff) solves the issue in promptdialog.inc
It sets the Kind proprty of the mbClose button to bkCustom (this will work as long as setting Kind := bkCustom will not reset the glyph or reset ModalResult)

This patch could be applied if we do not want to change the behaviour of TBitBtn.Click (see note 0058819).

To resolve the wrong result when clicking the X-bordericon on Vista and Win7, the patch in win32promptuser.diff should also be applied (see note 0058806).

Bart Broersma

2012-04-21 00:02

developer   ~0058823

Target 1.0 for review of patches.

Markus Müller

2012-04-21 08:26

reporter   ~0058825

Thank you very much for the changes. I have include it an recompile Lazarus.

Now, the Result:

mbOK >> Result Integer=1 = mrOK
mbClose >> Result Integer=6 = mrYes
mbCancel >> Result Integer=2 = mrCancel

I think the mbClose must make mrClose.

Now, I have make a better testing programm, please load the "TestMsg2.zip"
Here you can choice every button what you want see and see the result.

2012-04-21 08:26

 

TestMsg2.zip (3,745 bytes)

Bart Broersma

2012-04-21 17:04

developer   ~0058839

Last edited: 2012-04-21 17:18

@Markus: could you please test with attached sample program (msgdlg.zip)?

First in lcl/include/promptdialog:

procedure TPromptDialog.LayoutDialog;

change

      with CurButton do
      begin
        Parent:= Self;
        Layout := blGlyphLeft;
        OnKeyDown := @PromptDialogKeyDown;
        Kind := DialogButtonKind[Buttons[curBtn]];
        if Height < Glyph.Height + 5 then


(approx line nr. 265)
into

      with CurButton do
      begin
        Parent:= Self;
        Layout := blGlyphLeft;
        OnKeyDown := @PromptDialogKeyDown;
        Kind := DialogButtonKind[Buttons[curBtn]];

        if (Kind = bkClose) then
        begin
          CurButton.Kind := bkCustom;
          CurButton.ModalResult := mrClose;
        end;

        if Height < Glyph.Height + 5 then


Build and run the sample program.
Select mbOk and mbClose, then press button "Use TPromptDialog.CreateMessagDialog" (this will ensure that the LCL's own-built dialog appears).

In the console you will see what buttons are on the form and what their Kind and ModalResults are.
(If these are wrong, please report back)

Report back the results for:
1. click on OK
2. click on Close
3. click on X-bordericon
4. press Escape key

If the dialog returns a ModalResult that is "inavlid" (e.g. mrYes in this case) it will report it in the console.
If you see this happening, please copy the contenst of the console and report them here.

On my WinME (Win9x) and Win7-64 the results (with changes made in promptdialog.inc) are:
1. mrOK
2. mrClose
3. mrCancel
4. mrOK

2012-04-21 17:07

 

msgdlg.zip (3,897 bytes)

Markus Müller

2012-04-21 17:36

reporter   ~0058841

Last edited: 2012-04-21 17:40

The Result for "Use TPromptDialog.CreateMessagDialog"
1. mrOK
2. mrClose
3. mrCancel
4. mrOK

The Result for "Use Widgetset.PromptUser"
1. mrOK
2. mrYes
3. mrCancel
4. mrOK

The Result with my demo program
1. mrOK
2. mrYes
3. mrCancel
4. mrOK

Win7/64, Lazarus 1.1 r36901 FPC 2.6.0 i386-win32-win32/win64

If you want look into my PC, we can make a TeamViewer session, write me a mail.

Bart Broersma

2012-04-21 22:46

developer   ~0058856

Last edited: 2012-04-21 23:16

Results for MessageDlg('MessageDlg Test', 'Click any button', mtInformation, [mbOK, mbClose], 0) in Delphi XE:
1. mrOk
2. mrClose
3. mrCancel
4. mrCancel
(Source: http://www.nldelphi.nl/Forum/showthread.php?p=320088#post320088 )

If patch from win32promptuser.diff is applied, then Lazarus results on Win7 are the same.

2012-04-22 03:10

 

MyChanges.zip (16,155 bytes)

Markus Müller

2012-04-22 03:15

reporter   ~0058862

Yes, I have alter both files. You can see it in my Uploaded Files "MyChanges.zip".

Markus Müller

2012-04-22 05:07

reporter   ~0058863

Last edited: 2012-04-22 05:09

I have make a Linux-Test, without your .diff modifications:

The Result with my demo program
1. mrOK
2. mrClose
3. mrOK
4. mrOK

Lazarus 1.1 r36826, 2012-04-18, FPC 2.6.0, x86_64-linux-gtk 2, run in VirtualBox

The MessageDlg working with different operating systems are not exactly the same. This must be tested for all operating systems, and for all possible keys.

Bart Broersma

2012-04-22 10:04

developer   ~0058867

Last edited: 2012-04-22 12:24

Click on X-bordericon should always return mrCancel (for Delphi compatibility) I think.
Pressing Escape key should / can either return ModalEscapeResult or mrCancel, depending on OS (for instance the new Vista dialogs will return IDCANCEL).
However, I think that ModalEscapeResult in this case ([mbOk,mbClose]) should be mrClose, not mrOk.

Stephano

2012-04-22 10:36

developer   ~0058869

Last edited: 2012-04-22 11:26

Tested on Ubuntu 11.04 (GTK2).

Result for "Use Widgetset.PromptUser"
1. mrOK
2. mrClose
3. mrOK
4. mrOK

Result for "Use TPromptDialog.CreateMessagDialog" without the promptdialog.inc modification
1. mrOK
2. mrCancel (bug)
3. mrOk
4. mrCancel (not inline with MessageDlg's mrOK)

Result for "Use TPromptDialog.CreateMessagDialog" with the promptdialog.inc modification
1. mrOK
2. mrClose
3. mrCancel (not inline with MessageDlg's mrOK)
4. mrOK

I made a thorough test on MessageDlg in ubuntu 11.04. Escape and [x] border icon are equivalent and always return the same modal result. They will return the following in high to low order of preference (assuming the corresponding button is present):
mrCancel
mrNo
mrAbort
mrIgnore
mrNoToAll
mrYes
mrOK
mrRetry
mrAll
mrYesToAll

If the only button in MessageDlg is mbClose, then Escape or [x] will return mrCancel.

This corresponds exactly to what the ModalEscapeValue function does.

Bart Broersma

2012-04-22 12:44

developer   ~0058873

I have started a discussion on the mailinglist about how to respond to clicking on X-bordericon and pressing Escape key: http://lists.lazarus.freepascal.org/pipermail/lazarus/2012-April/073603.html

2012-04-22 16:02

 

TestMsgBox_XE.zip (602,027 bytes)

Markus Müller

2012-04-22 16:09

reporter   ~0058892

Last edited: 2012-04-22 16:12

I have build a DelphiXE Test program and upload it "TestMsgBox_XE.zip". It's the same code like my "TestMsg2.zip". In this ZIP is the EXE for Windows, too. With them you can see it.

Report back the results for:
1. click on OK
2. click on Close
3. click on X-bordericon
4. press Escape key

The result with the DelphiXE application:
1. mrOK
2. mrClose
3. mrCancel
4. mrOK

But when in the dialog is a button mbCancel and you press the Escape key, then the result is mrCancel, not mrOK.
When in the Dialog is only mbOK and mbCancel and mbOK is the default button and you press the Escape key, the result is not the default button, it is mrCancel!

You can test it with this DelphiXE EXE from me.

Markus Müller

2012-04-22 16:17

reporter   ~0058893

Last edited: 2012-04-22 16:30

I think, the X-bordericon and the Escape key should always return the same, mrCancel.

All other buttons where are defined must return the code from Button (mbOK > mrOK)

When press the Enter key, then must return the code from default button.

It is very easy to implement and documentation.

If you want, you can implement a new MessageDlg():
function MessageDlg(const aCaption, aMsg: string; DlgType: TMsgDlgType;
            Buttons: TMsgDlgButtons; HelpCtx: Longint; DefaultButton, EscapeButton: TMsgDlgBtn): Integer;
If the EscapeButton is set, then this is the result for "X-bordericon" and "Escape key".

PS: I have start a forum entry, german: http://www.lazarusforum.de/viewtopic.php?f=18&t=5886

Zeljan Rikalo

2012-04-22 16:35

developer   ~0058894

According to your above explanation (note 0058892) there's bug in Delphi XE, since Escape key should not result in mrOK.
IMO, Escape = [x] button -> should be mrCancel and nothing else in any case.

Bart Broersma

2012-04-22 18:38

developer   ~0058895

Markus's Dephi XE compiled executable on Win7
Buttons: [mbOk, mbClose]
1. OK -> mrOK
2. Close -> mrClose
3. X-bordericon -> mrCancel
4. Escape -> mrCancel

Markus's Dephi XE compiled executable on Win7 in XP compatibility mode
Buttons: [mbOk, mbClose]
1. OK -> mrOK
2. Close -> mrClose
3. X-bordericon -> mrCancel
4. Escape -> mrOK

So confusion in Delphi as well.

Note that before Delphi started using Vista-dialogs, some dialogs would not (and still won't on XP) close when the user presses Escape (e.g. [mbAbort,mbRetry,mbIgnore] or [mbYes,mbAbort,mbClose]).
On Vista and up it always returns mrCancel on Escape.
This makes sense for some combinatiosn of buttons, where pressing escape or clicking [X] leaves you guessing what the user actually wants.

I think that this new Vista and up behaviour will become the de facto standard.

If we want to keep returning ModalEscapeValue() on escape for compatibility with "older" Delphi's then we should also make the dialog behave like it does in Delphi, so not always close the dialog when the user presses Escape, but let it depend on the available buttons in the dialog.

Personally I would go for returning mrCancel always when user presses Escape or [X].

Markus Müller

2012-04-22 18:50

reporter   ~0058896

Last edited: 2012-04-22 18:51

>Personally I would go for returning mrCancel always when user presses Escape or [X].

Yes, do it. For all operating systems. Thx.

PS: My Test, post (0058892) was with WinXP.

Bart Broersma

2012-04-25 15:53

developer   ~0058972

Firts part of this bug (not retuning mrClose when clicked on mbClose) will be fixed by patch for issue 0021844.
(Patch from promptdialog-mrclose.diff can be disregarded)

Bart Broersma

2012-04-25 18:08

developer   ~0058974

Last edited: 2012-04-25 18:11

See msgdlg.diff.

Proposed fix:

If the widgetset has a (native) PromptUser function, then the behaviour of the dialog is as follows:
- Escape and [X]-bordericon will return mrCancel

If no widgetset specific PromptDialog is set up, then eventually TPromptDialog.CreateMessageDialog() is called.
I have changed it's behaviour to be compatible with Delphi:
- [X]-bordericon will return mrCancel
- Escape will only close the dialog if mbOk, mbNo or mbCancel is in Buttons,
  in this case it will return mrCancel, mrNo or mrOk (in that order)
  It does so by setting the Cancel property of the appropriate Button

This behaviour is consistent with both older Delphi's and newer ones using the new Vista-dialogs (as does Lazarus).

Note 0058972 still applies.

2012-04-25 19:51

 

MyChanges2.zip (11,189 bytes)

Markus Müller

2012-04-25 19:55

reporter   ~0058980

Thank you for changes.
I have include the .diff changes and test.
You can check, if my files are ok, see "MyChanges2.zip".

But the Result from MessageDlg(...mbClose...) = mrYes, not mrClose.

Bart Broersma

2012-04-25 23:26

developer   ~0058989

Last edited: 2012-04-25 23:28

@Markus: fixed that.
I updated the file msgdl.diff.
Please try again

2012-04-25 23:27

 

msgdlg.diff (5,412 bytes)   
Index: lcl/dialogs.pp
===================================================================
--- lcl/dialogs.pp	(revision 36898)
+++ lcl/dialogs.pp	(working copy)
@@ -562,11 +562,12 @@
   cBitmapY  = 10;      // y-position for bitmap in messagedialog
   cLabelSpacing = 10;   // distance between icon & label
 
-  DialogResult : Array[mrNone..mrYesToAll] of Longint = (
+  DialogResult : Array[mrNone..mrLast] of Longint = (
     -1, idButtonOK, idButtonCancel, idButtonAbort, idButtonRetry,
     idButtonIgnore, idButtonYes,idButtonNo, idButtonAll, idButtonNoToAll,
-    idButtonYesToAll);
+    idButtonYesToAll,idButtonClose);
 
+
   DialogButtonKind : Array[idButtonOK..idButtonNoToAll] of TBitBtnKind = (
     bkOk, bkCancel, bkHelp, bkYes, bkNo, bkClose, bkAbort, bkRetry,
     bkIgnore, bkAll, bkYesToAll, bkNoToAll);
Index: lcl/include/promptdialog.inc
===================================================================
--- lcl/include/promptdialog.inc	(revision 36898)
+++ lcl/include/promptdialog.inc	(working copy)
@@ -20,8 +20,8 @@
   { TPromptDialog }
 
   TPromptDialog = class(TForm)
-    procedure PromptDialogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
   private
+    FCancelKind: TBitBtnKind;
     function CreateButtons(AVerticalLayout: Boolean; ASpacing: Integer): Integer;
   public
     IsSmallDevice: Boolean;
@@ -44,11 +44,6 @@
     destructor Destroy; override;
   end;
 
-procedure TPromptDialog.PromptDialogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
-begin
-  if (Key = VK_Escape) then
-    ModalResult := -1;
-end;
 
 function TPromptDialog.CreateButtons(AVerticalLayout: Boolean;
  ASpacing: Integer): Integer;
@@ -75,9 +70,9 @@
       begin
         Parent:= Self;
         Layout  := blGlyphLeft;
-        OnKeyDown := @PromptDialogKeyDown;
 
         Kind := DialogButtonKind[Buttons[curBtn]];
+        if Kind = FCancelKind then Cancel := True;
 
         if Height < Glyph.Height + 5 then
           Height := Glyph.Height + 5;
@@ -123,13 +118,15 @@
 
 constructor TPromptDialog.CreateMessageDialog(const ACaption, aMsg: string;
   DialogType : longint; TheButtons: PLongint; ButtonCount, DefaultIndex : Longint);
+var
+  curBtn: Integer;
+  curKind: TBitBtnKind;
 begin
   inherited CreateNew(nil, 1);
 
   IsSmallDevice := (Screen.Width <= 300);
 
   AutoScroll := False;
-  OnKeyDown := @PromptDialogKeyDown;
   //debugln('TPromptDialog.CreateMessageDialog A ButtonCount=',dbgs(ButtonCount));
 
   ControlStyle:= ControlStyle-[csSetCaption];
@@ -170,6 +167,25 @@
   else
     TheDefaultIndex := DefaultIndex;
 
+  //Find which button should respond to cancel (if any)
+  FCancelKind := bkCustom;
+  for curBtn := 0 to NumButtons - 1 do
+  begin
+    if (Buttons[curBtn] >= Low(DialogButtonKind)) and
+       (Buttons[curBtn] <= High(DialogButtonKind)) then
+    begin
+      curKind := DialogButtonKind[Buttons[curBtn]];
+      case curKind of
+        bkCancel: FCancelKind := bkCancel;
+        bkNo: if (FCancelKind <> bkCancel) then FCancelKind := bkNo;
+        bkOk: if not (FCancelKind in [bkCancel, bkNo]) then FCancelkind := bkOk;
+      end;
+    end;
+  end;
+  if FCancelKind = bkCustom then FCancelKind := bkCancel; //default value if no mbCancel, mbNo or mbOk
+
+
+
   // Assures a minimum text size
   if MSG = '' then MSG := '   ';
 
@@ -261,8 +277,8 @@
       begin
         Parent:= Self;
         Layout  := blGlyphLeft;
-        OnKeyDown := @PromptDialogKeyDown;
         Kind := DialogButtonKind[Buttons[curBtn]];
+        if Kind = FCancelKind then Cancel := True;
         if Height < Glyph.Height + 5 then
           Height := Glyph.Height + 5;
 
Index: lcl/include/messagedialogs.inc
===================================================================
--- lcl/include/messagedialogs.inc	(revision 36898)
+++ lcl/include/messagedialogs.inc	(working copy)
@@ -32,36 +32,6 @@
 }
 function ModalEscapeValue(Buttons: TMsgDlgButtons): TModalResult;
 begin
-  If mbCancel in Buttons then
-    Result := mrCancel
-  else
-    If mbNo in Buttons then
-      Result := mrNo
-  else
-    If mbAbort in Buttons then
-      Result := mrAbort
-  else
-    If mbIgnore in Buttons then
-      Result := mrIgnore
-  else
-    If mbNoToAll in Buttons then
-      Result := mrNoToAll
-  else
-    If mbYes in Buttons then
-      Result := mrYes
-  else
-    If mbOk in Buttons then
-      Result := mrOk
-  else
-    If mbRetry in Buttons then
-      Result := mrRetry
-  else
-    If mbAll in Buttons then
-      Result := mrAll
-  else
-    If mbYesToAll in Buttons then
-      Result := mrYesToAll
-  else
     Result := mrCancel;
 end;
 
@@ -132,7 +102,11 @@
 begin
  if (Buttons = []) or (Buttons = [mbHelp]) then
     Buttons := Buttons + [mbOk];
-  CancelValue := ButtonResults[ModalEscapeValue(Buttons)];
+  //Native PromptUser() dialog should return mrCancel on Escape or [X]-bordericon
+  //TPromptDialog.CreatMessageDialog responds to Escape in "old Delhpi" style,
+  //it will return mrCancel, mrNo, or mrOK if one of these buttons is present, else it will not respons to Escape key,
+  //TPromptDialog.CreatMessageDialog does not use the CancelValue variable
+  CancelValue := idButtonCancel;
   if UseDefButton then
     DefaultButton := DefButton
   else

msgdlg.diff (5,412 bytes)   

Markus Müller

2012-04-26 09:27

reporter   ~0059001

Yeah! It Works!

Thank you very much.

Please write in witch SVN it is updated.

Bart Broersma

2012-04-26 14:39

developer   ~0059017

@Markus: I have no commit rights.
One of the Lazarus devels will have to review my patches and commit if he/she agrees.

Markus Müller

2012-04-26 15:16

reporter   ~0059018

Then I wait...

2012-04-26 23:37

 

dialogs.xml.msgdlg.diff (4,436 bytes)   
Index: docs/xml/lcl/dialogs.xml
===================================================================
--- docs/xml/lcl/dialogs.xml	(revision 36898)
+++ docs/xml/lcl/dialogs.xml	(working copy)
@@ -2581,16 +2581,28 @@
 
 expressed as an integer (see the constant definitions in <link id="Controls.TControl">TControl</link>
 
-, [mrNone..mrAll]).</descr>
+, [mrNone..mrAll]). <br/>
+If the user clicks the [X]-bordericon, the return value will be mrCancel. <br/>
+If the user presses the escape key, the result depends on the widgetset: <br/>
+- if the widgetset has implemented a native dialog, the result will be mrCancel. <br/>
+- otherwise the result will be mrCancel, mrNo or mrOk (in that order) if mbCancel, mbNo or mbOk is present
+(the dialog will not close (when the Escape key is pressed) if none of these buttons are present).
+        </descr>
         <errors/>
         <seealso/>
         <example file="dialogs/trymessagedlg.pas"/>
       </element>
       <!-- function result Visibility: default -->
       <element name="MessageDlg.Result">
-        <short>The result of this function is the button the user pressed to close the dialog.</short>
+        <short>The result of this function is either the button the user pressed to close the dialog, or mrCancel.</short>
         <descr>The result of this function is the button the user pressed to close the dialog.<br/>
-This is expresed as an integer</descr>
+This is expresed as an integer.<br/>
+If the user clicks the [X]-bordericon, the return value will be mrCancel. <br/>
+If the user presses the escape key, the result depends on the widgetset: <br/>
+- if the widgetset has implemented a native dialog, the result will be mrCancel. <br/>
+- otherwise the result will be mrCancel, mrNo or mrOk (in that order) if mbCancel, mbNo or mbOk is present
+(the dialog will not close (when the Escape key is pressed) if none of these buttons are present).
+        </descr>
       </element>
       <!-- argument Visibility: default -->
       <element name="MessageDlg.aMsg">
@@ -2647,8 +2659,15 @@
       </element>
       <!-- function result Visibility: default -->
       <element name="MessageDlgPos.Result">
-        <short>The result of this function is the button the user pressed to close the dialog.</short>
-        <descr>The result of this function is the button the user pressed to close the dialog.</descr>
+        <short>The result of this function is either the button the user pressed to close the dialog, or mrCancel.</short>
+        <descr>The result of this function is the button the user pressed to close the dialog.<br/>
+This is expresed as an integer.<br/>
+If the user clicks the [X]-bordericon, the return value will be mrCancel. <br/>
+If the user presses the escape key, the result depends on the widgetset: <br/>
+- if the widgetset has implemented a native dialog, the result will be mrCancel. <br/>
+- otherwise the result will be mrCancel, mrNo or mrOk (in that order) if mbCancel, mbNo or mbOk is present
+(the dialog will not close (when the Escape key is pressed) if none of these buttons are present).
+        </descr>
       </element>
       <!-- argument Visibility: default -->
       <element name="MessageDlgPos.aMsg">
@@ -2697,8 +2716,15 @@
       </element>
       <!-- function result Visibility: default -->
       <element name="MessageDlgPosHelp.Result">
-        <short>The result of this function is the button the user pressed to close the dialog.</short>
-        <descr>The result of this function is the button the user pressed to close the dialog.</descr>
+        <short>The result of this function is either the button the user pressed to close the dialog, or mrCancel.</short>
+        <descr>The result of this function is the button the user pressed to close the dialog.<br/>
+This is expresed as an integer.<br/>
+If the user clicks the [X]-bordericon, the return value will be mrCancel. <br/>
+If the user presses the escape key, the result depends on the widgetset: <br/>
+- if the widgetset has implemented a native dialog, the result will be mrCancel. <br/>
+- otherwise the result will be mrCancel, mrNo or mrOk (in that order) if mbCancel, mbNo or mbOk is present
+(the dialog will not close (when the Escape key is pressed) if none of these buttons are present).
+        </descr>
       </element>
       <!-- argument Visibility: default -->
       <element name="MessageDlgPosHelp.aMsg">
dialogs.xml.msgdlg.diff (4,436 bytes)   

Bart Broersma

2012-04-26 23:39

developer   ~0059031

Attached file dialogs.xml.msgdlg.diff contains a proposed update for documentation of MessageDlg, MessageDlgPos and MessagedlgPoshelp.

Markus Müller

2012-04-27 07:04

reporter   ~0059033

Why not generate a mrESC?

The dialog result can be mrESC when press the ESC Key or X-bordericon.

OK, it is not compatible with Delphi, but I think in this system have a long time ago Delphi make something not good.

Stephano

2012-04-27 10:48

developer   ~0059039

@Bart,
What if the dialog is as follows:
Your C: drive will be formatted now.
[Ok] [Abort]

Will the Escape button cause the drive to be formatted?

or:
The following operation is not recommended as it might cause loss of data. Stop now?
[Yes] [No]

Again Escape will not be the ideal action.

Bart Broersma

2012-04-27 11:13

developer   ~0059042

@Stephano: this has not changed, current implementation does this also.
It is also the way Delphi does this.
As a programmer you should not write such a messagedlg()!

@Markus: no need to implement yet another ModalResult.
This would also break Delphi compatibility.

Markus Müller

2012-04-27 12:39

reporter   ~0059045

No, I do not need it a other, yet. But I think, there are the result for ESC and X not good, in Delphi and Lazarus.

Juha Manninen

2012-04-28 16:55

developer   ~0059067

Applied, thanks.
The potential problems will be noticed only after applying the changes to trunk.
Please test everybody.

P.S.
I think Bart should have more rights but he does not want them :)

Stephano

2012-04-28 17:39

developer   ~0059068

He might need the rights as we are currently discussing some related changes on the mailing list. This includes bug 0021844 as well.

Markus Müller

2012-04-30 07:20

reporter   ~0059125

I have test the SVN 37071 for Win32, it works.
There are no other setup pakets in snapshot server !? They are all SVN36883.

Issue History

Date Modified Username Field Change
2012-04-19 07:17 Markus Müller New Issue
2012-04-19 07:17 Markus Müller Widgetset => Win32/Win64
2012-04-19 07:18 Markus Müller Note Added: 0058742
2012-04-19 08:10 Markus Müller Note Added: 0058745
2012-04-19 18:42 Bart Broersma Note Added: 0058766
2012-04-19 19:09 Markus Müller File Added: TestMsg.zip
2012-04-19 19:10 Markus Müller Note Added: 0058770
2012-04-19 19:13 Markus Müller Note Edited: 0058770
2012-04-19 19:21 Markus Müller Note Added: 0058771
2012-04-19 20:18 Markus Müller Note Edited: 0058770
2012-04-19 21:33 Maxim Ganetsky LazTarget => -
2012-04-19 21:33 Maxim Ganetsky Summary MessageDlg(mbClose) >> Result ist mnCancal not mrClose! => MessageDlg(mbClose) >> Result is mrCancel not mrClose!
2012-04-19 21:33 Maxim Ganetsky Description Updated
2012-04-19 22:37 Maxim Ganetsky Note Added: 0058775
2012-04-19 22:37 Maxim Ganetsky Status new => confirmed
2012-04-20 12:15 Bart Broersma Note Added: 0058787
2012-04-20 13:51 Bart Broersma Note Edited: 0058787
2012-04-20 13:51 Bart Broersma Note Edited: 0058787
2012-04-20 14:14 Bart Broersma Note Edited: 0058787
2012-04-20 14:15 Bart Broersma Note Edited: 0058787
2012-04-20 14:18 Markus Müller Note Added: 0058790
2012-04-20 15:12 theo Note Added: 0058797
2012-04-20 15:31 robson Note Added: 0058798
2012-04-20 17:30 Bart Broersma Note Added: 0058806
2012-04-20 17:31 Bart Broersma File Added: win32promptuser.diff
2012-04-20 17:39 Bart Broersma Note Added: 0058807
2012-04-20 17:58 Markus Müller Note Added: 0058809
2012-04-20 18:01 Markus Müller Note Edited: 0058809
2012-04-20 22:53 Bart Broersma Note Added: 0058817
2012-04-20 23:11 Bart Broersma File Added: modalres.zip
2012-04-20 23:20 Bart Broersma Note Added: 0058819
2012-04-20 23:35 Bart Broersma Note Edited: 0058819
2012-04-20 23:53 Bart Broersma File Added: promptdialog-mrclose.diff
2012-04-20 23:59 Bart Broersma Note Added: 0058822
2012-04-21 00:02 Bart Broersma Note Added: 0058823
2012-04-21 00:02 Bart Broersma Target Version => 1.0.0
2012-04-21 00:02 Bart Broersma Summary MessageDlg(mbClose) >> Result is mrCancel not mrClose! => Clicking on mbClose button in a MessageDlg returns mrCancel instead of mrClose as result
2012-04-21 08:26 Markus Müller Note Added: 0058825
2012-04-21 08:26 Markus Müller File Added: TestMsg2.zip
2012-04-21 16:41 Bart Broersma File Added: msgdlg.zip
2012-04-21 17:04 Bart Broersma Note Added: 0058839
2012-04-21 17:05 Bart Broersma Note Edited: 0058839
2012-04-21 17:06 Bart Broersma File Deleted: msgdlg.zip
2012-04-21 17:07 Bart Broersma File Added: msgdlg.zip
2012-04-21 17:08 Bart Broersma Note Edited: 0058839
2012-04-21 17:09 Bart Broersma Note Edited: 0058839
2012-04-21 17:10 Bart Broersma Note Edited: 0058839
2012-04-21 17:18 Bart Broersma Note Edited: 0058839
2012-04-21 17:36 Markus Müller Note Added: 0058841
2012-04-21 17:39 Markus Müller Note Edited: 0058841
2012-04-21 17:40 Markus Müller Note Edited: 0058841
2012-04-21 22:46 Bart Broersma Note Added: 0058856
2012-04-21 23:16 Bart Broersma Note Edited: 0058856
2012-04-22 03:10 Markus Müller File Added: MyChanges.zip
2012-04-22 03:15 Markus Müller Note Added: 0058862
2012-04-22 05:07 Markus Müller Note Added: 0058863
2012-04-22 05:09 Markus Müller Note Edited: 0058863
2012-04-22 10:04 Bart Broersma Note Added: 0058867
2012-04-22 10:36 Stephano Note Added: 0058869
2012-04-22 10:57 Stephano Note Edited: 0058869
2012-04-22 11:00 Stephano Note Edited: 0058869
2012-04-22 11:07 Stephano Note Edited: 0058869
2012-04-22 11:19 Stephano Note Edited: 0058869
2012-04-22 11:20 Stephano Note Edited: 0058869
2012-04-22 11:23 Stephano Note Edited: 0058869
2012-04-22 11:24 Stephano Note Edited: 0058869
2012-04-22 11:26 Stephano Note Edited: 0058869
2012-04-22 12:24 Bart Broersma Note Edited: 0058867
2012-04-22 12:44 Bart Broersma Note Added: 0058873
2012-04-22 16:02 Markus Müller File Added: TestMsgBox_XE.zip
2012-04-22 16:09 Markus Müller Note Added: 0058892
2012-04-22 16:10 Markus Müller Note Edited: 0058892
2012-04-22 16:12 Markus Müller Note Edited: 0058892
2012-04-22 16:17 Markus Müller Note Added: 0058893
2012-04-22 16:19 Markus Müller Note Edited: 0058893
2012-04-22 16:23 Markus Müller Note Edited: 0058893
2012-04-22 16:30 Markus Müller Note Edited: 0058893
2012-04-22 16:35 Zeljan Rikalo Note Added: 0058894
2012-04-22 18:38 Bart Broersma Note Added: 0058895
2012-04-22 18:50 Markus Müller Note Added: 0058896
2012-04-22 18:51 Markus Müller Note Edited: 0058896
2012-04-23 12:04 Bart Broersma Relationship added related to 0021844
2012-04-25 15:53 Bart Broersma Note Added: 0058972
2012-04-25 17:59 Bart Broersma File Added: msgdlg.diff
2012-04-25 18:08 Bart Broersma Note Added: 0058974
2012-04-25 18:11 Bart Broersma Note Edited: 0058974
2012-04-25 19:51 Markus Müller File Added: MyChanges2.zip
2012-04-25 19:55 Markus Müller Note Added: 0058980
2012-04-25 23:26 Bart Broersma Note Added: 0058989
2012-04-25 23:27 Bart Broersma File Deleted: msgdlg.diff
2012-04-25 23:27 Bart Broersma File Added: msgdlg.diff
2012-04-25 23:28 Bart Broersma Note Edited: 0058989
2012-04-26 09:27 Markus Müller Note Added: 0059001
2012-04-26 14:39 Bart Broersma Note Added: 0059017
2012-04-26 15:16 Markus Müller Note Added: 0059018
2012-04-26 23:11 Bart Broersma File Deleted: win32promptuser.diff
2012-04-26 23:12 Bart Broersma File Deleted: promptdialog-mrclose.diff
2012-04-26 23:37 Bart Broersma File Added: dialogs.xml.msgdlg.diff
2012-04-26 23:39 Bart Broersma Note Added: 0059031
2012-04-27 07:04 Markus Müller Note Added: 0059033
2012-04-27 10:48 Stephano Note Added: 0059039
2012-04-27 11:13 Bart Broersma Note Added: 0059042
2012-04-27 12:39 Markus Müller Note Added: 0059045
2012-04-28 16:55 Juha Manninen Fixed in Revision => r37065, r37066
2012-04-28 16:55 Juha Manninen Status confirmed => resolved
2012-04-28 16:55 Juha Manninen Resolution open => fixed
2012-04-28 16:55 Juha Manninen Assigned To => Juha Manninen
2012-04-28 16:55 Juha Manninen Note Added: 0059067
2012-04-28 17:39 Stephano Note Added: 0059068
2012-04-30 07:20 Markus Müller Note Added: 0059125