有谁知道是否可以在运行时生成ActiveX属性?
我只需要能够从Visual Basic中获取和设置这些属性。
我的ActiveX控件是用C ++编写的,我已经知道如何通过实现硬编码的C ++ get和put函数来创建属性。但是,我可能为此ActiveX控件提供了大量属性,理想情况下,公开的属性集将根据ActiveX控件的内部状态而更改。
我希望有一种方法可以从数据生成属性,例如以下XML:
<Properties>
<Property>
<Name>SomeProperty</Name>
<Type>Int</Type>
<DefaultValue>10</DefaultValue>
</Property>
...
<Properties>
由于
答案 0 :(得分:1)
根据您需要的语法,这可能非常简单或有些困难。
一种方法是在ActiveX控件中创建自己的名称/值集合。 您只需添加两种方法:
HRESULT GetPropery([in] BSTR name, [out,retval] VARIANT value);
HRESULT SetPropery([in] BSTR name, [in] VARIANT value);
基本上你会在控件上有一个属性,它包含所有其他属性的集合。这是最直截了当的方式。
您可以改为创建com collection (链接假定ATL,但有关com集合的通用信息)属性。对集合的Item()调用接受字符串。访问它就像(该集合名为“Properties”):
myValue = myControl.Properties("Name")
我不确定如何设置这样的值?
myControl.Properties("Name") = newValue
这可能要求集合不返回变体,而是返回具有“default”属性的COM对象。我甚至不记得默认属性的大部分细节 - 但我认为VB6客户端很好地支持它们,所有你必须在IDL / ODL文件中设置一些属性。
这两种想法都要求调用者具有方法(Get / SetProperty)的一点间接或使用集合属性(myobject.Properties.XXXX)。如果你必须有这样的语法:
x = myControl.MyDynamticProperty
您需要编写自己的实现IDispatch 的GetIDsOfName和Invoke。我前一段时间做过这件事,很丑陋。值得庆幸的是,由于我们对应用程序的这一部分采取了不同的方向,因此全部删除了。您必须强制调用者使用非vtable IDispatch接口(并且是后期绑定) - 我认为这可能很容易或很难,具体取决于调用语言。我的调用者总是VB 脚本所以这不是问题。
答案 1 :(得分:0)
首先,它在技术上是可行的,但涉及到内存和vtable。不是因为内心的微弱而且绝对不是你想长期保持的任何东西。 COM的设计使得一旦定义了接口,它对于该修订是不变的。这就是为什么在添加到界面时更新修订号是至关重要的。
我们必须在为金属切割软件创建成本计算模块时处理同样的问题。 Microsoft Scripting的Dictonary太不灵活,所以我们创建了一组类似的属性对象。它允许动态地向我们的类添加属性。
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。将Item定义为默认属性,将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
我们的版本比排序和格式化功能更复杂,这就是我们不使用Microsoft Scripting Dictonary的原因。这允许我们动态创建一组分层属性。事实证明,这对我们的软件实施成本核算模块非常有用。因为我们不断添加或更改字段以响应客户输入。
这对于处理XML字段的灵活性非常有用。您可以使用Vartype函数获取变体的确切类型。您可以选择将字符串存储为VB6,就像大多数BASIC变体一样,可以在数字和字符串之间自由转换。