0

C++/WinRTagile_ref应该允许以敏捷的方式使用非敏捷对象。但是,我发现这至少在CoreWindow实例中失败了。

作为一个简短的例子:

void Run()
{
    auto window{ CoreWindow::GetForCurrentThread() };
    window.Activate();

    auto agile_wnd{ make_agile(window) };
    ThreadPool::RunAsync([=](const auto&) {
        auto other_wnd{ agile_wnd.get() };
        other_wnd.SetPointerCapture();
    });

    auto dispatcher{ window.Dispatcher() };
    dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}

Run()在 UI 线程上调用,然后尝试创建一个敏捷引用,然后使用它CoreWindow从线程池中调用。但是,这失败了,"The application called an interface that was marshaled for a different thread."因为agile_ref使用RoGetAgileReference内部编组对象,并且创建引用然后解组它的调用都成功了,在我看来,这似乎CoreWindow只是拒绝被编组。

当然,除非这是按预期工作并且RoGetAgileReference调用默默地无法编组CoreWindow.

那么是什么导致SetPointerCapture调用失败,即使使用agile_ref?

4

1 回答 1

1

该错误具有误导性。大多数 Windows.UI 类实际上是敏捷的。挑战在于它们执行显式线程检查以确保您实际上是从适当的 UI 线程调用它们。这就是为什么a Agile_ref 没有帮助的原因。解决方案是使用 Dispatcher,它可以让您进入正确的线程。然后,您可以直接在对象上简单地调用方法。

于 2018-06-08T23:24:34.183 回答