Hello all,
I am having problems using MFC within a managed application in Whidbey. What I try to do is the following:
Writing a dll in C++/CLI that uses MFC. In this dll I implement managed wrapper classes around e.g. MFC dialog classes. Using these wrappers I want to display the dialogs in a managed application, written e.g. in C#.
This used to work with Visual Studio 2003 and managed extensions for C++ but, but it doesn't with Whidbey.
I used the wizard to create a MFC regular dll that uses the shared version of MFC, then applied the /clr switch to it. Then I reference this dll in a C# application, calling a managed wrapper class of the dll.
The problem is, that MFC does not get initialized correctly. Normally the ctor of the of the single static instance of the CWinApp derived class is called before DllMain is executed, entering the adress of the single instance into afxModuleState. Then DllMain calls CWinApp::InitInstance through this pointer. That's the way it works in VS 2003, at least if you follow http://support.microsoft.com/ id=814472.
In Whidbey, DllMain (defined in the mfc80d.dll) is called before the ctor of CWinApp and therefore the initialization doesn't work. CWinApp::InitInstance is not called and AfxGetApp() returns NULL. I tried to do something similar as in the KB article, applying the /NOENTRY switch to the linker, but I didn't succeed because of runtime errors. The header #include <_vcclrit.h> mentioned in the article is present in Whidbey but if you use it, you get a lot of "deprecated" messages and it doesn't work.
Are there any suggestions or samples for doing this What is the correct way to do this in Whidbey
Thanks for any help,
Bernd

Using MFC regular mixed mode dll (/clr) from a managed application with Visual Studio 2005 Beta 2
l_steve_l
I have done all that, but I still get strange errors, I understand the basics of C++ as a c# programmer, but I am not familiar with the "specials", when I make a pointer in my managed routine to a MFC Dialog, and when I call a DoModal, the program crashes,
Do you have a simple example how I can call a MFC Dialog from my c# app
AfxGetApp()->DoMessageBox(LPCTSTR(
"test"),1,1);This does work, but I am not able tot show a window
Regards
Pieter Quinart
Candela
http://www.codeproject.com/managedcpp/mfcandwindowsforms.asp
It describes three ways to wrap MFC controls in order to use them in .NET forms. The code uses managed extentions, but it is pretty simple to convert to C++/CLI.
By following the instructions, I was able to wrap the example control shown; however, the techniques shown were not helpful in wrapping other controls such as CButton, CEdit and the likes.
I'd appreciate any further information that you have found regarding using MFC controls in .NET.
gill cleeren
I have made some progress!
Well, its all in the documentation, but it is not that easy to find:
http://msdn2.microsoft.com
Develpment Tools and Languages / Visual Studio 2005 / Product Documentation / Visual C++ / Programming Guide / Native and .NET interoperability / Mixed (Native and Managed) Assemblies
http://msdn2.microsoft.com/en-us/library/ms140812(en-US,VS.80).aspx
There I found several topics, well worth reading. Very interesting was
The trick is to let the CWinApp derived class of the regular MFC dll compile without /clr. This generates a native class with a native ctor, that will be called before DllMain, as it used to be in the good old times. When CWinApp::InitInstance() is called, the afxApp pointer is valid an all is fine.
There seems to be an error in the documentation: For a regular MFC dll, you should follow the instructions for an extenstion dll, i.e. disable the precompiled headers, and do not compile stdafx.cpp and MyMFCApp.cpp with /clr.
You will loose support for precompiled headers
With that I was able to display MFC dialogs from a C# application. I could even reference a MFC extension .dll from my regular .dll and use the native classes defined there thru managed C++/CLI wrappers in the regular .dll. Nice!
But always remember: you have to put AFX_MANAGE_STATE(AfxGetStaticModuleState()); in all and every function of your managed wrapper classes that call directly or indirectly into MFC. This includes the ctors of the native classes that you might call in the ctors of the managed wrappers. Therefore you cannot use the initialisation list of the ctor but you have to call the native ctors in the managed ctor body after AFX_....
My next step will be to try to host a CWnd derived class with its own painting routines in a Windows.Forms.Control class...
Has anybody suggestions on this
Bernd
JF002
thanks for the link. That was exactly what I was looking for.
I tried the first method mentioned in the article, subclassing the window in the OnHandleCreated() override and it worked great.
We have a CWnd derived class that provides plotting of line graphs and we can now reuse it in C# applications without changing a single line of code.
Regards,
Bernd