Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance issue when hosting a WPF form in a native C++ application

I have WPF window which runs fine when hosted in a WPF application but when I load it from within my native C++ application it takes a very long time to render and the UI Thread blocks until it completes.

The main offender on my window is an series of items controls used to display a 9 by 12 grid of icons which represent states of components within my system.

The whole items control takes up to 14 seconds for its initial render. (This is almost instant when running in a WPF app)

Each line has a text header that when clicked displays a small summary of data (max, min, mean, std dev) for each of the status icons. clicking this header can take up to 4 seconds to render the summary but is instant in my WPF app.

Are there any known tricks for making WPF perform nicely within a native application?

[Edit]

I have just tried launching it from a large .NET windows forms application using the following code:

    public bool? ShowWpfDialog(System.Windows.Window window, Form owner)
    {
        var helper = new System.Windows.Interop.WindowInteropHelper(window)
                         {Owner = (owner == null) ? IntPtr.Zero : owner.Handle};
        return window.ShowDialog();
    }

I have the same performance issues as when running from the native app. (the .net app also runs native code.)

[Edit]

When I don't use the WindowInteropHelper the code performs properly:

    public bool? ShowWpfDialog(System.Windows.Window window, Form owner)
    {
        //var helper = new System.Windows.Interop.WindowInteropHelper(window)
        //                 {Owner = (owner == null) ? IntPtr.Zero : owner.Handle};
        return window.ShowDialog();
    }

What is the WindowInteropHelper doing that would cause a performance issue?

[Edit]

Could there be an issue with the way resources are resolved when I load it with an owner using the WindowInteropHelper?

like image 301
ghnz Avatar asked Jan 22 '13 19:01

ghnz


2 Answers

The docs for WindowInteropHelper indicate that you should set the HELPER'S handle to your c++ handle

WindowInteropHelper wih = new WindowInteropHelper(myDialog);
wih.Owner = ownerHwnd;
myDialog.ShowDialog();

But you seem to be doing the opposite.

like image 79
Alex Russell Avatar answered Oct 13 '22 00:10

Alex Russell


Nowhere in your post do you mention HwndSource or HwndHost which are the supported means of interoping between native code (either hosting WPF in Win32 or visa versa). WindowsInteropHelper is not intended to support full blown interop scenarios, it's only use is to basically get the Handle of a WPF Window.

These are a great series of articles and I recommend looking through them, because what you want to do is not going to be trivial unless it's a very limited scope.

like image 45
Greg B Avatar answered Oct 12 '22 23:10

Greg B