XE7 Dialog Box methods support anonymous methods to handle their closing
At today's RAD Studio, Dephi and C++Builder First Look Webinar (September 4 - 6am, 11am and 5pm PDT) several attendees asked questions about how to handle "blocking dialogs" on mobile devices. New in XE7 is support for an additional parameter to support handling the close of the dialog. This new parameter is documented in the "What's new in XE7 Dialog Box methods" document on the Embarcadero DocWiki.
Here is the text from that part of the What's new in XE7 page.
Dialog Box Methods Support Anonymous Methods to Handle Their Closing
In XE6, calls to dialog box methods (InputBox, InputQuery, MessageDlg, ShowMessage) were always blocking. Any code after a call to one of these methods is not executed until the dialog box closes. Android does not allow blocking dialog boxes, so you could not use these methods on Android.
On XE7, InputBox, InputQuery, and MessageDlg support a new optional parameter, <ACloseDialogProc>. Calls that include this new parameter work on all platforms, including Android. This new optional parameter allows you to provide an anonymous method that is called when the dialog box closes. When you call these methods using this new parameter, your call is blocking in desktop platforms and non-blocking in mobile platforms. If you need to execute code after your dialog box closes, use this new parameter to ensure that your application works as expected on all supported platforms. For more information about anonymous methods, see:
§ How to Handle Delphi Anonymous Methods in C++
If you call InputBox, InputQuery, or MessageDlg and you do not provide an anonymous method on your call, these methods behave as they used to behave in XE6: calls are blocking on all platforms, including iOS, and Android is not supported.
ShowMessage also gained support for Android in XE7, and calls to ShowMessage are blocking on desktop platforms and non-blocking on mobile platforms. However, ShowMessage does not provide any new parameter to handle its closing. If you need to execute code after the dialog box that ShowMessage shows closes, use MessageDlg instead of ShowMessage.
Samples are available for Object Pascal and C++
You can find updated examples for MessageDlg in the RAD Studio XE7 Source forge repository. Here are the links for the same programs in XE6 and XE7. If you compare the code you'll see what you need to add for the additional parameter using anonymous methods.
Object Pascal and C++ examples in RAD Studio SourceForge repo:
XE7:
XE6:
When you compare the sample code you need to add for MessageDlg for XE7, here is what you will see.
Object Pascal:
MessageDlg('Choose a button:', System.UITypes.TMsgDlgType.mtInformation,
[
System.UITypes.TMsgDlgBtn.mbYes,
System.UITypes.TMsgDlgBtn.mbNo,
System.UITypes.TMsgDlgBtn.mbCancel
],0,
// Use an anonymous method to make sure the acknowledgment appears as expected.
procedure(const AResult: TModalResult)
begin
case AResult
of
{ Detect which button was pushed and show a different message }
mrYES:
ShowMessage('You chose Yes');
mrNo:
ShowMessage('You chose No');
mrCancel:
ShowMessage('You chose Cancel');
end;
end
)
C++:
struct TCloseDialogHandler :public TCppInterfacedObject<TInputCloseDialogProc> {
void__fastcall Invoke(const System::Uitypes::TModalResult AResult) {
switch (AResult) {
case mrYes : ShowMessage("You chose Yes");
break;
case mrNo: ShowMessage("You chose No");
break;
case mrCancel: ShowMessage("You chose Cancel");
break;
}
}
};
_di_TInputCloseDialogProc handler =new TCloseDialogHandler();
/*
Show a multiple-button alert that triggers different code blocks
according to your input
*/
MessageDlg("Choose a button:", TMsgDlgType::mtInformation,
TMsgDlgButtons() << TMsgDlgBtn::mbYes<< TMsgDlgBtn::mbNo<< TMsgDlgBtn::mbCancel , 0, handler);


Comments
-
Remy Lebeau Friday, 10 April 2015
In XE7 and XE8, the only anonymous-method overload of InputQuery() that is implemented on Android is the one that accepts a TInputCloseQueryProc. The other anonymous-method overloads are NOT IMPLEMENTED by the TPlatformAndroid class, and will raise a "Blocking not implemented on this platform" exception at runtime. This also affects the Android implementation of TLoginCredentialService, which internally uses the unimplemented TInputCloseQueryFunc overload of InputQuery().
-
Stefan D1957 Friday, 9 January 2015
Sry for that but the examples you provide are too simple. In the Windows world we like that a messageDlg is blocking cause we have to wait for some User Entry to continue afterwords.
With the NonBlocking Approach we do not get what we want.
Simple Example:
User hits OK Button on Form to Save some Data.
Now i do some Plausi Controls in a loop.
If Plausi fails a MessageDlg pops out to ask the User what to do....
On Android the Loop will continue although the Dialog is shown....
I have to fully rewrite my code -
Please login first in order for you to submit comments
- Page :
- 1
I understand the need for consistent behaviour and I like how it was solved in Delphi / Object Pascal (while still allowing the default blocking way for other platforms then Android). But the code for C++ is RIDICULOUS and just overkill for such a very simple task: Showing a dialog and get result back. Defining a struct with a function and defining a handler object of it... and all of this outside of the MessageDlg() looks like a very bad way to code this.