#c# #user-controls #activex #ole
#c# #пользовательские элементы управления #activex #ole
Вопрос:
В настоящее время мне поручено создать подключаемый модуль 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
классе или есть другой способ выполнить то, что я хочу (возможно, решение очень простое, но я пока не смог его увидеть). До сих пор я уже пробовал различные «возможные» решения:
-
Я пытался повторно реализовать
IOleObject
интерфейс, но посколькуSystem.Windows.Forms.UnsafeNativeMethods.IOleObject
он является внутренним, это невозможно сделать (вы должны использовать точно такой же интерфейс, а переопределение интерфейса не приводит к точно такому же интерфейсу). -
Я пытался использовать внедрение CLR, как описано Зиадом Элмалки в CodeProject.
-
Я пытался использовать какую-либо форму AOP. Поскольку
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:
Вы могли бы попытаться реализовать ICustomQueryInterface (.Net 4.0): http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustomqueryinterface.aspx
Когда система запрашивает IOleObject, вы могли бы вернуть свой собственный пользовательский объект, который реализует IOleObject , перенаправляет методы, которые вас не интересуют, в реализацию UserControl и надлежащим образом делегировать вызовы QueryInterface для пользовательского объекта обратно в UserControl (агрегирование).
Комментарии:
1. Хотя я смог реализовать ICustomQueryInterface и вернуть свою собственную реализацию интерфейса IOleObject, пересылка методов, которые меня не волнуют, в UserControl не является чем-то тривиальным. Проблема остается той же: некоторые интерфейсы / структуры, используемые реализацией IOleObject, предоставляемой классом Control, являются частными / внутренними и не могут быть использованы, поэтому вам нужно каким-то образом дублировать эти интерфейсы / структуры и преобразовать их во внутреннюю реализацию, используемую классом Control (что, насколько я могу судить, невозможно).
2. Я надеялся, что IOleObject и соответствующие интерфейсы и структуры, предоставляемые в сборке Microsoft.VisualStudio.OLE.Interop, каким-то образом совместимы с IOleObject, предоставляемым в System. Windows. Формирует сборку, но это не тот случай … к сожалению!