C# 如何嵌入非托管C++;表单转换为.NET应用程序? 我已经成功地包装了我的非托管Borland C++ DLL,并从C.net .NET 4应用程序中启动了它的表单。是否可以将dll中的表单直接嵌入到.NET应用程序中 澄清,原始形式已经被用作Borland C++项目中的嵌入式控件。它本质上看起来像一个自定义控件,位于应用程序中的面板上

C# 如何嵌入非托管C++;表单转换为.NET应用程序? 我已经成功地包装了我的非托管Borland C++ DLL,并从C.net .NET 4应用程序中启动了它的表单。是否可以将dll中的表单直接嵌入到.NET应用程序中 澄清,原始形式已经被用作Borland C++项目中的嵌入式控件。它本质上看起来像一个自定义控件,位于应用程序中的面板上,c#,.net,c++,unmanaged,C#,.net,C++,Unmanaged,当我说“嵌入”时,我的意思是将位置放入表单,就像将按钮、面板等放到表单上一样。我不想只做一个儿童表格 如果这是不可能的,那么一个更好的问题可能是如何将未管理的自定义控件嵌入到.Net应用程序中?注意我编写此响应时假设OP希望将包含表单的本机DLL嵌入到.Net应用程序中,而不仅仅是修改其显示方式 简而言之,你需要用你的分布包来封装C++ DLL,并且用同样的方式导入/包装它的函数。 我记得从Delphi(使用与Borland C++相同的编译器后端)来回忆,表单设计器生成C++代码,通过Win3

当我说“嵌入”时,我的意思是将位置放入表单,就像将按钮、面板等放到表单上一样。我不想只做一个儿童表格

如果这是不可能的,那么一个更好的问题可能是如何将未管理的自定义控件嵌入到.Net应用程序中?

注意我编写此响应时假设OP希望将包含表单的本机DLL嵌入到.Net应用程序中,而不仅仅是修改其显示方式

简而言之,你需要用你的分布包来封装C++ DLL,并且用同样的方式导入/包装它的函数。 <>我记得从Delphi(使用与Borland C++相同的编译器后端)来回忆,表单设计器生成C++代码,通过Win32 API创建表单中的每个资产的WinPro/消息循环等。p> 由于所有这些代码都是非托管的,因此无法将其编译成托管程序集。你可以将它移植到托管C++,但是这会扼杀它在C++中的大部分好处,而且你会被一个蹩脚的异常模型和C++的其他精彩部分所困扰。在这种情况下,您最好还是用C#重写它

但是,由于这是软件,几乎任何事情都有可能,这里有一个非常蹩脚的解决方案:将DLL作为二进制资源嵌入.NET应用程序中,并在运行时将其内容拉入二进制流,保存到磁盘,然后加载(我不确定是否有办法从内存中执行非托管DLL,而不是将其放在RAM磁盘上进行欺骗)

这唯一能让你得到的是隐藏DLL的能力,但我真的不明白这有什么意义

编辑
您的意思是将代码嵌入显示为子窗口,还是将代码嵌入.NET项目中?

是的,您只需要使用user32.dll中的一些低级win32函数:SetParent、GetWindowLog、SetWindowLong、MoveWindow。您可以创建一个空的.NET容器控件,将本机窗口的父控件设置为.NET控件,然后(可选)修改窗口样式(即删除本机窗口的边框),并注意与.NET控件一起调整其大小。请注意,在托管级别,.NET控件将不知道它有任何子控件

在.NET控件中,执行以下操作

public void AddNativeChildWindow(IntPtr hWndChild){

        //adjust window style of child in case it is a top-level window
        int iStyle = GetWindowLong(hWndChild, GWL_STYLE);
        iStyle = iStyle & (int)(~(WS_OVERLAPPEDWINDOW | WS_POPUP));
        iStyle = iStyle | WS_CHILD;
        SetWindowLong(hWndChild, GWL_STYLE, iStyle);


        //let the .NET control  be the parent of the native window
        SetParent((IntPtr)hWndChild, this.Handle);
         this._childHandle=hWndChild;

        // just for fun, send an appropriate message to the .NET control 
        SendMessage(this.Handle, WM_PARENTNOTIFY, (IntPtr)1, (IntPtr)hWndChild);

}
然后重写.NET控件的WndProc,使其适当地调整本机窗体的大小,例如填充客户端区域

 protected override unsafe void WndProc(ref Message m)
    {

        switch (m.Msg)
        {
            case WM_PARENTNOTIFY:
                   //... maybe change the border styles , etc
                   break;
              case WM_SIZE:
                iWid =(int)( (int)m.LParam & 0xFFFF);
                iHei= (int) (m.LParam) >> 16;
                if (_childHandle != (IntPtr)0)
                {

                    MoveWindow(_childHandle, 0, 0, iWid, iHei, true);

                }
                break;

        }

 }

你的意思是在show as child窗口中嵌入,还是在.NET项目中就地嵌入代码?这当然会使本机表单成为.NET应用程序的子表单之一,但并不能真正解决“嵌入”问题NET应用程序中的窗口。我们似乎对这个问题的解释完全不同。这个问题模棱两可。我试图进一步澄清这个问题。从本质上说,我所寻找的是一种方法,可以将表单放置在.NET表单中,就像在表单上放置按钮和标签一样。我希望将其嵌入表单控件中l,而不仅仅是一个子窗口。如果您像我所描述的那样将其包装在自定义控件中,您也可以像其他控件一样在表单设计器中使用它。只是IDE不知道如何处理本机事件,您需要在包装器中手动处理它。