Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-08

Inconsistent result from MessageDlg

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart

Hi all,

While investigating issue #19863 in the bugtracker (http://bugs.freepascal.org/view.php?id=19863) I stumbled upon this.

If you have a MessageDlg (without a mrCancel button) and you click the "Close" border-icon of the dialog then the result now depends on your OS (on Windows that is)

On Windows Vista (and up) 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 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;

To me it makes more sense that pressing Escape key and clicking the "Close" border-icon will give the same result.

At least we should make it behave consistently.

Any opinions on how we want it to behave (or how it "must" behave)?

Bart

Reply by email

Bart
to Hans-Peter Diettrich: Two buttons of an Dialog can have the special properties Default (CR) and Cancel (Esc).…
Hans-Peter Diettrich wrote
Bart schrieb: IMO it's perfectly sufficient to also map Close to the Cancel button, and to disallow Close when no button has Cancel=True.

?

You won't be able to do this when using TaskDialogIndirect(), it's just a Windows modal dialog form, and clicking on the "Close" border-icon will close it no matter what we think is convenient...

Show quoted text 5 lines
This will leave it up to the designer, to specify the intended behaviour and results of the dialog. Adding more actions and implicit return values, than specified by the designer, can cause a misinterpretation of these unexpected results, what is highly undesireable.

Well, this is sort of my point too.

If we specify [mbNo,mbYes,mbAbort] I would think it would be logical to only have mrNo, mrYes and mrAbort as possible returnvalues.

Our implementation of the Win Vista dialog behaves like that, the others do not.

It would be pretty easy to make all MessageDlgs behave like that, but I'ld like to hear the opinions of Lazarus devels about that.

Also there is the Delphi compatibility issue (cannot test that, my Delphi is much to old).

Bart

Reply by email

Hans-Peter Diettrich
to Bart: While investigating issue #19863 in the bugtracker…
Show quoted text 8 lines
If you have a MessageDlg (without a mrCancel button) and you click the "Close" border-icon of the dialog then the result now depends on your OS (on Windows that is) On Windows Vista (and up) 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 it will be mrCancel always.

Two buttons of an Dialog can have the special properties Default (CR) and Cancel (Esc).

IMO it's perfectly sufficient to also map Close to the Cancel button, and to disallow Close when no button has Cancel=True. This will leave it up to the designer, to specify the intended behaviour and results of the dialog. Adding more actions and implicit return values, than specified by the designer, can cause a misinterpretation of these unexpected results, what is highly undesireable.

DoDi

Reply by email

Hans-Peter Diettrich
to Bart: ? You won't be able to do this when using TaskDialogIndirect(), it's just a Windows modal…
Show quoted text 11 lines
On 8/19/11, Hans-Peter Diettrich wrote: > Bart schrieb: > > IMO it's perfectly sufficient to also map Close to the Cancel button, > and to disallow Close when no button has Cancel=True. ? You won't be able to do this when using TaskDialogIndirect(), it's just a Windows modal dialog form, and clicking on the "Close" border-icon will close it no matter what we think is convenient...

This only indicates that Lazarus modal dialogs possibly should not be created this way.

Also there is the Delphi compatibility issue (cannot test that, my Delphi is much to old).

I'll test with Delphi XE...

DoDi

Reply by email

Hans-Peter Diettrich
to Hans-Peter Diettrich
Show quoted text 12 lines
Bart schrieb: > On 8/19/11, Hans-Peter Diettrich wrote: >> Bart schrieb: >> >> IMO it's perfectly sufficient to also map Close to the Cancel button, >> and to disallow Close when no button has Cancel=True. > > ? > > You won't be able to do this when using TaskDialogIndirect(), it's > just a Windows modal dialog form, and clicking on the "Close" > border-icon will close it no matter what we think is convenient...

No TaskDialogIndirect procedure in XE. MessageDlgPosHelp forks: if (Win32MajorVersion >= 6) and UseLatestCommonDialogs and ThemeServices.ThemesEnabled then

     Result := DoTaskMessageDlgPosHelp('', Msg, DlgType, Buttons,
       HelpCtx, X, Y, HelpFileName)
   else
     Result := DoMessageDlgPosHelp(CreateMessageDialog(Msg, DlgType,

Buttons),

       HelpCtx, X, Y, HelpFileName);

where the first version creates an TTaskMessageDialog (TCustomTaskDialog), the latter a TForm.

> Also there is the Delphi compatibility issue (cannot test that, my > Delphi is much to old). I'll test with Delphi XE...

The Delphi documentation is outdated, as usual. Experiments on XP suggest that the dialog Close (X) returns mrCancel(=IDCANCEL), regardless of the specified buttons.
TCustomTaskDialog.Flags:TTaskDialogFlags include
tfAllowDialogCancellation, which seems to be ON by default, and tfCanBeMinimized. These flags look as being related to the window menu.

ESC does nothing or maps to e.g. mrNo, depending on the specified buttons.

IMO we are free to return whatsoever when the dialog is only closed, or deny close, as "compiler specific" (undefined) behaviour. I still think that only one of the specified buttons should be returned as the result, so that a Close should act like ESC.

DoDi

Reply by email

Felipe Monteiro de Carvalho
to Hans-Peter Diettrich

I think it should return mrCancel in case of ESC or X button click, regardless of the existing buttons.

If the buttons are No and Yes, you cannot simply map that to either No or Yes. Which one is cancel? That depends on the question.

Felipe Monteiro de Carvalho

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho
Show quoted text 5 lines
I think it should return mrCancel in case of ESC or X button click, regardless of the existing buttons. If the buttons are No and Yes, you cannot simply map that to either No or Yes. Which one is cancel? That depends on the question.

That's quite an easy example: Yes=Default, No=Cancel. When the user shall have a chance for an explicit Cancel, mbYesNoCancel is the right choice instead.

DoDi

Reply by email