Click here to Skip to main content
Licence CPOL
First Posted 19 Jan 2007
Views 44,974
Downloads 1,283
Bookmarked 20 times

Not OLE .NET/WPF Container of MFC Applications

By | 12 Aug 2007 | Article
How to build Not OLE container of MFC applications based on hosting of MFC application from within WinForms and WPF applications

Contents

Introduction

In an e-mail to my first article "Hosting a MFC MDI application from within WinForms and WPF applications" I received a question - "Is it possible to build a container of MFC applications using the described technology?" This task has caused a little change of architecture to make components more flexible. Such work always brings pleasure, and it was the main motivation for this article. On the other hand, the result looks like an OLE container, but I have done this without creating COM objects!

I used two applications as samples: UmlEditor (MDI) and DialogEditor (SDI) by Johan Rosengren. We can simply embed both these applications in WinForms or the WPF framework, using MfcAdapter. For simplicity, I used RichTextBox based demo editors "FormsDemo" (WinFroms) and "WPFDemo" (WPF) as such kind of a container:

Architecture of the Container

The main change is to divide MfcAdapter and MFC application in separate components. In this case, we will have an MfcAdapter that is fully independent from an actual MFC application:

The low level .NET component in the described architecture is a Mixed (managed/unmanaged) DLL with an 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.

To host MFC application in WinForms/WPF framework, as described in my first article, we should:

  • Keep an invisible CMainFrame and a created CView. I have updated the application initialization and set bMakeVisible parameter to "false" in the overridden document template to implement this. The good news is we don't need to override CDocManager and to change document like in previous version of MfcAdapter.
  • Keep the modal properties of the hosted dialogs. Create the MFC MainFrame window as child of Framework MainForm window. Use the CNotifyHook in the MFC MainFrame for supporting modal MFC dialogs in external framework.
  • Auto-layout support. We have to implement some methods from CLayoutView class in our hosted view: SetPrefferedSize(), GetPreferredSize(), and Scale().

The detailed description of necessary MFC code changes and Project settings necessary for creating mixed DLL are described in the previous article.

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 can be hosted in ViewCtrl (WinForms) or ViewFrameworkElement (WPF). Mid-level components are not dependant on the actual MFC application or on the actual .NET/WPF Framework. The sample version supports SDI/MDI MFC applications, but it is possible to add support for other MFC application types: Dialog based and Multiple top-level documents.

The high level components are FormsDemo (WinForms) and WPFDemo (WPF). Both editors have two hosted MFC applications with documents: UmlEditor.dll + UmlEdi1.uml and DialogEditor.dll + DlgEdi1.dlg. Both editors support:

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

Layout

While the initialization of MFC application and the hosting of MFC View is solved relatively easily, Layout is one of the main problems of the integration MFC and WinForms/WPF. To support necessary Layout in a hosted View, the CView interface is not enough, therefore I used the CLayoutView interface. With this interface, I realized a relatively simple Layout in a described example. If you need another layout realization, you can override methods: ViewCtrl. GetPrefferedSize(), ViewCtrl.ScaleControl() and use another interface.

Layout problems are also problems with WindowsFormsHost class. This class tries to realize the WPF Layout for hosted WinForms Control. Unfortunately, I could not take advantage of WindowsFormsHost even in simple cases. Is this the result of pure compatibility of WinForms and WPF Layout or simply programming bugs, I don't know. For example:

<!--Test WindowsFormsHost-->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms">

<FlowDocumentPageViewer>
  <FlowDocument TextAlignment="Left" Background="AliceBlue" >
    <Paragraph>
      <Bold>Test WindowsFormsHost</Bold>
    </Paragraph>
    <Paragraph>
      TestCase1: change Zoom.
    </Paragraph>
    <Paragraph>
      TestCase2: remove Background="Yellow" attribute from wrapped button.
    </Paragraph>
    <Paragraph>
      <Button>WPF button</Button>
    </Paragraph>
    <Paragraph>
      <WindowsFormsHost Background="Yellow">
      <wf:Button Text="Windows Forms button" FlatStyle="Flat"/>
      </WindowsFormsHost>
    </Paragraph>
  </FlowDocument>
</FlowDocumentPageViewer>
</Page>

The first Test Case would introduce a cycle, the second - exception.

Thus, instead of ViewCtrl and WindowsFormsHost classes, I used ViewFrameworkElemen class for hosting View in WPF. In this case, we should implement the necessary WPF Layout instead of implementation of WinForms Layout and its "conversion" to WPF with WindowsFormsHost. As well as in case of ViewCtrl we can override methods: ViewFrameworkElement. OnMeseareOverride() and ViewFrameworkElement.ArrangeOverride() to realize any other Layout, for example, to support the resolution-independent layout.

