104 lines
3.0 KiB
C++
104 lines
3.0 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
//
|
|
// Module Name:
|
|
// - CppWinrtTailored.h
|
|
//
|
|
// Abstract:
|
|
// - This is effectively a copy-paste of TAEF's Tailored.h, ported to cppwinrt.
|
|
// Unfortunately, TAEF only provides a CX or pure c++ version of the
|
|
// RunOnUIThread function, which doesn't compile for us. This version has been
|
|
// ported to cppwinrt for our uses.
|
|
// - RunOnUIThread is a helper function for running test code on the UI thread
|
|
//
|
|
// Author:
|
|
// - Mike Griese (zadjii-msft) 04-Dec-2019
|
|
#pragma once
|
|
#include "pch.h"
|
|
|
|
extern "C" __declspec(dllimport) HRESULT __stdcall Thread_Wait_For(HANDLE handle, unsigned long milliseconds);
|
|
|
|
namespace details
|
|
{
|
|
class Event
|
|
{
|
|
public:
|
|
Event() :
|
|
m_handle(::CreateEvent(nullptr, FALSE, FALSE, nullptr))
|
|
{
|
|
}
|
|
|
|
~Event()
|
|
{
|
|
if (IsValid())
|
|
{
|
|
::CloseHandle(m_handle);
|
|
}
|
|
}
|
|
|
|
void Set()
|
|
{
|
|
::SetEvent(m_handle);
|
|
}
|
|
|
|
HRESULT Wait()
|
|
{
|
|
return Thread_Wait_For(m_handle, INFINITE);
|
|
}
|
|
|
|
bool IsValid()
|
|
{
|
|
return m_handle != nullptr;
|
|
}
|
|
|
|
HANDLE m_handle;
|
|
};
|
|
};
|
|
|
|
// Function Description:
|
|
// - This is a helper function for running a bit of test code on the UI thread.
|
|
// It will synchronously dispatch the provided function to the UI thread, and
|
|
// wait for that function to complete, before returning to the caller. Callers
|
|
// should make sure to VERIFY_SUCCEEDED the result of this function, to ensure
|
|
// the code executed successfully.
|
|
// Arguments:
|
|
// - function: A pointer to some function to run. This should accept no params,
|
|
// and any return value will be ignored.
|
|
// Return Value:
|
|
// - S_OK _after_ we successfully execute the provided function, or another
|
|
// HRESULT indicating failure.
|
|
template<typename TFunction>
|
|
HRESULT RunOnUIThread(const TFunction& function)
|
|
{
|
|
auto m = winrt::Windows::ApplicationModel::Core::CoreApplication::MainView();
|
|
auto cw = m.CoreWindow();
|
|
auto d = cw.Dispatcher();
|
|
|
|
// Create an event so we can wait for the callback to complete
|
|
details::Event completedEvent;
|
|
if (!completedEvent.IsValid())
|
|
{
|
|
return HRESULT_FROM_WIN32(::GetLastError());
|
|
}
|
|
|
|
HRESULT invokeResult = E_FAIL;
|
|
|
|
auto asyncAction = d.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal,
|
|
[&invokeResult, &function]() {
|
|
invokeResult = WEX::SafeInvoke([&]() -> bool { function(); return true; });
|
|
});
|
|
|
|
asyncAction.Completed([&completedEvent](auto&&, auto&&) {
|
|
completedEvent.Set();
|
|
return S_OK;
|
|
});
|
|
|
|
// Wait for the callback to complete
|
|
HRESULT hr = completedEvent.Wait();
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
return invokeResult;
|
|
}
|