MFC -> .NET
So I work with MFC-based legacy applications for most my day. None of them were designed particularly well. They were created seven or eight years ago to satisfy a particular requirement. They did their job well but then mutated over the years to satisfy other requirements. With no eye to design or architecture, these changes were added piecemeal until present day, when what we have is a ball of code full of hacks, workarounds and general feature-aggregation.
Saying this is problematic to maintain would be an understatement. With no unit tests, or any tests at all (except loading it up and making sure it doesn't format the hard disk by accident), regressions are a very real possiblity and happen far too often.
This being said, we're limited in our options of what to do. We can:
- Stick it out, leave it be and continue on course to a code armageddon. Not my favorite option.
- Scrap the applications altogether and rewrite them in C# or Managed C++. Not really a good option either since, as bad as these apps are maintenance-wise, they do very complicated jobs somewhat well. We'd be lucky to code up a new app in six months that does 1/4 of what they do now. Fun for developers, bad for business.
- Keep the codebase as is, but roll in .NET on a feature-by-feature basis. This is the best of both worlds--we keep our legacy code and all of it's (mostly working) warts, but are able to introduce .NET here and there with an eye to eventually replacing all of the legacy code with .NET in a few years.
Can you guess which choice we're going with? The silver bullet here and the reason we're able to do this is a magical language I call Managed C++. Microsoft has done plenty of evil things (or so I read), but the interoperability of Managed C++ with legacy code is not one of them.
Since these apps are all MFC, we're able to load them up in Visual Studio 2005 (moving from VS6, itself a rather painful transition we made last year), throw the /clr compiler switch and, after a fixing a few compiler errors (mostly due to not using the _T macro with strings as much as we should) we automagically have support for the CLR in our app.
The first thing I'm doing is implementing a C# User Control for inclusion on one of our data entry forms. This is a pretty simple thing to do. You just drop a static control on your form where you want the User Control to go and create a data member in your dialog class like so:
class CMFC01Dlg : public CDialog
{
// ...
// Data member for the .NET User Control:
// (note: ctrl_lib is a user created control assembly)
CWinFormsControl<ctrl_lib::usercontrol1> m_ctrl1;
}
Then, in your ::DoDataExchange method, just add the following:
void CMFC01Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDXManagedControl(pDX, IDCCTRL1, m_ctrl1);
}
Congratulations, you now have a .NET User Control on your MFC form with about 6 lines of code.
The point here is that very often there's a way to keep your legacy code while also transitioning to newer technologies. It may not always be easy or particularly fun, but your customers will thank you and so will your company.