none
[WinRT + C++/CX] Synchronous MessageDialog RRS feed

  • Question

  • Hi

    Is there any chance to create synchronous messagedialog or create own that is synchronous? What I mean is I want to stop code execution until user choose some option.

    Thanks


    • Edited by Artur Siwiak - JMMJ Wednesday, October 15, 2014 8:40 PM Inaccurate topic and question
    Wednesday, October 15, 2014 1:28 PM

Answers

  • I suggest reading up on this topic:

    http://msdn.microsoft.com/en-us/library/windows/apps/hh780559.aspx

    You may be able to chain your tasks together.  In the meantime something like this should work:

    //  Declared outside of your function:
    IAsyncOperation<IUICommand^>^ _dialog;
    
    //  Then in a routine something like this:
    
    
    		IAsyncAction^ pAction = Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() {
    
    			MessageDialog^ msg = ref new MessageDialog("Message", "Title");
    			_dialog = msg->ShowAsync();
    
    		}));
    
    		auto runTask = create_task(pAction);
    		runTask.wait();
    
    		auto dlgTask = create_task(_dialog);
    		dlgTask.wait();
    
    		
    		OutputDebugString(L"After Message Dialog");


    Bret Bentzinger (MSFT) @awehellyeah

    Friday, October 17, 2014 8:29 PM
    Moderator

All replies

  • Wednesday, October 15, 2014 8:18 PM
    Moderator
  • Ok, you have a right. What I really wanted is synchronous MessageDialog.

    I've updated topic, and message

    Wednesday, October 15, 2014 8:43 PM
  • It is not recommended to block your application.  What are you trying to accomplish?


    Bret Bentzinger (MSFT) @awehellyeah

    Thursday, October 16, 2014 4:24 PM
    Moderator
  • Engine in application, that I'm working on, is written in old style: all code is synchronous but working in seperate threads (not on UI thread). 

    What I want to achieve is show messagedialog after click on some button but on click I'm calling the old-style code. This code must wait until user click on messagedialog's button.

    Because there is a lot of places where messagedialog is used to communicate with user I would like to avoid rewriting code and using callbacks (this is unquestionably an extremely complex problem).

    Thursday, October 16, 2014 6:13 PM
  • I am still struggling to understand the issue.   you should be able to await the call to MessageDialog.ShowAsync, and it will not execute the next line of code until that returns.


    Bret Bentzinger (MSFT) @awehellyeah

    Thursday, October 16, 2014 7:20 PM
    Moderator
  • Of course, you are right but to avoid error "The application called an interface that was marshalled for a different thread" I must use RunAsync() and in this case code below RunAsync() will not wait for the result of displayed MessageDialog.

    Consider example - I'm obligated to use foo():

    bool foo() {
      return ShowMessage();
    }
    
    bool ShowMessage() {
        Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this, message, title]() {
        auto loader = ref new Windows::ApplicationModel::Resources::ResourceLoader();
        UICommand^ cancelCommand = ref new UICommand(
          loader->GetString(L"App_Cancel"), ref new UICommandInvokedHandler([this](IUICommand^){
    
        }
        ));
    
        MessageDialog^ msg = ref new MessageDialog(message, title);
        msg->Commands->Append(ref new UICommand("OK", ref new UICommandInvokedHandler([this](IUICommand^){
    
        }
        )));
        msg->Commands->Append(cancelCommand);
        msg->DefaultCommandIndex = 0;
        msg->CancelCommandIndex = 1;
        msg->ShowAsync();
      }));
      return ???; // in need this place need information which button was clicked and then return true or false
    }


    Thursday, October 16, 2014 8:27 PM
  • Now your dilemma makes sense.  Check out this post:

    https://social.msdn.microsoft.com/Forums/windowsapps/en-US/e15d4852-a601-4bd6-88b4-42480fd71e70/win-rt-awaiting-the-dispatcherrunasync?forum=winappswithcsharp

    Basically call RunAsync()->AsTask()->Wait().

    The call to RunAsync() Should block until the message box is done.


    Bret Bentzinger (MSFT) @awehellyeah

    Thursday, October 16, 2014 9:12 PM
    Moderator
  • AsTask() as I see is only in .NET not in Native (which I forgot to mention)
    Thursday, October 16, 2014 11:10 PM
  • I suggest reading up on this topic:

    http://msdn.microsoft.com/en-us/library/windows/apps/hh780559.aspx

    You may be able to chain your tasks together.  In the meantime something like this should work:

    //  Declared outside of your function:
    IAsyncOperation<IUICommand^>^ _dialog;
    
    //  Then in a routine something like this:
    
    
    		IAsyncAction^ pAction = Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, ref new Windows::UI::Core::DispatchedHandler([this]() {
    
    			MessageDialog^ msg = ref new MessageDialog("Message", "Title");
    			_dialog = msg->ShowAsync();
    
    		}));
    
    		auto runTask = create_task(pAction);
    		runTask.wait();
    
    		auto dlgTask = create_task(_dialog);
    		dlgTask.wait();
    
    		
    		OutputDebugString(L"After Message Dialog");


    Bret Bentzinger (MSFT) @awehellyeah

    Friday, October 17, 2014 8:29 PM
    Moderator
  • Works perfectly!

    Thank you very much. Also thank you for the link.

    Friday, October 17, 2014 9:38 PM