1

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

我在 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 类,然后尝试在工作线程的事件处理程序中调用它。在 Agile.cpp 中,它看起来像是在尝试获取代理,但由于 hresult REGDB_E_IIDNOTREG 接口未注册而失败。好像我很接近了;不知何故,我需要注册我的 C++/CX 类。在普通的 COM 中,我相信这将与全局接口表有关。不知道这对 C++/CX 是如何工作的.. 它不是自动的?

4

1 回答 1

1

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

Why not simply post a custom window message from your event handler to get back to the UI thread? Under the covers, that's all that CoreDispatcher is doing (it's also what COM does to get back to an STA window).

If you absolutely must get COM cross apartment marshaling working for your classes, you're going to have to register proxy/stub DLLs for all your interfaces. That means you need to use the WINMDIDL tool to generate an IDL file from the winmd file that's associated with your C++/CX component. You then need to run that IDL file through the MIDL tool with the /winrt command line switch. That will create a proxy/stub DLL, you can then register that proxy/stub DLL just like you'd register any other COM proxy/stub DLL.

于 2012-08-10T14:02:22.133 回答