views:

70

answers:

1

I've got some unmanaged code sitting in a DLL. It publishes some methods that my calling (managed) code uses to hook into some COM notifications. Rather than deal with unmanaged code calling back into managed code, I've created a hidden Control derived object and am passing its handle property which the unmanaged code then uses as a parameter to SendMessage.

My Control derived class:

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);
  }
}

Relevant line in unmanaged code:

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

m_window_message & m_message are the same (both from RegisterWindowMessage), and m_notify == InteropWindow.Handle (pData varies, but is used as an opaque handle in the managed code). The unmanaged code is being invoked. These facts have been confirmed via debugging.

Shortly after I create the InteropWindow, the calls to SendMessage succeed. Afterwards (seconds later) the messages stop getting to WndProc, though there is no indication of any error.

The question is, what am I doing wrong here?


I've ruled out lifecycle issues (to the best of knowledge anyway), and played with HandleRef to no avail.


Edit the second.

I've re-written this to use function calls instead, which while fraught with its own perils, works a bit more like I'd expect. I've come to suspect this is a COM threading issue, but that's just a gut feeling.

+1  A: 

Did you try passing your managed window's handle as a HandleRef? C# can marshal a HandleRef as an IntPtr and vice versa, I've seen Microsoft use that trick quite a bit when decompiling some of their stuff.

You can also load up a .Net profiler and watch the GC. It would be nice to know if your app is breaking right after a collect.

Jonathan.Peppers
I've confirmed the handle stays valid through GCs; or, at the very least, there's absolutely no indication that it becomes invalid ever. No invocation of Control.HandleDestroyed, no invalid handle warnings on use, no first chance exceptions anywhere, no nothing.
Kevin Montrose
Could you instead try making an event on your COM object? I've been the subscriber on the managed side and it might be a much simpler solution. I am not sure how make the event on the COM/unmanaged side, however.
Jonathan.Peppers