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

Posted

技术标签:

【中文标题】如何在 Windows 窗体应用程序中显示 MFC 控件?【英文标题】:How do I display an MFC control in a windows forms application? 【发布时间】:2010-02-03 11:55:08 【问题描述】:

我想创建一个 Windows 窗体控件,该控件显示一个 MFC 控件,例如 CIPAddressCtrl,带有一个正常工作的 Text 属性和 TextChanged 事件。如有必要,我很乐意使用 C++/CLI。

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

【问题讨论】:

【参考方案1】:

This article 提供了一个解决方案,它将包装您的 MFC 控件。巧妙的技巧是在 Control::OnHandleCreated 的覆盖中使用 SubclassWindow。其余代码涉及使用 .NET 属性手动包装 MFC 控件的属性。

【讨论】:

谢谢!我有点挣扎 - 见***.com/questions/2343097/…【参考方案2】:

在我的类似情况下,OnHandleCreated 中的SubclassWindow 由于某种原因无法正常工作。经过一番努力,我得到了它(没有 C++/CLI):

首先,从Form#Handle 获取 HWND 并将其传递给您的 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*

编辑:this related question 中的代码也使用Attach/Detach

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

【讨论】:

以上是关于如何在 Windows 窗体应用程序中显示 MFC 控件?的主要内容,如果未能解决你的问题,请参考以下文章

在 MFC 应用程序中托管 Windows 窗体 (C#) (VC++,VS6.0)

捕获托管在 mfc 对话框上的 windows 窗体事件(c#)

如何在Visual Studio 2015中创建MFC窗体应用

如何在Visual Studio 2015中创建MFC窗体应用

vc中如何让背景图片随窗体的大小变化而改变 mfc

vs2013中用MFC和C++创建程序后,工具箱中的控件全部显示灰色,无法拖进对话框。