Как я могу встроить неуправляемую форму C ++ в приложение .NET? - PullRequest
5 голосов
/ 01 марта 2011

Мне удалось успешно обернуть мою неуправляемую библиотеку Borland C ++ и запустить ее формы из приложения C # .NET 4.0. Можно ли встроить форму из библиотеки DLL прямо в приложение .NET?

Для пояснения, исходная форма уже используется в качестве встроенного элемента управления в проекте Borland C ++. По сути, это выглядит как пользовательский элемент управления, расположенный на панели приложения.

Когда я говорю «внедрить», я имею в виду поместить INTO в форму так же, как вы перетаскиваете на нее кнопки, панели и т. Я не просто хочу сделать детскую форму.

Если это невозможно, то, возможно, лучше задать вопрос, как мне встроить неуправляемый пользовательский элемент управления в приложение .Net?

Ответы [ 2 ]

4 голосов
/ 01 марта 2011

Да, вам просто нужно использовать некоторые низкоуровневые функции win32 из user32.dll: SetParent, GetWindowLog, SetWindowLong, MoveWindow. Вы можете создать пустой контейнерный элемент управления .NET, установить родительский элемент собственного окна в элемент управления .NET, затем (необязательно) изменить стиль окна (т. Е. Удалить границы собственного окна) и обратить внимание, чтобы изменить его размер вместе с .NET control. Обратите внимание, что на управляемом уровне элемент управления .NET не будет знать, что у него есть дочерние элементы.

В .NET control сделайте что-то вроде

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

}

Затем переопределите WndProc элемента управления .NET, чтобы он соответствующим образом изменил размер собственной формы - например, для заполнения клиентской области.

 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;

        }

 }
1 голос
/ 01 марта 2011

Примечание Я написал этот ответ, предполагая, что ОП хотел буквально встроить собственную DLL, содержащую форму, в приложение .NET, а не просто изменить способ ее отображения.

Короче, нет.Вам нужно будет упаковать C ++ DLL с вашим дистрибутивом и импортировать / обернуть его функции так же, как вы это делаете сейчас.

Кажется, я вспоминаю из моего Delphi (который использует тот же серверкак Borland C ++) дни, когда конструктор форм генерирует код C ++, который создает цикл winproc / message и т. д. для каждого из активов в форме через Win32 API.

Поскольку весь этот код неуправляем, он не может быть скомпилирован в управляемую сборку.Вы могли бы перенести его на управляемый C ++, но это убило бы большую часть преимуществ использования C ++ для начала, и вы застряли с дрянной моделью исключений и всеми другими замечательными частями C ++.В этом случае вам, вероятно, было бы лучше просто переписать его на C #.

Но, поскольку это программное обеспечение, и почти все возможно, вот действительно неудачное решение: встроить DLL как двоичный ресурс вваше приложение .NET и, во время выполнения, извлекает его содержимое в двоичный поток, сохраняет его на диск и затем загружает его (я не уверен, что есть способ выполнить неуправляемую DLL из памяти, кроме обмана путем установкиэто на диске RAM).

Единственное, что вы получаете, это возможность скрыть DLL, но я действительно не вижу в этом смысла.

Редактировать Вы имеете в виду встраивать как в show как дочернее окно, или встраивать как на месте код в .NET-проекте?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...