在 C++/WinRT UI 线程上构建 Xaml 控件
Constructing Xaml controls on C++/WinRT UI thread
我不确定我做错了什么,但即使我肯定在 UI 线程上,我在构建 'The application called an interface that was marshalled for a different thread.' 时始终收到错误“'The application called an interface that was marshalled for a different thread.'” =42=] C++ 中的控件。
请参阅以下基本示例,它使用默认 C++/WinRT CoreApplication 模板的简化版本:
#include "pch.h"
using namespace winrt;
using namespace Windows;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;
using namespace Windows::ApplicationModel::Activation;
struct App : implements<App, IFrameworkViewSource, IFrameworkView> {
CompositionTarget m_target{nullptr};
IFrameworkView CreateView() { return *this; }
void Initialize(CoreApplicationView const &) {}
void Load(hstring const &) {}
void Uninitialize() {}
void Run() {
CoreWindow window = CoreWindow::GetForCurrentThread();
winrt::Windows::UI::Xaml::Controls::TextBox textbox; // Crashes here
CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
void SetWindow(CoreWindow const &) {
Compositor compositor;
ContainerVisual root = compositor.CreateContainerVisual();
m_target = compositor.CreateTargetForCurrentView();
m_target.Root(root);
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { CoreApplication::Run(make<App>()); }
我已经尝试使用 window.Dispatcher().HasThreadAccess()
来验证我是否在正确的线程上进行 UI 调用,并且它总是 returns true
。
我还尝试从 window 的 Dispatcher
调用 RunAsync()
并在传递给此方法的 lambda 中构造一个 Xaml 对象,它仍然有完全相同的结果。 HasThreadAccess
returns true
这里也是
任何人都可以向我解释我哪里出错了吗? C++ 不支持构造 Xaml 对象吗?
[编辑]
这是一个重现问题的示例项目,同样基于默认的 CoreWindow C++/WinRT 模板:
事实证明,基于 CoreApplication 的模板不支持 Xaml 命名空间中的任何内容,因为它更倾向于为游戏等提供薄 UWP 层。
要获得 Xaml 支持,您需要使用完整模板,然后事情就会神奇地开始起作用。
我不确定我做错了什么,但即使我肯定在 UI 线程上,我在构建 'The application called an interface that was marshalled for a different thread.' 时始终收到错误“'The application called an interface that was marshalled for a different thread.'” =42=] C++ 中的控件。
请参阅以下基本示例,它使用默认 C++/WinRT CoreApplication 模板的简化版本:
#include "pch.h"
using namespace winrt;
using namespace Windows;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;
using namespace Windows::ApplicationModel::Activation;
struct App : implements<App, IFrameworkViewSource, IFrameworkView> {
CompositionTarget m_target{nullptr};
IFrameworkView CreateView() { return *this; }
void Initialize(CoreApplicationView const &) {}
void Load(hstring const &) {}
void Uninitialize() {}
void Run() {
CoreWindow window = CoreWindow::GetForCurrentThread();
winrt::Windows::UI::Xaml::Controls::TextBox textbox; // Crashes here
CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
void SetWindow(CoreWindow const &) {
Compositor compositor;
ContainerVisual root = compositor.CreateContainerVisual();
m_target = compositor.CreateTargetForCurrentView();
m_target.Root(root);
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { CoreApplication::Run(make<App>()); }
我已经尝试使用 window.Dispatcher().HasThreadAccess()
来验证我是否在正确的线程上进行 UI 调用,并且它总是 returns true
。
我还尝试从 window 的 Dispatcher
调用 RunAsync()
并在传递给此方法的 lambda 中构造一个 Xaml 对象,它仍然有完全相同的结果。 HasThreadAccess
returns true
这里也是
任何人都可以向我解释我哪里出错了吗? C++ 不支持构造 Xaml 对象吗?
[编辑]
这是一个重现问题的示例项目,同样基于默认的 CoreWindow C++/WinRT 模板:
事实证明,基于 CoreApplication 的模板不支持 Xaml 命名空间中的任何内容,因为它更倾向于为游戏等提供薄 UWP 层。
要获得 Xaml 支持,您需要使用完整模板,然后事情就会神奇地开始起作用。