1

ネイティブ デスクトップ アプリケーション (/ZW を使用しない) と、/ZW でビルドされた DLL があります。DLL は、ToastNotificationManager.

トースト クリックのイベントを受け取る DLL に C++/CX クラスがあります。これはすべて正常に機能します。ただし、イベントはワーカー スレッドで受信されます。どういうわけか、メインスレッドへの呼び出しを取得する必要があります。これを達成するための最良の方法は何ですか?

属性を設定してみました

[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 を除いて?

編集: Windows.UI.Core.CoreWindow.GetForCurrentThread() は、UI スレッドでクエリを実行すると null を返します。UI スレッドは MFC ベースです。

edit2: 私は Platform::Agile で遊んでいます。メイン スレッドに C++/CX クラスを指すアジャイル ポインターを設定し、ワーカー スレッドのイベント ハンドラーでそれを呼び出そうとします。agile.cpp では、プロキシを取得しようとしているように見えますが、hresult REGDB_E_IIDNOTREG Interface not registered で失敗します。私は近くにいるようです。どうにかして C++/CX クラスを登録する必要があります。プレーンな COM では、これはグローバル インターフェイス テーブルにあると思います。ただし、これが C++/CX でどのように機能するかはわかりません..自動ではありませんか?

4

1 に答える 1

1

デスクトップアプリケーションからCoreDispatcherを使用することはできません。これには、CoreWindowが必要であり、CoreWindowがデスクトップアプリケーションに対して有効になっていません。

イベントハンドラーからカスタムウィンドウメッセージを投稿して、UIスレッドに戻ってみませんか?裏では、CoreDispatcherが実行しているのはそれだけです(これは、COMがSTAウィンドウに戻るために実行することでもあります)。

どうしてもCOMクロスアパートメントマーシャリングをクラスで機能させる必要がある場合は、すべてのインターフェイスにプロキシ/スタブDLLを登録する必要があります。つまり、WINMDIDLツールを使用して、C ++/CXコンポーネントに関連付けられているwinmdファイルからIDLファイルを生成する必要があります。次に、/winrtコマンドラインスイッチを使用してMIDLツールからそのIDLファイルを実行する必要があります。これにより、プロキシ/スタブDLLが作成され、他のCOMプロキシ/スタブDLLを登録するのと同じように、そのプロキシ/スタブDLLを登録できます。

于 2012-08-10T14:02:22.133 に答える