首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将非托管C++表单嵌入到.NET应用程序中?

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

Stack Overflow用户
提问于 2011-03-01 23:48:28
回答 2查看 3K关注 0票数 5

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

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

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-02 00:13:39

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

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

代码语言:javascript
复制
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,使其适当地调整本机窗体的大小--例如填充工作区。

代码语言:javascript
复制
 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;

        }

 }
票数 4
EN

Stack Overflow用户

发布于 2011-03-01 23:56:31

注意:我写这个响应的前提是,OP想要在.NET应用程序中直接嵌入包含表单的本机DLL,而不仅仅是修改表单的显示方式。

简而言之,不是。您需要将C++ DLL与您的发行版打包在一起,并以与现在相同的方式导入/包装它的函数。

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

由于所有代码都是非托管的,因此无法将其编译为托管程序集。您可以将其移植到托管C++,但这将扼杀在C++中使用它的大部分好处,并且您将被困在一个糟糕的异常模型和C++的所有其他精彩部分中。在这种情况下,最好用C#重写它。

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

这样做得到的唯一好处就是能够隐藏DLL,但我真的不明白这一点。

编辑您的意思是像显示一样嵌入到子窗口中,还是像在.NET项目中一样嵌入代码?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5156794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档