开发者

How do I display an MFC control in a windows forms application?

开发者 https://www.devze.com 2022-12-18 18:46 出处:网络
I\'d like to create a windows forms con开发者_JAVA技巧trol 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 wi

I'd like to create a windows forms con开发者_JAVA技巧trol 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.


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.


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)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号