ActiveX и C#

Рейтинг: 1Ответов: 2Опубликовано: 11.06.2011

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

Ответы

▲ 7Принят

Простейший пример ActiveX на C#.

Код:

using System;
using System.Runtime.InteropServices;

namespace Example 
{

    public interface Greetings
    {
        string Greeting();
    }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Sample : Greetings
    {
        public string Greeting()
        {
            return "Hello, World!";
        }
    }
}

Сборка:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:library example.cs

Регистрация в системе (от администратора):

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe example.dll /tlb /codebase

Тестовая страница:

<html>
<head>
  <script language="javascript">
    <!-- Загрузить объект ActiveX -->
    var z = new ActiveXObject("Example.Sample");

    <!-- Вызвать метод -->
    alert(z.Greeting());
  </script>
</head>
<body>
</body>
</html>

Более подробная документация:

▲ 2

Если речь идет о простом компоненте повторного использования - то все сказано в первом ответе. Если же речь идет об интерфейсном элементе - то все не так просто. C# в чистом виде не дает такой возможности. Но можно сделать контрол на C#, а потом сделать для него обертку на С++ с использованием MFC. В MFC есть класс CWinFormsControl, оборачивающий WinForms контролы в CWnd. Далее нужно, используя возможности WinForms, сделать обычный контрол на C#, назовем его, к примеру MyLib.MyControl. Далее, создать ActiveX MFC проект, в свойствах проекта включить поддержку CLR и добавить ссылку на сборку с контролом. В заголовочном файле ActiveX добавить член

CWinFormsControl<MyLib::MyControl>  m_myControl;

и вставить/расширить обработчики событий в ActiveX (как это сделать - см. доку по MFC):

int MyActiveX::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (COleControl::OnCreate(lpCreateStruct) == -1)
        return -1;

    m_myControl.CreateManagedControl(WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, 0);
    m_myControl.ModifyStyleEx(0, WS_EX_CONTROLPARENT);

    return 0;
}

void MyActiveX::OnSize(UINT nType, int cx, int cy)
{
    COleControl::OnSize(nType, cx, cy);

    if (::IsWindow(m_myControl.m_hWnd))
        m_myControl.MoveWindow(0, 0, cx, cy);
}

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