繁体   English   中英

如何将非托管C ++表单嵌入到.NET应用程序中?

[英]How can I embed an unmanaged C++ form into a .NET application?

我已经能够成功包装非托管的Borland C ++ dll,并从C#.NET 4.0应用程序启动它的表单。 是否可以将dll中的表单直接嵌入到.NET应用程序中?

为了澄清,原始形式已经被用作Borland C ++项目中的嵌入式控件。 它本质上看起来像一个自定义控件,位于应用程序内的面板上。

当我说“嵌入”时,我的意思是将按钮,面板等放在表单上的方式放入表单。 我不只是想做一个孩子的形式。

如果这不可能,那么也许更好的问题是如何将未管理的自定义控件嵌入到.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;

        }

 }

请注意, 我写此响应的前提是OP希望将包含该表单的本机DLL实际上嵌入.NET应用程序中,而不仅仅是修改其显示方式。

简而言之,没有。 您需要使用自己的发行版打包C ++ DLL,并以与现在相同的方式导入/包装其功能。

我似乎从我的Delphi(使用与Borland C ++使用相同的编译器后端)的回忆中回忆起,表单设计器生成C ++代码,该代码通过Win32 API为表单中的每个资产创建一个winproc / message循环,等等。

由于所有代码都是非托管代码,因此无法将其编译为托管程序集。 您可以将其移植到托管C ++,但这会扼杀从C ++入手的大多数好处,并且您会陷入一个cr脚的异常模型以及C ++的所有其他精彩部分。 在这种情况下,最好只用C#重写它。

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

这让您获得的唯一好处就是隐藏了DLL的能力,但我真的不明白这一点。

编辑您是要嵌入作为子窗口显示,还是嵌入到.NET项目中的代码中?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM