Сделать элемент управления ActiveX работать без формы? - PullRequest
1 голос
/ 25 мая 2010

Мы используем накладки Topaz Signature. Они предоставляют свои API-интерфейсы в элементе управления ActiveX, который должен быть помещен в элемент управления Winform. Что ж, то, как будет работать наш проект, мы не хотим иметь форму (по крайней мере, не видно). Мы просто хотим, чтобы элемент ActiveX подписи получал изображение в фоновом режиме.

static AxSigPlus sig = new AxSIGPLUSLib.AxSigPlus();

public static void Begin()
{
    ((System.ComponentModel.ISupportInitialize)(sig)).BeginInit();
    sig.Name = "sig";
    sig.Location = new System.Drawing.Point(0, 0);
    sig.Size = new System.Drawing.Size(0, 0);
    sig.Enabled = true;

    sig.TabletState = 1; //error here
    sig.SigCompressionMode = 0;
}

Хорошо, я получаю сообщение об ошибке в отмеченной строке. Исключение составляет

Exception of type 'System.Windows.Forms.AxHost+InvalidActiveXStateException' was thrown.

Что мне делать, чтобы решить эту проблему? Будет ли проще создать новую скрытую форму и установить контроль над ней, чтобы она была невидимой?

Ответы [ 4 ]

2 голосов
/ 25 мая 2010

Да, это не может работать таким образом. Оболочка AxHost требует, чтобы ее дескриптор был создан до ее использования. Что требует, чтобы это был дочерний элемент управления в форме, метод Show () которого вызывается.

Обычно вы получаете две оболочки взаимодействия из элемента управления ActiveX, AxBlah.dll, которая содержит оболочку AxHost, и Blah.dll, которая упаковывает интерфейсы COM. Вам нужно всего лишь ссылаться на Blah.dll. Будет ли это работать, остается открытым вопросом, для многих элементов управления ActiveX требуется дескриптор окна для синхронизации потоков.

Если это не сработает, вам понадобится форма хоста. Вы можете сделать его невидимым, вставив этот код в класс формы:

    protected override void SetVisibleCore(bool value) {
        if (!IsHandleCreated) CreateHandle();
        value = false;
        base.SetVisibleCore(value);
    }

Вам нужно вызвать Application.Run () для прокачки цикла сообщений.

1 голос
/ 16 августа 2011

Это то, что я сделал (в основном добавил невидимый элемент управления Axe и затем вызвал его методы):

using (AxRUNNERXLib.AxRunnerX crm = new AxRUNNERXLib.AxRunnerX ()) {
    Controls.Add (crm);
    crm.Visible = false;

    crm.CustomerPrefix = m_SelCall.CustomerPrefix;
    crm.LoadDefaultDescription ();
    crm.SearchByID (m_SelCall.CustomerID);
    crm.OperatorID = Form1.operatorID.ToString ();
    crm.ShowHistory ();

    Controls.Remove (crm);
}
1 голос
/ 25 мая 2010

Вы можете просто использовать COM-объект напрямую (это зависит от того, как они реализовали элемент управления). Обычно, когда вы импортируете COM-объект в ваши ссылки, он создает оболочку AxHost, но он также должен импортировать объекты базового класса. Найдите то, что потом просто создайте как обычный класс, не используйте версию AxHost. Если кажется, что нет объектов базового класса, вы можете создать объект, используя Activator и либо CLSID, либо ProgID элемента управления. Что-то вроде:

object o = Activator.CreateInstance(Type.GetTypeFromProgID("prog.id"))

0 голосов
/ 26 мая 2010

На самом деле все закончилось тем, что Topaz предоставил элемент управления ActiveX и оболочку .Net вокруг него. Я переключился на оболочку .Net, и она не требует помещения в форму или что-либо еще. Я оставлю этот вопрос, хотя, если бы не эта обертка, я бы на самом деле имел с этим дело.

...