如何在 Windows 窗体应用程序中显示 MFC 控件?

发布于 2024-08-20 11:14:15 字数 243 浏览 3 评论 0原文

我想创建一个 Windows 窗体控件,该控件显示 MFC 控件(例如 CIPAddressCtrl),并具有工作 Text 属性和 TextChanged 事件。如何在 Windows 窗体应用程序中显示 MFC 控件?如有必要,我很乐意使用 C++/CLI。

注意:我不是在问如何创建一个全新的 Windows 窗体控件;而是在问如何创建一个全新的 Windows 窗体控件。我想在 Windows 窗体应用程序中托管旧控件。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡笑忘祈一世凡恋 2024-08-27 11:14:15

本文提出了一个解决方案,它将包装您的MFC控制。这个巧妙的技巧是在 Control::OnHandleCreated 的重写中使用 SubclassWindow。其余代码涉及使用 .NET 属性手动包装 MFC 控件的属性。

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.

南风几经秋 2024-08-27 11:14:15

在我的类似情况下,OnHandleCreated 中的 SubclassWindow 由于某种原因不起作用。经过一番努力,我成功了(没有 C++/CLI):

首先,从 Form#Handle 并将其传递给您的 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);
}

然后,在您的 DLL 中,CWnd::Attach 到获取HWND并初始化控件。使用 Dispose 上的 CWnd::Detach 进行清理。

/** 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();
}

请参阅 GuestControl.cs / guest.cpp * 查看完整示例。

编辑:此相关问题中的代码也使用Attach/ 分离

* 示例是我的作品。 (麻省理工学院许可证)

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文