简体   繁体   中英

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

I have been able to successfully wrap my unmanaged Borland C++ dll, and launch it's forms from a C# .NET 4.0 application. Is it possible to embed a form from the dll directly into a .NET application?

To clarify, the original form is being used as an embedded control in a Borland C++ project already. It essentially looks like a custom control, sitting on a panel within the application.

When I say 'embed' I mean place INTO a form in the same way you drop buttons, panels, etc on to a form. I'm not looking to just make a child form.

If this is not possible, then perhaps a better question would be how do I embed an unmanged custom control into a .Net application?

Yes, you just need to use some low-level win32 functions from user32.dll : SetParent, GetWindowLog, SetWindowLong , MoveWindow . You can create an empty .NET container control, set the parent of the native window to the .NET control, then (optionally) modify the window style (ie to remove borders of native window), and pay attention to resize it together with the .NET control. Note that, at a managed level, the .NET control will be unaware it has any children.

In the .NET control do something like

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);

}

Then override the WndProc of the .NET control to make it resize the native form appropriately -- for example to fill the client area.

 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;

        }

 }

Note I wrote this response assuming that the OP wanted to literally embed the native DLL containing the form in the .NET app, not just modify the way in which it's displayed.

In short, no. You'll need to package the C++ DLL with your distribution and import/wrap its functions the same way that you're doing now.

I seem to recall from my Delphi (which uses the same compiler back-end as Borland C++) days that the form designer generates C++ code which creates a winproc/message loop, etc for each of the assets in the form via with Win32 API.

Since all of that code is unmanaged, it can't be compiled into a managed assembly. You could port it to managed C++, but that would kill most of the benefit of having it in C++ to start with, and you're stuck with a crappy exception model and all of the other wonderful parts of C++. In that case, you'd probably be better off just rewriting it in C#.

But, since this is software, and almost anything is possible, here's a really lame solution: embed the DLL as a binary resource in your .NET app and, at run time, pull its contents into a binary stream, save it to disk and then load it (I'm not sure if there is a way to execute an unmanaged DLL from memory, other than cheating by putting it on a RAM disk).

The only thing this gets you is the ability to hide the DLL, but I really don't see the point.

Edit Do you mean embed as in show as a child window, or embed as in place the code within the .NET project?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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