MfcAdapter

Articles about MfcAdapter:

Why do we need to embed MFC application in .NET application?

First of all, we have to describe existing MFC based applications. MFC was one of the first C ++ libraries for support of completed GUI Framework development. A lot of MFC applications have been developed at the last 10 years. The main problems of these applications: too expensive support and bad integration with other apps. The main reason of these problems is not component, strongly typified, closed architecture of MFC.

Unlike MFC - .Net Framework provides the infrastructure required to open architecture, component  development. But the problem is, that the migration of the MFC application in a .NET application is too expensive.

Besides it is necessary to distinguish between migration MFC --> WinForms and migration MFC --> WPF. By MFC --> WPF migration you receive a new powerful graphic library and an opportunity it is essential to change graphic functionality that can be very important for graphic applications. By MFC --> WinForms migration you have "same" Controls and GDI as in MFC. So the MFC --> WinForms migration may be is not so satisfied.

As an alternate to the migration scenario, Microsoft offers some interoperation solutions (in an interoperation scenario, you don't try to turn the MFC code into .NET automatically, you just try to insure that they can work together):  

The first technology allows to host the MFC control only. ("If your Win32 logic is already packaged up nicely as a control...") You can turn a dialog into a control with some efforts - but not the larger MFC MDI application.

The MFC Windows Forms support classes allow the backwards integration of the .NET code in an MFC application. It lets you arrange .NET Forms as Views or Dialogs. There are some important limitations in this case: the .NET Framework can not be integrated (the old MFC framework has to be used), the part of the integrated Forms functionality is not available (for example, laying out), and a separate control can be integrated as a Form only (for example, the .NET MenuStrip can not be used in the MFC Framework). I find that these kinds of interoperation solutions are pure alternates to the migration scenario, and I haven't found real examples of these solutions in the Internet.

 MfcAdapter provides the build old MFC MDI application in an existing .NET application or rapidly create a new WinForms/WPF GUI framework for it. After this, you can gradually migrate from the old MFC dialogs and views to the new WinForms and then to the WPF UI elements. Such an alternative Microsoft, intermediate integration of MFC and WinForms might seem to be more expedient for larger MFC MDI projects in comparison with a complete migration into .NET.

From the technical point of view, a mixed MFC DLL with a CWinApp-derived class, the hosting of MFC views in WinForms controls and in WPF FrameworkElement, and the support of the WPF auto-layout in hosted views used in MfcAdapter, are not discussed on the Internet.
 

Architecture of MfcAdapter v 2.1

The main idea of the MfcAdapter architecture is to make MfcAdapter fully independent from an actual MFC application:

 

The low level .NET component in the described architecture is a Mixed (managed/unmanaged) Dll with a MFC application and the managed class ModuleState inside. The ModuleState is a managed pointer to unmanaged AFX_MODULE_STATE of the MFC application. With static method ModuleState.GetModuleState() the MfcAdapter or other C++/CLI component can load AFX_MODULE_STATE from necessary Mixed Dll. After this, MfcAdapter can switch to this AFX_MODULE_STATE and use the unmanaged API of the hosted MFC application. Additionally, the Mixed MFC Dll provides managed equivalents to CommandIDs which can be processed in the MFC application.

The mid-level component's MfcAppAdapter, ViewCtrl and ViewFrameworkElemen are wrappers to the unmanaged MFC application. These components combine into MfcAdapter. MfcAppAdapter is responsible for the initialization/termination of the encapsulated MFC application, the command interface to the application and the document opening. The MFC View created in hosted MFC application can be found with method MfcAppAdapter.GetCreatedView() and be hosted in ViewCtrl (WinForms) or ViewFrameworkElement(WPF). Mid-level component's are not dependant on the actual MFC application or on the actual .Net/WPF framework.

Some methods of ViewCtrl and ViewFrameworkElemen like LegacyViewWndProc and  LegacyPreTranslateMessage can be used in overridden methods of  ViewCtrl and ViewFrameworkElemen to customize the message handling. With this customizing you can fine split the message processing between control and hosted application.    

The MfcAdapter supports different type of  MFC applications -SDI/MDI/Dialog based/Multiple top-level documents.

The high level component is WinForms (FormsDemo) or WPF (WPFDemo) application. This application supports:

  • Simply layout of hosted Controls (FormsDemo) or hosted FrameworkElemens (WPFDemo)
  • UpdateUI and event handling of the ToolStrip (FormsDemo) or ToolBar (WPFDemo) in hosted MFC applications.

How to convert your MFC application to mix dll

Before the using of MfcAdapter you have to convert your MFC Application to a mixed MFC dll. As a rule, the MFC class based application architecture is strongly typed. A lot of classes, for example, the MDI classes CDocument,CView, CFrameWnd, and others cannot be used without the CWinApp (application) class and a complicated initialization. The simple solution in this case is to put the full application in a DLL and to mix with the managed C++ class ModuleState. We can use this class as the managed interface between the WinForms framework and the MFC application.

1. To provide normally unmanaged and managed initializations of mixed MFC dll use special project settings:

Configuration Typee Dynamic Library (.dll)
Character Set Use Unicode Character Set
Use Managed Extensions No
Output File .dll

Update options which come against the compiler option /clr for the project configuration file and for other source files:

Basic Runtime Checks Default
Enable Minimal Rebuild No
Enable C++ Exceptions With SHE Exceptions (/EHa)
Debug Information Format Program Database (/Zi)
Create/Use Precompiled Headers Not Using Precompiled Headers
Entry Point  

2. Add MfcCommand.cpp with ModuleState class to the project and set for this file "Common Language Runtime Support (/clr)". Other project classes are unmanaged and have to have "No Common Language Runtime support" setting!!!

3. Add "Additional Include Directories" - "%MfcAdapter%\include" , %MfcAdapter% is MfcAdapter install directory.

4. Resolve a linker problem - the LNK2005 error. Add macro AFX_MANAGE_STATE (AfxGetStaticModuleState()) to the static constructor or at the beginning of InitInstance. Now MFC application can be compiled as mixed MFC dll.

5. Before the using mixed MFC dll with MfcAdapter you have to make some changes:

  • Keep an invisible CMainFrame and a created CView and  modal properties of the hosted dialogs.

    You have to remove the creation of the main window from InitInstance to the new AttachApplication method and create the MFC MainFrame window as child of Framework MainForm window (override CMainFrame::PreCreateWindow). The view's content has to be invisible when creating and initializing. It would be activated only after attaching to the WinForms control. In the source code, set bMakeVisibleparameter to false in the overridden MultiDocTemplate::OpenDocumentFile, and CMainFrame::OnWindowNew. Don't use CView::OnCreate. Creating and initializing of our view class' members inherited from CWnd, Control, DropTarget.Register, ToolTip, and so on, should be removed from the OnCreate method to the OnInitialUpdate. In this case, these members will be created after the view is attached to the WinForms control. Add new DetachApplication method and override CMainFrame::OnClose and CMainFrame::OnDestroy to close main window by exit application. The normal close scenario occurs when a client calls dispose on the MfcAppAdapter and closes the legacy MFC application before the WinForms Framework MainForm is closed. Use the CNotifyHook in the MFC MainFrame for support modal MFC dialogs in external framework.

  • Auto-layout support.

    You have to implement some methods from CLayoutView class in your hosted view: SetPrefferedSize(), GetPreferredSize(), and Scale().

You can simply find all changes in samples project. All changes begin with comment //******AS update start********

Build prerequisites

All samples use $MfcAdapter variable in build scripts. Setup will set this variable with install directory of MfcAdapter in system environment of your PC (MfcAdapter=C:\Program Files\AS\MfcAdapter" in default case).

 

Because the MfcAdapter uses MFC library, you have to avoid mix Debug and Release version and mix VS2005 and VS2008 version of MfcAdapter assemblies. Simply copy necessary Debug or Release assemblies by Post Build Event. (See example of script in samples project settings: copy "$(MfcAdapter)\$(ConfigurationName)\MfcAppAdapter.dll" "$(TargetDir)MfcAppAdapter.dll").

License provider

ViewControl, ViewFrameworkElement and ViewFrameworkElementEx are licensed using standard Microsoft LicenseProvider. It means, that these objects try to load necessary licenses from your application. Using   LicenseProvider utility from MfcAdapter install directory ($MfcAdapter), you can create license (file AS.Dsc.Lic) for your application and update your project settings. You can use this script in Pre build event from samples: if not exist "$(ProjectDir)AS.Dsc.lic" "$(MfcAdapter)\Utilities\LicenseProvider.exe" "$(ProjectPath)". After this you have to rebuild your project and created licenses will be saved in your application. Trial version of the MfcAdapter 2.1 supports the trial (30 days) licenses.

Compatibility

Control/FrameworkElement

Type

Support of MFC applications container

Supported MFC Views

ViewCtrl (v2.1;v2.2) WinForms Yes CWnd, CView, CScrollView
ViewFrameworkElement (v2.1) WPF Yes CWnd, CView, CScrollView
ViewFrameworkElementEx (v2.2) WPF No CWnd, CView, CScrollView, CCtrlView, CListView, CTreeView, CEditView, CRichEditView

All classes suport the hosting of CWnd, CView or CScrollView based customers views. You can directly embed a control object (like CListCtrl, CHeaderCtrl and so on+) or for example COleDropTarget as class member in your class. In any case don't use CView::OnCreate for creating and initializing of view class' members inherited from CWnd. This code should be removed from the OnCreate method to the OnInitialUpdate. In this case, these members will be created after the view attached to the WinForms Control or to HwndHost element in WPF.

ViewFrameworkElementEx extends ViewFrameworkElement to support the hosting of CCtrlView, CListView, CTreeView, CEditView, CRichEditView based customer’s views. ViewFrameworkElementEx can host just as ViewFrameworkElement CWnd, CView or CScrollView based customer’s views. But it can be used only for hosting single MFC application. See the sample “RowList“ from MfcAdapter install directory ($MfcAdapter).

The current version of the MfcAdapter does not support the hosting of CFormView based views.

 

�2005 - 2007 AS. All Rights Reserved. http://mfcadapter22.000webhostapp.com/
������� ����������� ����� contadores swappernet
www.000webhost.com