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

前端 未结 2 1146
花落未央
花落未央 2021-02-10 01:38

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 i

2条回答
  •  悲&欢浪女
    2021-02-10 02:01

    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 (i.e. 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;
    
            }
    
     }
    

提交回复
热议问题