简体   繁体   中英

Is it possible to use CWinFormsControl/AfxWinForms.h in a C++/CLI project targeting net6.0-windows and how?

We have a fairly large solution containing a mix of C++/CLI and C# projects using MFC and Winforms controls to build the UI. Several MFC dialogs in the app make use of a CWinFormsControl from afxwinforms.h to embed WinForms controls inside them, currently everything targets .NET48 and works fine. We are trying to update everything to .NET6.0 and everything seems OK except the one project that includes afxwinforms.h.

The project settings are:
Common Language Runtime Support: .NET Core Runtime Support(/clr:netcore)
.NET Core Target Framework: net6.0-windows (I have tried just net6.0, net5.0...)
Platform Toolset: Visual Studio 2022 (v143)

We include <afxwinforms.h> amongst several other afx includes in a precompiled header and the compiler gives this error building our stdafx.h:

C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.h(30,8): fatal error C1107: could not find assembly 'System.Windows.Forms.dll': please specify the assembly search path using /AI or by setting the LIBPATH environment variable

From some searching on the internet I found and attempted to pass the following directories using the Additional #using Directories property of the project:
C:\Program Files (x86)\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.0\
C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\
C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.0\

Any of those paths seems to sort out the above compiler error, and intellisense seems to recognise everything in afxwinforms.h too. However, the compiler starts giving warnings such as:

C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um\objidl.h(9724): message : see declaration of 'IPersist'
C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um\objidl.h(11125): message : see declaration of 'IPersistStorage'
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32): message : This diagnostic occurred while importing type 'System::Windows::Forms::Control ' from assembly 'System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32,3): warning C4691: 'IQuickActivate': type referenced was expected in unreferenced module 'System.Windows.Forms.Primitives', type defined in current translation unit used instead
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32,3): message : This diagnostic occurred while importing type 'System::Windows::Forms::Control ' from assembly 'System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32,3): warning C4691: 'IOleInPlaceUIWindow': type referenced was expected in unreferenced module 'System.Windows.Forms.Primitives', type defined in current translation unit used instead
C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32,3): message : This diagnostic occurred while importing type 'System::Windows::Forms::Control ' from assembly 'System.Windows.Forms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

before giving this error:

C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.30.30705\atlmfc\include\afxwinforms.inl(32,3): fatal error C1001: Internal compiler error. (compiler file 'd:\a01_work\20\s\src\vctools\Compiler\CxxFE\sl\p1\c\cpimport.cpp', line 12502) To work around this problem, try simplifying or changing the program near the locations listed above.

So, my main questions are:
Is it possible to do this, can I embed a WinForms control in an MFC dialog using a CWinFormsControl in .NET6.0?
If it is possible, where am I going wrong causing the problems above?
If it isn't possible, is there an alternative way to do something like this: (trimmed down sample)

//C#
public class MyUserControl : System.Windows.Forms.UserControl
{

}

//C++
#include <afxwinforms.h>
class MyWnd : public CWnd
{
public:
    CWinFormsControl<MyUserControl> mMyControl;

    int OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        auto rc = __super::OnCreate(lpCreateStruct);
        if (rc >= 0)
        {
            CRect rcChild(0, 0, lpCreateStruct->cx, lpCreateStruct->cy);
            m_optionsControl.CreateManagedControl(WS_CHILD | WS_VISIBLE, rcChild, this, 1);
        }
        return rc;
    }
};

I can reproduce this in a quick, small sample.
In Visual Studio 2022 create a new project, CLR Empty Project (.NET)
Add a header and source file, include the header from the source. #include <afxwinforms.h> to the header file.
Project->Properties->Configuration Properties->Advanced:
Use of MFC: Use MFC in a shared DLL
Common Language Runtime Support: (should already be) .NET Core Runtime Support (/clr:netcore)
.NET Core Target Framework: (should already be) net6.0

Build the project, you should get an error about not being able to find the System.Windows.Forms.dll.

Project->properties->Configuration Properties -> C/C++ -> General: Additional #using Directories:
C:\Program Files (x86)\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.0\ OR
C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.0\ref\net6.0\ OR
C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.0<br />

Build again, you should get the internal compiler error.

i was trying to solve the same issue. From the code inside mfc its clear they only support .net framework for now.

What worked for me was to make a copy of the afxwinforms.h and .inl plus some files from "C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.32.31114\atlmfc\src\mfcm" into my project directly so it stops linking into the microsoft mfcmXXX.lib and just adjusted the files slightly to get it to compile.

Here is how I fix it:

  1. Use Visual Studio 2022, in project.vcxproj, add this reference:
    <ItemGroup><FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" /></ItemGroup>
  1. Then, you will see "System.Windows.Forms.dll" in "External Dependencies" of Solution Explorer. Look at the properties for this dll, which is under: C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.7\ref\net6.0\System.Windows.dll
  2. open project's property, Configuration Properties -> C/C++ -> General -> Additional #Using Directories, add the folder's full path there. enter image description here (I just use net6.0, not net6.0-window)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM