2009-07-13 10 views
0

DLLに管理されていないコードがあります。私の呼び出し(マネージ)コードがいくつかのCOM通知にフックするために使用するいくつかのメソッドを公開しています。マネージコードを呼び出すアンマネージドコードを扱うのではなく、私はコントロールの派生オブジェクトを作成し、非マネージコードがSendMessageのパラメータとして使用するhandleプロパティを渡しています。 WinFormが作成直後以外のメッセージを受信しない

私のコントロールの派生クラス:

class InteropWindow : Control 
{ 
    //delegate 
    private Handler m_callback; 
    //window message 
    private uint m_message; 

    public InteropWindow(Handler callback, uint message) 
    : base() 
    { 
    m_callback = callback; 
    m_message = message; 
    } 

    protected override void WndProc(ref Message m) 
    { 
    if (m.Msg == m_message) 
    { 
     m_callback(new IntPtr((int)m.WParam)); 
    } 

    base.WndProc(ref m); 
    } 
} 

アンマネージコードに該当する行:

SendMessage(m_notify, m_window_message, (WPARAM)pData, 0); 

m_window_message & m_messageは(両方RegisterWindowMessageから)同一であり、そしてm_notify == InteropWindow.Handle(pDataを変更されますが、マネージコードでは不透明なハンドルとして使用されます)。アンマネージコードが呼び出されています。これらの事実はデバッグによって確認されています。

InteropWindowを作成した直後に、SendMessageの呼び出しが成功します。その後(秒後)、メッセージはWndProcに到達しなくなりますが、エラーの兆候はありません。

質問は、私はここで間違っていますか?


私は(とにかくの知る限りでは)ライフサイクルの問題を除外し、無駄にHandleRefでプレイしました。


秒を編集します。

代わりに関数呼び出しを使用するようにこれを書き直しました。これは、独自の危険を伴いながら、私が期待していたよりも少しうまく機能します。私はこれがCOMスレッドの問題であると疑うようになったが、それはちょうど腸の感覚である。

答えて

1

管理対象ウィンドウのハンドルをHandleRefとして渡してみましたか? C#はIntPtrとしてHandleRefをマーシャリングすることができますが、その逆もあります。私は、Microsoftがその一部を逆コンパイルするときにそのトリックをかなり使用するのを見ました。

.NetプロファイラをロードしてGCを監視することもできます。あなたのアプリがコレクトの直後に壊れているかどうかを知ることは良いことです。

+0

私はハンドルが有効であることを確認しました。少なくとも、それが今まで無効となったということは絶対にありません。 Control.HandleDestroyedの呼び出し、無効なハンドル警告の使用、どこにも最初のチャンス例外はありません。 –

+0

代わりにCOMオブジェクトでイベントを作成してみることができますか?私は管理された側の加入者であり、はるかに簡単な解決策かもしれません。しかし、どのようにCOM /アンマネージド側でイベントを作るのか分かりません。 – jonathanpeppers

関連する問題