Pages

Friday 2 June 2006

Mixing legacy MFC code with Windows Forms (Part 1)

I am looking into how to run legacy MFC code within a nice-looking Windows Forms framework. I built an MDI with Windows Forms and C# using ADO.NET. I have a large code base in C++: rather than rewriting the complete application from scratch (and therefore having to maintain and deploy 2 distinct applications, one in Windows Forms, one in MFC), I'd like to integrate the legacy code inside the new Windows Forms framework. This would allow for a smooth transition from MFC to Windows Forms.
I must solve two problems:
  • use an MFC property sheet from a C# app
  • manage ODBC and ADO.NET connections in a single exe
Backgrounders:
Getting closer:
What I have tried so far:

  • Subclass System.Windows.Forms.Control
As a starting point I used http://www.codeproject.com/managedcpp/mfcandwindowsforms.asp, which explains how to drag and drop into the Windows Forms designer a control based on legacy MFC code. This technique relies on subclassing: the Windows Forms control is created first, then its handle is passed to the MFC class which is then responsible for drawing the control. It works well as long as the MFC class derives from CWnd.
Subclass a Windows forms control with an MFC CWnd
The Winforms C# App calls a C++ managed wrapper (derived from System::Windows::Forms::Control). Upon creation of its handle, the wrapper associates the handle with a CWnd-derived MFC class. The original code from the Codeproject article used C++ managed extensions. I compiled it with VS2005 so I had to translate it from C++ managed extensions to C++/CLI and it worked just fine.
This technique works ok with a CWnd-derived class. Unfortunately our legacy MFC code is based on property sheets so this is not going to be enough, but it’s a start.
  • One single C++/CLI App containing MFC legacy source and dialog templates.
Created a C++ Windows Forms project. Added the MFC property sheets and property pages sources files to it. Also added the dialog templates associated with each page. The app consisted of a windows form that launches the MFC property sheet when you click a button. It worked.
However for some reason only the Release version of the executable worked. The Debug version kept displaying the following assertion,
Error
an instead of displaying the appropriate line of code just got my machine to thrash.
Anyway this is still not quite what I want to do: my Windows Forms MDI framework is written in C#, not in C++. The legacy code must reside a DLL compiled in mixed mode.
  • A C# Windows Forms project calls a dialog residing inside a mixed-mode exe
Attempt2
I created the MFC dialog project with the Wizard then modified its properties:
    • Changed to DLL
    • Switched on /clr
    • Disabled pre-compiled headers.
Got the following error:
Fixups
  1. Created an MFC MDI App with Visual Studio 2005.
  2. Added MFCAppAdapter.cpp (copied from Alexey Shalnov’s article).
  3. Changed MFCAppAdapter.cpp compile options to /clr (at the file level, not the project level).
  4. Set Code Generation option: set to default.
  5. Set Enable Minimal Rebuild option to No.
  6. Set Enable C++ Exceptions to Yes with SEH
  7. Set Debug Information Format to Zi
  8. Add references to System and System.Windows.Forms
TBC

2 comments:

Anonymous said...

the link to

Developing Windows Forms Control using MFC and Managed C++

moved to

http://www.codeproject.com/KB/miscctrl/mfcandwindowsforms.aspx

Matt said...

Thanks! Would you be the author of the article by any chance?