Tech Off Post

Single Post Permalink

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

    Hi there.

    I really need help from someone who knows the ins and outs of Microsoft development. I am "porting" a .Net Winforms app written for Windows Mobile into WPF. This winforms app is actually a navigaion application, similar to tom-tom or Garmen navigation that we have come to know and love.  I have in my posession the WinForms app, plus the COM library it requires to do its work. The COM library is compiled to x86 if someone was wondering, I have both x86 and ARMv4 version of it. BUT I do not have the source code of the COM object.

    Ok so what do we have? Exceptions for Africa as usual:

    Unable to cast COM object of type 'NETSMMobile.SM3DDisplayTransformationClass' to interface type 'NETSMMobile.I3DDisplayTransformationSetup'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{8D724E8D-E00A-4700-9722-009901156857}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

    Now, this looks like a normal coding error, but SM3DDisplayTransformationClass implements I3DDisplayTransformationSetup. I have checked and double checked. So how can this happen then. Well, somehow WinForms' Invoke causes the "cast" to fail. I say "cast" because there is no real cast going on there. Anywais lets say there is a "cast", implicid maybe, the cast works "outside" of the invoke, but not inside. Here is the code I used to test this:

    private void Instance_MapLoaded(object sender, NETSMMobile.esriSMRendererLoadStatus eStatus)
       // Here I injected my little test line to cause an exception. The real exception actually happned in the else statement below.
       double d = MapObject.Instance.MapView.RotationAngle; //This line throws the exception but only if the method was called inside the Invoke below.  Look for MapView's explenation below.
       if (m_bDisposed)
       if (InvokeRequired)
          Invoke(new MapLoadedEventHandler(Instance_MapLoaded), new Object[] { sender, eStatus });
           //Where the exception actually fires, inside here somewhere.

    MapView implements IMapView that exposes the RotationAngle Property. The MapView implementation redirects the call to a COM interface object hosted inside MapView:

    class MapView : IMapView
       //Our COM interface
       private I3DDisplayTransformationSetup m_objTransformation;
       public double RotationAngle
          get{ return m_objTransformation.RotationAngle; }
    // Generated by Microsoft (R) .NET Framework Type Library to Assembly Converter 3.5.30729.1
    [TypeLibType( 2 )]
    [ClassInterface( 0 )]
    [Guid( "36FAAB60-7424-4DF6-8DB6-B9931DF3EB26" )]
    public class SM3DDisplayTransformationClass : SM3DDisplayTransformation, I3DDisplayTransformationSetup, IDisplayTransformation
       [DispId( 2 )]
       public virtual double RotationAngle { get; set; }
    [InterfaceType( 1 )]
    [Guid( "8D724E8D-E00A-4700-9722-009901156857" )]
    public interface I3DDisplayTransformationSetup
       [DispId( 2 )]
       double RotationAngle { get; set; }

    There, that should be enough to demonstrate the link to COM from that call that causes the exception. Now I have tried to guess things such as spamming [STAThread] and things like that but I am getting nowhere. I fear I have to little knowledge of COM and .Net->COM and to study these things might take 100 years, which I don’t have .

    To add, I have tested that I registered the COM object on my BOX. If I unregistered it the code would fail much earlier with proper error basically saying that the COM interface does not exist.

    I also tried referencing the COM object directly, same error.

    I also generated my own .NET assembly from the COM object using that tlbimp.exe, but  same results.

    One more thing, if you compile the original Forms project and deploy it to a Windows mobile device, it would work. So I fear the problem lies in the port, or differences between WinForms on Compact Framework and full .Net.

    Please help someone, anyone.