2009-02-27 1 views
2

Кто-нибудь знает, можно ли генерировать свойства ActiveX во время выполнения?Могут ли свойства ActiveX (доступ к которым из Visual Basic) обрабатываться процедурой во время выполнения?

Мне нужно только получить и установить эти свойства из Visual Basic.

My ActiveX control закодирован в C++, и я уже знаю, как создавать свойства, реализуя жестко заданные функции C++ get and put. Однако у меня есть потенциально большой набор свойств для этого элемента управления ActiveX, и в идеале выставленный набор свойств изменится в зависимости от внутреннего состояния элемента управления ActiveX.

Я надеюсь, что есть способ для генерации свойств из данных, например, следующий XML:

<Properties> 
    <Property> 
     <Name>SomeProperty</Name> 
     <Type>Int</Type> 
     <DefaultValue>10</DefaultValue> 
    </Property> 

    ... 

<Properties> 

Благодаря

+0

Вы хотите установить свойства своего собственного элемента управления ActiveX с помощью VBA? Можно установить большинство свойств большинства (если не всех) элементов управления в VBA во время выполнения. – Fionnuala

+0

Да, я хочу получить и установить свойства управления ActiveX с помощью VBA. Но это не проблема. Я хочу динамически изменять набор доступных/открытых свойств элемента управления ActiveX во время выполнения. –

ответ

0

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

Нам пришлось иметь дело с этой же проблемой при создании модуля калькуляции для нашего программного обеспечения для резки металла. Диктоника Microsoft Scripting была слишком негибкой, поэтому мы создали аналогичный набор объектов, называемый свойством. Это позволяет динамически добавлять свойства к нашим классам.

Option Explicit 

Private priName As String 
Private priValue As Variant 

Private priProperties As PropertyList 

Public Property Get Properties() As PropertyLis 
    Set Properties = priProperties 
End Property 

Public Function Assign(ByVal RHS As Property) 
    priName = RHS.Name 
    priValue = RHS.Value 
    priProperties.Assign RHS.Properties 
End Function 

Public Function Clone() As Property 
    Dim nObject As Property 

    Set nObject = New Property 

    nObject.Name = priName 
    nObject.Value = priValue 

    If Not priProperties Is Nothing Then 
     nObject.Properties.Assign priProperties 
    End If 

    Set Clone = nObject 

    Set nObject = Nothing 
End Function 

Public Property Get Name() As String 
    Name = priName 
End Property 

Public Property Let Name(ByVal RHS As String) 
    priName = RHS 
End Property 

Public Property Get Value() As Variant 
    Value = priValue 
End Property 

Public Property Let Value(ByVal RHS As Variant) 
    priValue = RHS 
End Property 

Private Sub Class_Initialize() 
    mPropertyType = PropertyTypeEnum.ptVariant 
    mPropertyList = New PropertyList 
End Sub 

PropertyList. Определите элемент как свойство по умолчанию, а NewEnum - свойство вашего перечислителя.

Option Explicit 

Private mCol As Collection 

Public Sub Assign(nObject As PropertyList) 
    Dim I As Long 

    Me.Clear 
    For I = 1 To nObject.Count 
     Me.AddMember nObject(I).Clone 
    Next 

End Sub 

Public Function Clone() As PropertyList 
    Dim nObject As PropertyList 
    Dim I As Long 

    Set nObject = New PropertyList 

    For I = 1 To Count 
     nObject.AddMember Me(I).Clone 
    Next I 

    Set Clone = nObject 

    Set nObject = Nothing 
End Function 

Public Sub AddMember(Item As Property) 
    mCol.Add Item, Item.Name 
End Sub 

Public Sub Add(Name As String, Optional Value As Variant) 
    Dim Item As Property 
    If Not Defined(Name) Then 
     Set Item = New Property 

     Item.Name = Name 

     If Not IsMissing(Value) Then N.Value = Value 
     AddMember N 
    Else 
     If Not IsMissing(Value) Then Me(Name).Value = Value 
    End If 