Compatibility

The current version of the MfcAdapter supports the hosting of 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.

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

CCtrlView, CListView, CTreeView, CEditView, CRichEditView are supported in the FULL version of the MfcAdapter only.

Deployment and Installation

Demo Samples

The demo projects are comprised of .NET 2.0 projects:

  • FormsDemo.exe - WinForms editor. Container with hosted MFC applications UmlEditor and DialogEditor
  • MdiFormsDemo.exe - WinForms editor. Full version of the hosted UmlEditor
  • SdiFormsDemo.exe - WinForms editor. Full version of the hosted DialogEditor
  • FormTest.exe - Simple test for hosting the CScrollView and the CListCtrl

and .NET 3.0 projects:

  • WpfDemo.exe - WPF editor. Container with hosted MFC applications UmlEditor and DialogEditor
  • WpfPageDemo.exe - WPF FlowDocument. Container with hosted MFC applications UmlEditor and DialogEditor

Simply run the necessary application.

Source Code

After we unzip, we have one solution - Samples.sln with all demo projects. The deployed version of MfcAdapter consists of MfcAppAdapter.dll, ViewControl.dll, ViewFrameworkElement.dll, HostApp.h, LayoutView.h and supports only Unicode/Debug_x86 configuration. Simply copy *.dll and *.h files from "MfcAdapter" directory of zip to "MfcAdapter" directory of samples. Please note that standard "Debug" directory is renamed to "Debug_x86".

Set the necessary project as the startup project, and then build and run.

I tried to keep the encapsulated MFC code as short as possible, so I have not fixed some of the native problems of this code, for example, compiler warnings, an unhandled exception when opening a recent file that does not exist and others.

Download and use MfcAdapter SDK documentation for hosting your MFC Application.

Programming Guide with Source Code

I updated the programming guide and source code of the wizards MFC/Dialog application "DialogWiz" for current version of the MfcAdapter.

History

  • 27.01.2007 - Initial version
  • 01.04.2007 - Common controls support

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alexey Shalnov



Germany Germany

Member

I'm a Russian (MS, Physics, Lomonosov Moscow State University) Software Engineer living in Berlin, Germany since 1999. I have a long experience in Windows programming and have been developing large GUI, Real Time Enterprise Client/Server and Database C++/C# commercial applications. I am interested in different aspects of the interop of MFC and WinForms/WPF applications.
 
Try last version of MfcAdapter 2.2 VS2010 from my home page:
 
http://home.arcor.de/alexeyshalnov/home/index.htm

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 Pinmemberpmorelfourrier5:56 13 Apr '10  
GeneralRe: My vote of 1 PinmemberAlexey Shalnov21:36 14 Apr '10  
QuestionCant find source code for MFCAdapter. Pinmemberpmorelfourrier5:55 13 Apr '10  
QuestionCannot access the website for .NET 3.5 compatible sources PinmemberKumaravel Sadras13:41 15 Oct '08  
Generalcan't find reference: AS.MfcHost2 Pinmemberthebigandroid17:23 25 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 PinmemberAlexey Shalnov11:09 26 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 Pinmemberthebigandroid3:17 28 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 PinmemberAlexey Shalnov6:20 28 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 Pinmemberthebigandroid16:45 28 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 Pinmemberthebigandroid17:19 28 Apr '08  
GeneralRe: can't find reference: AS.MfcHost2 PinmemberAlexey Shalnov3:46 1 May '08  
QuestionWorking with single-byte character set PinmemberMyriaLeJean1:57 9 Aug '07  
AnswerRe: Working with single-byte character set PinmemberAlexey Shalnov11:09 9 Aug '07  
QuestionHosting app that uses CLR PinmemberMyriaLeJean0:37 31 Jul '07  
AnswerRe: Hosting app that uses CLR PinmemberMyriaLeJean2:44 31 Jul '07  
QuestionI have an extended listview derived from MFC listview/listcontrol Pinmemberaskflee14:41 19 Mar '07  
AnswerRe: I have an extended listview derived from MFC listview/listcontrol PinmemberAlexey Shalnov10:50 5 Apr '07  
QuestionShould it work with CFormViews? PinmemberMyriaLeJean4:38 9 Mar '07  
AnswerRe: Should it work with CFormViews? PinmemberAlexey Shalnov21:41 11 Mar '07  
AnswerRe: Should it work with CFormViews? PinmemberAlexey Shalnov10:56 5 Apr '07  
GeneralExcellent Work! PinmemberAAntix20:08 23 Jan '07  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 12 Aug 2007
Article Copyright 2007 by Alexey Shalnov
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid