Using C++ MFC and WinRt error "this function must be called from a UI thread"

50 views Asked by At

I have a MFC application which calls a coroutine named CheckForAppUpdates, from its OnInitDialog function. When the code executes, I get an error message:

this function must be called from a UI thread

Here is the relevant code:

BOOL MainDlg::OnInitDialog() {
     CDialogEx::OnInitDialog();
     HWND hwnd = GetSafeHwnd();

     winrt::init_apartment();
     CheckForAppUpdates(hwnd);
     // snip
}


winrt::fire_and_forget MainDlg::CheckForAppUpdates(HWND hWnd) {
try {
    // Capture the UI thread context
    // co_await winrt::resume_foreground(); // needs a Dispatcher.. which needs a..
    winrt::apartment_context ui_thread;
    // Switch to a background thread
    co_await winrt::resume_background();

    if (auto storeContext{ winrt::Windows::Services::Store::StoreContext::GetDefault() })
    {
        const auto updates =  co_await storeContext.GetAppAndOptionalStorePackageUpdatesAsync();

        if (updates) {
            const auto numUpdates = updates.Size();

            if (numUpdates > 0) {

                co_await ui_thread;
                // This method must be called on the UI thread. See docs..
                auto result = co_await storeContext.RequestDownloadAndInstallStorePackageUpdatesAsync(updates);

                auto overallState = result.OverallState();

                CString text;
                switch (overallState)
                {
                case StorePackageUpdateState::OtherError:
                    text = L"Updates: Other Error";
                    break;
                case StorePackageUpdateState::Downloading:
                    text = L"Updates: Downloading";
                    break;
                case StorePackageUpdateState::Pending:
                    text = L"Updates: Pending";
                    break;
                case StorePackageUpdateState::Canceled:
                    text = L"Updates: Cancelled";
                    break;
                case StorePackageUpdateState::Deploying:
                    text = L"Updates: Deploying";
                    break;
                default:
                    text.Format(L"Updates: %d", overallState);
                    break;
                }

                ::PostMessage(hWnd, WM_USER_APP_MSG, 0, (LPARAM)new CString(text));
                co_return;
            }
        }
    }
}
catch (winrt::hresult_error const& ex)
{
    // Handle WinRT exceptions
    ::PostMessage(hWnd, WM_USER_APP_MSG, 1, (LPARAM)new CString(ex.message().c_str()));
}
catch (std::exception const& ex)
{
    // Handle other exceptions
    ::PostMessage(hWnd, WM_USER_APP_MSG, 1, (LPARAM)new CString(ex.what()));
} 
}
0

There are 0 answers