locked
MessageDialog and blocking on the main thread for a more powerful assert?

    Question

  • I'm struggling to get MessageDialog to be useful for assertions. I'd like to give the developer the option to break, continue or always ignore an assert - something that was extremely easy in the past via MessageBox and similar APIs and something I've seen implemented at every software house I've worked at in the past, but is now made difficult because I absolutely must stall the main thread to make this useful.

    I am struggling - firstly because PPL task decides throwing an exception is an acceptable response to waiting for a task to complete on the main thread because it is an STA thread... more importantly though it seems that the way MessageDialog is implemented is fundamentally not multi-threaded. Whatever code I write to coax it into stalling and waiting for completion - it just deadlocks and the dialog is not even displayed. If I try and show the dialog from a different thread it throws an undebuggable exception.

    Presumably this is because, for whatever reason, the dialog box, which need no nothing about any of the rest of the app, nor depend on it, has some logical dependency - e.g. is kicked off by a message in some single threaded message queue, or needs something that happens on a frame-by-frame basis, needs to enter some critical section, is spin-locking waiting for some green light etc.

    When the exception is thrown from the wait the dialog does display but not until the subsequent frame, although catching and handling the exception works fine - it doesn't allow me to create the functionality that I want.

    Is there anyway to work around this? Since I want this for debug functionality that will never be seen in the wild I don't see any harm in working this seemingly needless restriction - especially given the ease with which one can write while( true ); vs. using the PPL task stuff, and stall the main thread on demand.

    I find it hard to resist the temptation to rant about all the control I've had taken away in Windows 8/WinRT/Metro development due to "problems" I've never had or caused - only to be rewarded with locks, exceptions, critical sections and leaky memory management schemes that suck away my performance, memory and the joy of coding, whilst preventing me from writing the best code possible... that single sentence will have to suffice.

    Thursday, June 07, 2012 6:00 PM

Answers

  • if it's just for debug (you don't care about appstore validation) you can do whatever you want, even call the MessageBoxW API.  Just GetProcAddress.

    extern "C" HMODULE WINAPI GetModuleHandleW(__in_opt  LPCTSTR lpModuleName);
    
    typedef int (WINAPI *pMessageBox)( __in_opt  HWND hWnd, __in_opt  LPCTSTR lpText, __in_opt  LPCTSTR lpCaption, __in      UINT uType);
    typedef HWND (WINAPI *pGetActiveWindow)(void);
    
    void App2::MainPage::Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	static pMessageBox MessageBox_p = 0;
    	static pGetActiveWindow GetActiveWindow_p = 0;
    
    	HMODULE mod = GetModuleHandleW(L"user32.dll");
    
    	MessageBox_p = (pMessageBox)GetProcAddress(mod, "MessageBoxW");
    	GetActiveWindow_p = (pGetActiveWindow)GetProcAddress(mod, "GetActiveWindow");
    
    	MessageBox_p(GetActiveWindow_p(), L"Hello", L"Hello", MB_OK);
    }
    

    • Marked as answer by Semi Essessi Friday, June 08, 2012 4:02 PM
    Thursday, June 07, 2012 8:07 PM

All replies

  • if it's just for debug (you don't care about appstore validation) you can do whatever you want, even call the MessageBoxW API.  Just GetProcAddress.

    extern "C" HMODULE WINAPI GetModuleHandleW(__in_opt  LPCTSTR lpModuleName);
    
    typedef int (WINAPI *pMessageBox)( __in_opt  HWND hWnd, __in_opt  LPCTSTR lpText, __in_opt  LPCTSTR lpCaption, __in      UINT uType);
    typedef HWND (WINAPI *pGetActiveWindow)(void);
    
    void App2::MainPage::Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	static pMessageBox MessageBox_p = 0;
    	static pGetActiveWindow GetActiveWindow_p = 0;
    
    	HMODULE mod = GetModuleHandleW(L"user32.dll");
    
    	MessageBox_p = (pMessageBox)GetProcAddress(mod, "MessageBoxW");
    	GetActiveWindow_p = (pGetActiveWindow)GetProcAddress(mod, "GetActiveWindow");
    
    	MessageBox_p(GetActiveWindow_p(), L"Hello", L"Hello", MB_OK);
    }
    

    • Marked as answer by Semi Essessi Friday, June 08, 2012 4:02 PM
    Thursday, June 07, 2012 8:07 PM
  • Thanks for the response. I'll give it a go...
    Friday, June 08, 2012 9:31 AM
  • yes... I am giving up and living with the message dialog. its not ideal... without running in the debugger it doesn't steal the focus despite using system modal and foreground properties.
    Friday, June 08, 2012 4:03 PM