End Sub 

Private Sub Class_Initialize() 
    Set mCol = New Collection 
End Sub 

Private Sub Class_Terminate() 
    Set mCol = Nothing 
End Sub 

Public Sub Clear() 
    Set mCol = New Collection 
End Sub 

Public Property Get Count() 
    Count = mCol.Count 
End Property 

Public Property Get Defined(Index As Variant) As Boolean 
    Dim Item As Property 

    On Error Resume Next 

    If IsNumeric(Index) Then 
     Set Item = mCol(Index) 
    Else 
     Set Item = mCol(UCase(Index)) 
    End If 

    If Err.Number <> 0 Then 
     Defined = False 
    Else 
     Defined = True 
    End If 

End Property 

Public Property Get Item(Index As Variant) As Property 
    If IsNumeric(Index) Then 
     Set Item = mCol(Index) 
    Else 
     Set Item = mCol(UCase(Index)) 
    End If 
End Property 

Public Property Get NewEnum() As IUnknown 
    Set NewEnum = mCol.[_NewEnum] 
End Property 

Наша версия более sophiscated, чем это с сортировкой и возможности форматирования, поэтому мы не использовали Microsoft Scripting справочник. Это позволяет нам динамически создавать иерархический набор свойств. Что оказалось полезным при внедрении модуля калькуляции для нашего программного обеспечения. Поскольку мы постоянно добавляем или меняем поле в ответ на ввод клиента.

Это должно оказаться полезным при работе с гибкостью полей XML. Вы можете использовать функцию Vartype, чтобы получить точный тип варианта. При желании вы можете выбрать сохранение строк, поскольку VB6, как и большинство вариантов BASIC, может свободно конвертировать между числами и строками.

1

Это может быть очень легко или несколько сложно в зависимости от требуемого синтаксиса.

Одним из способов было бы создать свой собственный набор значений в элементе управления ActiveX. Можно добавить только два метода:

HRESULT GetPropery([in] BSTR name, [out,retval] VARIANT value); 
HRESULT SetPropery([in] BSTR name, [in] VARIANT value); 

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

Вы можете создать com collection (ссылка предполагает ATL, но theres общая информация о коллекциях com) свойство вариантов. Сделайте вызов Item() коллекции принятыми строками.Доступ было бы как (коллекция называется «Свойство»):

myValue = myControl.Properties("Name") 

Я не знаю, как вы могли бы установить значение, как это?

myControl.Properties("Name") = newValue 

Это может потребовать, чтобы коллекция возвращала не варианты, а COM-объекты со свойством «по умолчанию». Я даже не помню, как много деталей свойств по умолчанию, но я думаю, что клиенты VB6 поддерживают их хорошо, и все, что вам нужно было, было установлено в качестве атрибутов в файле IDL/ODL.

Обе идеи требуют, чтобы вызывающие абоненты имели это немного косвенности метода (Get/SetProperty) или использования свойства collection (myobject.Properties.XXXX). Если вы должны иметь синтаксис вроде этого:

x = myControl.MyDynamticProperty 

Вам нужно написать свой собственный реализацию IDispatch GetIDsOfName «s и Invoke. Я сделал это некоторое время назад, это было уродливо. К счастью, все это было удалено, так как мы пошли в другом направлении с этой частью приложения. Вам придется заставить вызывающих абонентов использовать интерфейс IDispatch без виртуальной таблицы (и быть связанным с поздней задержкой). Я полагаю, это может быть легко или сложно в зависимости от языка вызова. Мои абоненты всегда были VB сценарий, так что это не было проблемой.

+0

Спасибо. Первый вариант, который вы упомянули, звучит хорошо. IDispatch звучит интересно, но я действительно не хочу увязнуть в реализации его ... это похоже на раковину в реальном времени. –

+0

Идея IDispatch может быть огромной раковиной. Но я многое узнал о том, как работает IDispatch. Что еще пригодится в отладке - хорошо, хорошо, когда он это сделал ...;) – Aardvark

Смежные вопросы