Search code examples
c#.netmfcc++-cliinterop

Calling MFC Dialog from C# .Net?


I need to integrate legacy MFC code into my C# .Net application.

To simulate my MFC code for the purpose of simplifying integration, I created a sample MFC Dialog application, with one button and one edit box. It writes Hello World into the edit box, when I click the button.

My goal is to make this callable from my .Net application. I will be happy if my .Net application can pop up the Dialog box, and have it print HelloWorld when I click the button. I have heard that C++/CLI is a good way to do this. If dynamic linking complicates the matter, I am ok with static linking too.

Firstly, I would like to know if this is even possible? I do not understand the process needed to accomplish this.

So far: I enabled the CLR support from Project properties, and created a C# WinForms application. I was able to add the MFC Dialog application as a reference to the C# WInforms application. But I am stuck at finding out how to export the dialog across the interface. Since, I am doing static linkage, do I still have to write dllexports for the dialog class? How do I export all of the dialog class, how will C# find the resource file that describes how the GUI is laid out for the Dialog?

The code for the dialog box is App Wizard generated, I just added an edit box and a button, and added a handler for the button that writes HelloWorld into the edit box.


To get a start, I tried creating another MFC application to see if I could at least call my MFC Dialog from another MFC application. In the consumer application, I added my Hello World Dialog app as a reference, and included the path to the Dialog header file. But it gave me error saying that IDD_DLG, which is the ID for my dialog was unidentified. So, I need to figure out how to supply with the resource file, where all the IDs are defined.


Solution

  • MFC Methods cannot directly be P/Invoked (see this SO Answer), what I have done to invoke a dialog box from another program is to create a DLL containing the dialog box, export a function which can invoke the dialog box and call the DLL function from an external application (e.g.: C#):

    #include "stdafx.h"
    #include "afxdialogex.h"
    #include "MyDlg.h"
    
    extern "C" __declspec (dllexport) BOOL ShowDlg()
    {   AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
        CMyDlg dlg;
        INT_PTR nResponse = dlg.DoModal();
        return (nResponse == IDOK);
    }
    

    You could also add parameters to pass to/from the dialog box as required...