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)
      return;
   if (InvokeRequired)
      Invoke(new MapLoadedEventHandler(Instance_MapLoaded), new Object[] { sender, eStatus });
   else
   {
       //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.

Regards.