SimConnect and WPF

I’ve noticed some folks having problems using SimConnect with WPF based apps because there’s no easily accessed hWnd and no easily overridden DefWndProc.  Here’s a solution that works around those problems and is also usable in WinForms apps if you like.

In the existing managed samples provided in the SDK, the 2nd param of the new SimConnect(…) line is the hWnd and the 3rd param is the WM_Xxx based message to send to the main window.  For this solution, we will instead pass 0 for both of those params and pass an AutoReset EventWaitHandle object as the 4th param to that call.  Then we will create a background thread that waits for this event to fire and then calls the ReceiveMessage function to handle data received from SimConnect.

Here’s a couple of code snippets:

This first snippet shows the data used:

// data
Microsoft.ESP.SimConnect.SimConnect sc;
System.Threading.EventWaitHandle scReady = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset);
System.Threading.Thread bgThread = null;
public delegate void MyDelegate();

And this next snippet shows the code that uses these data items:

// code
private void ConnectToSimConnect(void)
{
    sc = new Microsoft.ESP.SimConnect.SimConnect("VE_SC_WPF", (IntPtr)0, 0, scReady, 0);
 
    bgThread = new System.Threading.Thread(new System.Threading.ThreadStart(scMessageThread));
    bgThread.IsBackground = true;
    bgThread.Start();
}
 
private void scMessageThread()
{
    while (true)
    {
        scReady.WaitOne();
        this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new MyDelegate(scMessageProcess));
    }
}
 
private void scMessageProcess()
{
    sc.ReceiveMessage();
}

With the code above, all of the OnRecvXxx callbacks will still happen on the UI thread context, meaning the rest of your code can stay the same as it was when using the hWnd and WM_Xxx message with an overridden DefWndProc. 

If you would prefer that the message handling and the OnRecvXxx callbacks occur on the background thread context, you can do that with this code snippet instead:

// code
private void ConnectToSimConnect(void)
{
    sc = new Microsoft.ESP.SimConnect.SimConnect("VE_SC_WPF", (IntPtr)0, 0, scReady, 0);
 
    bgThread = new System.Threading.Thread(new System.Threading.ThreadStart(scMessageThread));
    bgThread.IsBackground = true;
    bgThread.Start();
}
 
private void scMessageThread()
{
    while (true)
    {
        scReady.WaitOne();
        sc.ReceiveMessage();
    }
}

Doing things this way will require you to handle any thread synchronization that might be required to access any UI elements within each OnRecvXxx callback, but if you aren’t accessing UI elements much in your callbacks, then the 2nd way might be more efficient overall, but will require more work on your part to insure things happen on the correct thread.

I’ve been playing around with WPF for the last couple of weeks and its a lot of fun and can do some really cool things (repeat after me, DataTemplates are your friend :-> ).  Hopefully the above code snippets will let folks out there write some cool WPF based SimConnect clients.

Tim "Beatle" Gregson

Advertisements

7 Comments on “SimConnect and WPF”

  1. Fabio says:

    Hi,thanks for all info about WPF and simconnect. I try to use WPF as a dialog inside FSX. But there are some issue about WPF rendering and FSX . Are you informed in that way? Is there a workaround?ThanksFabio Merlo

  2. Beatle's says:

    You have to be doing some serious hacking to even get a managed assembly to run inside of FSX, which is not something that is supported at all.  We tell folks to limit what they do with regular standard windows API style windows as GDI and DirectX occasionally have interoperability issues (which is why the screen is blacked out while showing most of our dialogs).  With WPF, that\’s a DirectX 3D based rendering environment and so is FSX (obviously), so I would expect nothing but trouble trying to get the two of those to play nicely together within the same process space.
     
    If you want your addon to have a "heavy" UI, I would suggest writting it as an external SimConnect based addon, which also has the added benefit that it can be run on a seperate networked computer.

  3. Fabio says:

    Tanks for explained me the situation. i try to write my addon as an external SimConnect based addon with fsx menu item with small option in a standard dialog based GDI window.
     
    Thanks
     
    Fabio Merlo

  4. Unknown says:

    I\’ve spent the last few weeks to get managed code running inside FSX, using a similar approach as SQL Server to stop the managed code from eating up all unmanaged memory.
     
    If possible, my FSX addon should run as a standalone application side by side to FSX, but for those users who used to run FSNavigator inside FS9 in full screen mode with just one screen, I want my stuff to run inside FSX as well. So far, it seems to work quite well, even with "heavy" UI using classic UI Windows.Forms. Even WPF seems to work, but so far I have only tried very simple WPF forms.
     
    Anyway, in my FSX/.NET adapter code, the managed code\’s UI thread is FSX\’s UI thread, so I do the SimConnect receiving in a background thread, like you described above. That seems to works fine.
     
    However, when I try to receive SimConnect stuff in the UI thread, it crashes badly. Most likely not just because I am to dumb to cast the required magic spells, but because SimConnect expects that the sending thread in FSX and the receiving thread elsewhere are not the same thread ? In other words, I assume that FSX\’s UI thread is the thread that sends SimConnect stuff ? Or am I just not trying hard enough .. ;-P
     
    I understand that in FSX, managed code for modules/dlls is not supported, but I hope in FS 11 it will be supported.
     
    Thanks
    Martin
     


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s