Изменить имя типа подключаемого модуля Active-X, написанное на C # - PullRequest
4 голосов
/ 08 июня 2011

В настоящее время мне поручено создать плагин Active-X для одного из наших клиентов.Теперь я успешно создал подключаемый модуль Active-X в C # /. NET (элемент управления Windows Form, который наследуется от класса System.Windows.Forms.UserControl), однако приложение, в котором размещается подключаемый модуль, отображает имя класса элемента управления взаголовок диалогового окна, в котором отображается плагин Active-X.

После долгих поисков и разборок я обнаружил, что хост * вызывает метод IOleObject.GetUserType и что это возвращаемое значениеэтого метода, который используется хостом в качестве заголовка диалогового окна.Глядя на класс System.Windows.Forms.UserControl, я обнаружил, что этот класс наследует от класса System.Windows.Forms.Control, который, в свою очередь, явно реализует интерфейс System.Windows.Forms.UnsafeNativeMethods.IOleObject.

Я хотел бы знать, есть ли какой-то способ переопределитьGetUserType метод в классе UserControl или, если есть другой способ выполнить то, что я хочу (возможно, решение очень простое, но я до сих пор не видел его).Я уже пробовал различные «возможные» решения:

  1. Я пытался повторно реализовать интерфейс IOleObject, но, поскольку System.Windows.Forms.UnsafeNativeMethods.IOleObject является внутренним, он не являетсяможно сделать это (вы должны использовать точно такой же интерфейс, и переопределение интерфейса не приведет к точно такому интерфейсу).

  2. Я пытался использовать инъекцию CLR, как описано вЗиад Эльмалки о CodeProject .

  3. Я пытался использовать некоторую форму АОП.Поскольку класс Control наследуется от System.MarshalByRefObject до System.ComponentModel.Component, я подумал, что мой пользовательский элемент управления мог бы вернуть какой-то прокси-сервер, который будет перехватывать вызовы, отправляемые методу GetUserType.

К сожалению, я не смог заставить это работать.Что работает, так это изменение имени класса, но поскольку имена классов не могут иметь пробелов или других специальных символов, это не является приемлемым решением (подчеркивания просто не совпадают).

Чтобы уточнить, вотпример кода того, что я хочу выполнить (обратите внимание, что оно не завершено):

using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[ ComVisible(true)
, ClassInterface(ClassInterfaceType.AutoDual)
, Description("My Active-X plug-in")
, Guid("...")
]
public partial class MyControl : UserControl
{
    public override int GetUserType(int dwFromOfType, out string userType)
    {
        userType = "The caption to show in the host";
        // Return S_OK
        return 0;
    }
}

Надеюсь, кто-то здесь может мне помочь.

Заранее спасибо!

1 Ответ

0 голосов
/ 18 июня 2011

Вы можете попытаться реализовать ICustomQueryInterface (.Net 4.0): http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustomqueryinterface.aspx

Когда система запрашивает IOleObject, вы можете вернуть свой собственный пользовательский объект, который реализует IOleObject, перенаправить методы, которые вам не нужны, в реализацию UserControl и правильно делегировать вызовы QueryInterface пользовательского объекта обратно в UserControl (агрегация ).

...