需要手动调度才能将 WinRT Toast 事件获取到 UI 线程上



我有一个本机桌面应用程序(没有使用/ZW)和一个用/ZW构建的DLL。DLL 用于通过 ToastNotificationManager 创建 WinRT 吐司。

我在 DLL 中有一个 C++/CX 类,它接收 toast 单击的事件。这一切都工作正常;但是,事件在工作线程上传入。不知何故,我需要调用主线程。实现这一目标的最佳方法是什么?

我试过设置属性

[Threading(ThreadingModel::STA)]
[MarshalingBehavior(MarshalingType::Standard)]

对于我的 C++/CX 类,但仍然在工作线程上调用事件。我尝试在桌面应用程序中将[Platform::STAThread]添加到我的主方法中。我已经在应用程序开始时尝试了::RoInitialize(RO_INIT_SINGLETHREADED);

我在这里走错路了吗?我是否需要使用以下内容:

var dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher; // from UI thread
dispatcher.RunAsync // from worker thread?

除了C++/CX?

编辑:当我在我的UI线程上查询它时,Windows.UI.Core.CoreWindow.GetForCurrentThread()返回null。UI 线程基于 MFC。

edit2:我一直在玩Platform::Agile。我在主线程上设置了一个敏捷指针,指向我的 C++/CX 类,然后尝试在工作线程上的事件处理程序中调用它。在敏捷中.cpp它看起来像是试图获取代理,但失败了,REGDB_E_IIDNOTREG接口未注册。似乎我很接近;不知何故,我需要注册我的 C++/CX 课程。简而言之,我相信这将与全局接口表有关。不确定这对 C++/CX 是如何工作的。.这不是自动的吗?

您将无法从桌面应用程序使用 CoreDispatcher,它需要 CoreWindow,并且未为桌面应用程序启用 CoreWindow。

为什么不简单地从事件处理程序发布自定义窗口消息以返回到 UI 线程?在幕后,这就是CoreDispatcher所做的一切(这也是COM为返回STA窗口所做的)。

如果绝对必须让 COM 跨单元封送处理适用于您的类,则必须为所有接口注册代理/存根 DLL。这意味着您需要使用 WINMDIDL 工具从与 C++/CX 组件关联的 winmd 文件生成 IDL 文件。然后,需要使用/winrt 命令行开关通过 MIDL 工具运行该 IDL 文件。 这将创建一个代理/存根 DLL,然后您可以注册该代理/存根 DLL,就像注册任何其他 COM 代理/存根 DLL 一样。

最新更新