Tech Off Post

Single Post Permalink

View Thread: WPF + WindowsFormsHost + .Net Forms + ( COM interfaces + Forms Invoke ) = E_NOINTERFACE Exception
  • User profile image

    pompomJuice said:
    Dexter said:

    Thanks for that information.

    I have mailed the original authors of those COM objects for those questions.

    Also thanks for pointing out my miss interpretation of Dr. Dobbs. I also wondered about that, since he never mentions .Net in the article itself, only the heading. I think the heading might be wrong.

    All other research I did also pointed out that everything should just work. Oh well, kind of fixed that problem by removing them out of the invokes.

    Now the other error: I have checked it out for about 5 minutes. It looks less involved. There error seems to happen all on its own in one method call. Here it is:

    public void SetClientRect(Rectangle rcClient) // exception
       if (m_objClientEnvelope == null)
          m_objClientEnvelope = new SMEnvelopeClass(); // The COM object
      m_objClientEnvelope.XMin = rcClient.Left;// <---- EXCEPTION happens here on m_objClientEnvelope
      m_objClientEnvelope.XMax = rcClient.Right;
      m_objClientEnvelope.YMin = rcClient.Top;
      m_objClientEnvelope.YMax = rcClient.Bottom;
      ((IDisplayTransformation)m_objTransformation).ClientRect = m_objClientEnvelope; // exception
    //The interface generated by that Assembly generator
    [Guid( "C3D7F3E5-28D7-407F-BBED-CF8F2222BE35" )]
    [TypeLibType( 2 )]
    [ClassInterface( 0 )]
    public class SMEnvelopeClass : SMEnvelope, IEnvelope
       public SMEnvelopeClass();
      [DispId( 4 )]
      public virtual double XMax { get; set; }
      [DispId( 3 )]
      public virtual double XMin { get; set; }
      [DispId( 2 )]
      public virtual double YMax { get; set; }
      [DispId( 1 )]
      public virtual double YMin { get; set; }

    Ok so again I think its a threading problem because that method instantiates m_objClientEnvelope the first time it is called. I injected a thread id call there and it is clear that if the creating thread accesses that member it works, if the thread ID changes it fails with that error. I think its a different kind of error for the same problem, those threads are not part of the same apartment and the marshalling between the apartments ( or thread and apartment? ) is not working? I am guessing here, my COM knowledge is a day old. Baby steps.

    I think with the previous error I got lucky. A worker thread instantiated the COM object and used it inside that worker thread. Because I eliminated the other thread created by invoke I sidestepped that problem.

    The new error occurs because two worker threads ( that are essential to the program ) are trying to access the same COM object. This time trickery might not work. Sigh.... I am out of ideas here.

    With regards to your comment "So your component is either not registered correctly or it doesn't have a proxy at all." Basically what I did was regsvr32 smmobile.dll and tlbimp smmobile.dll /out:NETSMMobile.dll and referenced that NETSMMobile.dll in my devStudio. I read about that proxy/stub file and I have no idea if that information was "imbedded" within the COM object itself. But I don’t have that proxy dll file that they speak of.

    Thanks for the help.




    Ok I have fixed the errors. It seems that I needed to pay closer attention when fiddeling with STAThread and MTAThread attributes.

    The errors go away setting the creation/access threads to MTA, but ensuring all threads accessing the COM objects are MTA is tedious, as any events (OnMouseclick for instance) triggered from STA (Forms UI) required me to make worker threads that are MTA to do the work using COM interfaces. These MTA worker threads make calls to Form UI again so again more wrappers for invoke were required.

    So the original problem described at the top was caused by the fact that Control.Invoke spawned a STAThread, which  caused that E_NOINTERFACE error. Therefor the mistake was made by me, or the programmer not making sure that all COM access originated from MTAThread. The original implementation onto Windows CE Masked this problem as windows CE does not seem to have a problem with this.

    The port is compete, no exceptions, but the hackinng required to make it work must have broken something. Normal controls work fine but the map drawing failes for some reason. At least I understand the COM now.