問題タブ [iconnectionpoint]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
286 参照

c# - モーダル WinForms 経由で呼び出された C++ から IConnectionPointImpl インターフェイスを呼び出す際の問題

COM 経由でさまざまなタイプの VBA マクロをサポートするネイティブ C++ アプリケーションがあります。これらの型の 1 つである はVBAExtension、それ自体をコア C++ アプリケーションに登録し、 (から派生したクラス) のインスタンスになりますIConnectionPointImpl<Extension, &DIID_IExtensionEvents, CComDynamicUnkArray>。これは正常に機能します。適切な VBAExtension オブジェクトがあれば、コア マクロとその他の VBA マクロの両方が IExtensionEvents のメソッドにアクセスできます。

また、実行時にコア アプリケーションに読み込まれる .NET アセンブリ (C# で記述) もあります。歴史的な理由から、アセンブリは自動実行 VBA マクロによって読み込まれます。次に、ユーザーが特定のボタンを押すと、別の VBA マクロがアセンブリのメイン エントリ ポイントを実行し、System.Windows.Formsさらに対話するためのダイアログが表示されます。

それがセットアップです。VBAExtension.NET アセンブリ内からメソッドにアクセスすると、奇妙な動作が見られます。具体的には、アセンブリ内のさまざまな場所から次のコードを実行しています。

アセンブリのメイン オブジェクトのコンストラクターから実行すると、または、アセンブリのメイン エントリ ポイント (ダイアログが表示される前) から、すべて問題ありません。 の名前がVBAExtension出力されます。

ただし、アセンブリの (モーダル- 呼び出しているform.ShowDialog()) WinForm のボタンによって開始されたコマンドから同じコードを実行すると、ve.Names はすべて空白になります。サブクラスによるpDispatch->Invoke呼び出しはIConnectionPointImpl成功しますが (S_OK を返します)、戻り変数は設定されません。

ダイアログを非モーダル(で呼び出すform.Show()) に変更すると、名前が再び機能します。フォームのモダリティ (モーダルネス?) は、IConnectionPointImpl呼び出しが成功するかどうかに影響するようです。

何が起こっているか知っている人はいますか?

編集:最初の投稿以来、重要なのは呼び出しスタックではないことを実証しました。代わりに、呼び出しがモーダル ダイアログから行われたかどうかです。本文を更新しました。

編集 2: Hans Passant の回答によると、彼の診断上の質問に対する回答は次のとおりです。

  • 予想どおり、良い (モードレス) ケースでは、VBA イベント ハンドラの名前を変更してもエラーは発生しません。この呼び出しは単にデータを返しません。
  • MsgBox 呼び出しを VBA ハンドラに入れました。モードレスの場合は表示されますが、モーダルの場合は表示されません。したがって、ハンドラはモーダル ケースでは実行されません。
  • を使用するとErr、VBA ハンドラで例外が発生した場合に VBA エラー ダイアログが表示されることがわかります。それをクリアすると、C++Invoke呼び出しにはリターン コードとして 0x80020009 (「例外が発生しました」) が含まれ、pExcepInfo には一般的なエラー値が入力されます (VBA は実際の詳細を飲み込みました)。
  • このイベントは、最初のダイアログの直後、または C# アドインの 2 回目の呼び出し中に、モーダル ダイアログの 2 番目の表示では発生しません。

次のステップとして、メッセージ ループを掘り下げてみます。