Tech Off Thread

4 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

C# Window in C++ App

Back to Forum: Tech Off
  • User profile image
    Ben Breen

    Hi all,

    I have a C++ (MFC) MDI app, and I would like to slowly move this over to C#, one section at a time. I would first of all like to do this just by writing any new child windows in C#.

    Does anyone have any ideas of how to create C# MDI child windows inside a C++ MFC app using managed and unmanaged code?

    Any help here would be very usefull!

    Ben

  • User profile image
    Terry Denham

    I've done some of this and I would recommend against it.

    In my case I had a huge framework library of derived MFC classes that I tried to incorporate WinForms into. Just compiling my existing framework with /clr produced a exe of about 125MB. The linking took about 400MB to build the executable. This is because with compiling under /clr all the MFC classes produce metadata.

    Another way that I haven't looked into is not to compile the app with clr but take advantage of the fact that you can treat clr classes as com objects. This way your existing application is still compiled c++ code but the new WinForms are invoked through com interop. This would require you to have a seperate assembly for your new WinForms classes.

    I look forward to hearing about your progress if you decide to go this route.

  • User profile image
    Ben Breen

    The COM iterop method does sound the best route to take.

    I am however finding it difficult to create a C# window which will recognise the C++ MFC window as the parent (eg. in order to gain proper MDI child behaviour from the C# window).

    If you know a way which may work, I would love to hear it.

    Ben

  • User profile image
    denan921

    Don't know if you are still interested, but I came across this page when looking for a solution. Since I didn't find any solution on the internet I designed one myself:
    * Create the Form as usual using C#
    * Send the handle to the C++ app (using COM in my example)
    * In the C++ app, retrieve the handle and use CWnd::FromHandle to create a CWnd wrapper
    * Set the parent to the desired MFC window
    * Call ShowWindow and voilá

    example using COM interop:
    C# Wrapper for the Form
    ===================
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IDotNetTool
    {
        System.IntPtr GetHandle();
    }

    [ClassInterface(ClassInterfaceType.None)]
    public class DotNetTool : IDotNetTool{

        private MyForm m_Form;

        public DotNetTool()
        {
           m_Form = new MyForm();
        }

        public System.IntPtr GetHandle()
        {
              return m_Form.Handle;
        }
    }

    in the C++ app
    ==========
    #import "DotNetTool.tlb" no_namespace named_guids
    ....
    void Foo::Bar()
    {
    CComPtr<IDotNetTool> pDotNetTool;
    ::CoCreateInstance(CLSID_DotNetTool,NULL,CLSCTX_INPROC_SERVER,
                                    IID_IDotNetTool, (void**)&pDotNetTool);
    HWND hDotNetWnd = (HWND)pDotNetTool->GetHandle();   
    CWnd* pTest = CWnd::FromHandle(hDotNetWnd);
    pTest->SetParent(pParent); //pParent is a CWnd* to the desired container
    pTest->ShowWindow(TRUE);
    }

    Note that C# assembly must be compiled for COM interop to produce the DotNetTool.tlb file. And it also needs a strong name, generated by using sn.exe -k <desired filename> and attached as the assembly key file.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.