Core: support for MFC in WPF applications running on .NET Core 3.0

Created on 31 Oct 2018  ·  20Comments  ·  Source: dotnet/core

We have some very large WPF applications that still use quite a lot of MFC through C++/CLI and mixed mode assemblies. Since .NET Core 3.0 will support mixed mode assemblies, it would be great if this scenario is also officially supported in 3.0

Are you planning to support this in 3.0?

area-wpf needs-more-info

Most helpful comment

.NET Core 3.0 will support C++/CLI on Windows. I don't know much about MFC or how that interacts though.

All 20 comments

@richlander @leecow @vivmishra do we have official details on our planned C++/CLI support in .NET Core 3.0?

.NET Core 3.0 will support C++/CLI on Windows. I don't know much about MFC or how that interacts though.

@diverdan92 @fabiant3 any insights about MFC support in WPF?

@jeffschwMSFT - do you know?

I am not aware of any explicit product decision around MFC usage. @bitbonk can you share a sample of what you have been doing on .NET Framework WPF + MFC? We can take a look. If it is WIndows only and C++/CLI I would expect it would align with our C++/CLI work.

@morganbr Is it official statement ?
I didn't see any blogpost about this

C++/CLI is official. MFC support depends on what is expected.

@karelz
Does that mean it will be possible to use .NET standard and .NET core assemblies from C++/CLI? It would bei awesome to use libraries like Microsoft.Extensions.Logging in our C++/CLI code!

It means that C++/CLI assemblies (targeting .NET Core) will be able to run on .NET Core.

I can't share the whole application because it is too big, but this is basically what we do:

Our root applications are (have now become) regular C# WPF application projects. In System.Windows.Application.OnStartup we call into a mixed mode (C++/CLI) assembly to initialize MFC (using a ref class MfcInitializer).

_MyApp.cpp in the mixed mode assembly_:

// static instance, with is declared as follows:
// class _declspec(dllexport) CMyApp : public CWinAppEx
CMyApp* myApp;

public ref class MfcInitializer
{
public:
    static bool Initialize()
    {
        myApp = new CMyApp();        
        ComponentDispatcher::ThreadFilterMessage += gcnew System::Windows::Interop::ThreadMessageEventHandler(&MfcInitializer::OnThreadFilterMessage);
        ComponentDispatcher::ThreadIdle += gcnew System::EventHandler(&MfcInitializer::OnThreadIdle);
        return theApp->InitInstance() != 0;
    }

    static void Exit()
    {
        myApp->ExitInstance();
        ComponentDispatcher::ThreadFilterMessage -= gcnew System::Windows::Interop::ThreadMessageEventHandler(&MfcInitializer::OnThreadFilterMessage);
        ComponentDispatcher::ThreadIdle -= gcnew System::EventHandler(&MfcInitializer::OnThreadIdle);
    }

    static void OnThreadFilterMessage(System::Windows::Interop::MSG %msg, bool %handled)
    {
        ::MSG m;
        m.message = msg.message;
        m.hwnd = (HWND)msg.hwnd.ToPointer();
        m.wParam = (WPARAM)msg.wParam.ToPointer();
        m.lParam = (LPARAM)msg.lParam.ToPointer();
        m.pt.x = msg.pt_x;
        m.pt.y = msg.pt_y;
        m.time = msg.time;
        handled = ::AfxPreTranslateMessage(&m) != 0 ? true : false;
    }

    static void OnThreadIdle(Object^, EventArgs^)
    {
        LONG lIdle = 0;
        while (AfxGetApp()->OnIdle(lIdle++))
        {
        }
    }
}

Our application has an extensibility model for MFC/C++ developers. They can write purely unmanaged MFC dlls that get loaded by us using LoadLibraryEx. The extensibility APIs are declared in a header file we deploy. This header file is also the place where class _declspec(dllexport) CMyApp : public CWinAppEx is declared. Extension authors can derive from a special plugin class that is declared as_declspec(dllexport). At runtime we load (LoadLibraryEx) an instantiate those classes.

The native MFC content is wrapped in a System.Windows.Forms.Integration.WindowsFormsHost which is then wrapped in a System.Windows.Forms.Integration.ElementHost which is then dispayed in a WPF panel.

Any update on this? I suppose at some point before the release of 3.0 you'd need to make a somewhat official statement. I would guess that the integration of MFC into WPF and WinForms Apps was one main things C++/CLI was used for. cc @onovotny

Our C++/CLI support is coming along. We hope to have it in an upcoming preview. There are a number of moving parts with the compilers/libraries shipping in an upcoming VS 2019 release and the runtime support coming in an upcoming .NET Core 3.0 Preview. I do not have a firm date at this point, though all seems on track for a .NET Core 3.0 ship.

@jeffschwMSFT
C++/CLI support is one thing and it is great to know that it is coming along. But what about the MFC support (which this issue is about)?

The developer in me kind of hopes that MFC will not be supported (so I have arguments to get rid of the old stuff) but my boss may think differently. 🤷🏻‍♂️

Adding @cmckinsey

Still no mention of MFC anywhere.

Maybe clarify what support you are asking for? MFC is C++/win32 and has nothing to do with .NET - neither Core nor Desktop - so there's no mention of MFC anywhere because there's nothing needing mentioning. MFC is doing its own thing and you can use the general purpose .NET Core / WinAPI interop, but there's nothing MFC specific required or available.

The closest I can think of is the ActiveX API which is not MFC specific but which is probably still supported by WinForms. I don't think they are actively testing it, so if you have scenarios which need ActiveX WinForms interop to host MFC then this probably needs to be discussed/resolved in the WinForms repo.

I though I already did clarify what I meant to great extend. What‘s missing?

What you described is general purpose interop and not related to MFC? Thats why its not mentioned anywhere. What I'm asking is what MFC specific support are you expecting? C++/CLI already has been confirmed and the rest is just plain old win32 general purpose interop which still is present in WPF and WinForms mostly

If you have specific scenarios you need to work regarding WPF or WinForms you'll probably be better off presenting them to the corresponding repositories (WinForms gets a lot of attention, WPF not so much, but from what I've gathered WPF is mostly staying as it was, the only major thing being removed is being hosted in a browser)

This issue has been automatically closed due to no response from the original author. Please feel free to reopen it if you have more information that can help us investigate the issue further.

Was this page helpful?
0 / 5 - 0 ratings