How do I display an MFC control in a windows forms

2019-02-19 00:59发布

问题:

I'd like to create a windows forms control which shows an MFC control such as CIPAddressCtrl, with a working Text property and TextChanged event. How do I display an MFC control in a windows forms application? I'm happy to use C++/CLI if necessary.

NOTE: I'm not asking how to create a brand new windows forms control; I want to host a legacy control in a windows forms app.

回答1:

This article presents a solution which will wrap your MFC control. The neat trick of this is its use of SubclassWindow in the override of Control::OnHandleCreated. The rest of the code involves manually wrapping the attributes of the MFC control with .NET properties.



回答2:

In my similar case, SubclassWindow in OnHandleCreated didn't work for some reason. After some struggle, I got it work (without C++/CLI):

First, get a HWND from Form#Handle and pass it to your MFC DLL.

class GuestControl : Control
{
    private IntPtr CWnd { get; set; }

    public GuestControl()
    {
        CWnd = attach(Handle);
    }

    protected override void Dispose(bool disposing)
    {
       if (disposing)
       {
          detach(CWnd);
       }

       base.Dispose(disposing);
    }

    [DllImport("your_mfc_dll")]
    private static extern IntPtr attach(IntPtr hwnd);
    [DllImport("your_mfc_dll")]
    private static extern void detach(IntPtr hwnd);
}

Then, in your DLL, CWnd::Attach to the obtained HWND and initialize the control. Clean up with CWnd::Detach on Dispose.

/** Attach to C# HWND and initialize */
extern "C" __declspec(dllexport) CWnd* PASCAL attach(HWND hwnd) {
    auto w = std::make_unique<CWnd>();

    if (!w->Attach(hwnd)) { return nullptr; }

    // ... initialize your MFC control ...

    return w.release();
}

/** Detach and delete CWnd */
extern "C" __declspec(dllexport) void PASCAL detach(CWnd *cwnd) {
    auto w = std::unique_ptr<CWnd>(cwnd);
    w->Detach();
}

See GuestControl.cs / guest.cpp* for a full example.

Edit: The code in this related question also use Attach/Detach.

* The example is my work. (MIT License)