Как правильно расширить существующий компонент ActiveX / COM? - PullRequest
2 голосов
/ 04 марта 2011

Я обновляю приложение MFC, содержащее пользовательский элемент управления ActiveX. В рамках обновления у меня была причина добавить новые методы в элемент управления ActiveX, и теперь он имеет интерфейс, отличный от старой версии. Изменения не повлияли на исходные методы, поэтому старые клиенты все еще могут использовать новый компонент.

У меня все работает, но я знаю, что то, что я сделал, вонючее! Как правильно обновлять интерфейс COM / ActiveX.

Этот компонент был построен с использованием MFC, и Googling не предоставляет большой помощи, кроме базовых учебных пособий типа «Создание элемента управления ActiveX с MFC». Я могу найти множество вещей об ATL, но я не хочу портировать компонент поверх.

У меня были различные предложения от коллег, такие как изменение направляющих и наследование интерфейса, но ничего определенного.

Так что вообще считается лучшей практикой для обновления интерфейсов COM?

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

Я попытался создать второй интерфейс (см. Ниже), как предложено MSalters, но я не уверен, что я сделал это правильно. Я создал новый интерфейс и новый coclass в файле odl. Это приводит к тому, что MFC в клиентском приложении генерирует два отдельных класса-оболочки, один из которых получен из CWnd для тестового класса Coclass, а другой - из COleDispatchDriver для тестового класса Test2 - я бы ожидал два похожих класса-оболочки ....

library TestLib
{
    importlib(STDOLE_TLB);

    // This is the original interface.......

    [ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286223)]
    dispinterface _DTest
    {
        properties:
        methods:
            [id(1)] short TestMethod();
    };

    //  Class information for CTestCtrl
    [ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED48), control ]
    coclass Test
    {
        [default] dispinterface _DTest;
    };


    //  This is the new interface.

    [ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286224)]
    dispinterface _DTest2
    {
        properties:
        methods:
            [id(1)] short TestMethod();
            [id(2)] short TestMethod2();
    };

    //  Class information for CTestCtrl2

    [ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED49), control ]
    coclass Test2
    {
        [default] dispinterface _DTest2;
    };
};

Ответы [ 2 ]

3 голосов
/ 04 марта 2011

Зависит.

Если у вас есть клиенты, которые компилируют свой собственный код (C ++ или C # или VB) для библиотеки типов вашего элемента управления, файла .h или .idl, вам, вероятно, придется изменитьРуководства по COM.

В следующих случаях вам не нужно менять руководство по COM:

  1. Ни один сторонний разработчик не потребляет ваш код.Никто не сломается, если вы измените интерфейс.

  2. Это элемент управления ActiveX, размещенный в веб-браузере и доступный через Javascript.

  3. Всепрограммное обеспечение в зависимости от вашей COM DLL поставляется вместе с обновленной версией вашего элемента управления.

  4. Это «внутреннее».Любой зависимый может при необходимости быстро перекомпилировать.

Если любое из вышеперечисленного верно, то вам не нужно менять направляющие COM.Просто добавьте новые методы в существующее объявление интерфейса.Перекомпилируйте все зависимые программы с изменениями.

В некоторых случаях вам следует быть осторожным.

  1. Кто-то уже скомпилировал (C ++, C # или VB) ипоставляется программное обеспечение на ваш существующий интерфейс - и они не могут сразу обновить, когда вы отправляете.Новые методы должны быть объявлены в новом интерфейсе COM.В существующую декларацию coclass также внесены изменения для поддержки этого интерфейса.

  2. Вы удаляете методы, изменяете поведение или иным образом вносите критические изменения в программное обеспечение доставки.Измените ваш гид на CoClass так, чтобы он мог сосуществовать бок о бок с теми, кто зависит от старой версии.Переименуйте также и DLL, чтобы она не перезаписывала старую при обновлении.

В приведенном выше примере я не думаю, что вам нужно объявлять новый Coclass - простоновый интерфейс.И вашему новому интерфейсу не нужно реализовывать методы первого.Просто пометьте оба интерфейса на Coclass.

dispinterface _DTest
{
    properties:
    methods:
        [id(1)] short TestMethod();
};

//  This is the new interface.
[ uuid(D2F8E5A8-8A95-463C-814F-B3CF84286224)]
dispinterface _DTest2
{
    properties:
    methods:
        [id(2)] short TestMethod2();
};


//  Class information for CTestCtrl
[ uuid(1DBD2333-2073-4FB6-89AC-E4B200ADED48), control ]
coclass Test
{
    [default] dispinterface _DTest;
    dispinterface _DTest2;
}

};

1 голос
/ 04 марта 2011

Вы всегда можете добавить интерфейсы. Новый элемент управления может просто реализовать старый и новый интерфейсы одновременно. Наследование - это простой метод C ++ для переработки больших частей старого интерфейса и реализации.

...