1

注意:这可能是在黑暗中拍摄的,我问这纯粹是出于好奇。

当使用 Microsoft 公共控件库 (mscomctl.ocx) 中的 ImageList 控件时,我发现 VB6 生成的 FRM 代码无法解析为真实的属性/方法名称,我很好奇如何进行解析。下面给出了一个生成的 FRM 代码示例,其中包含 3 个图像的 ImageList:

   Begin MSComctlLib.ImageList ImageList1 
      BackColor       =   -2147483643
      ImageWidth      =   100
      ImageHeight     =   45
      MaskColor       =   12632256
      BeginProperty Images {2C247F25-8591-11D1-B16A-00C0F0283628} 
         NumListImages   =   3
         BeginProperty ListImage1 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":0054
            Key             =   ""
         EndProperty
         BeginProperty ListImage2 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":3562
            Key             =   ""
         EndProperty
         BeginProperty ListImage3 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":6A70
            Key             =   ""
         EndProperty
      EndProperty
   End

根据我的经验,BeginProperty 标记通常意味着正在分配一个复合属性(一个对象),例如大多数控件的 Font 对象,例如:

Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   10950
   ClientLeft      =   60
   ClientTop       =   450
   ClientWidth     =   7215
   BeginProperty Font 
      Name            =   "MS Serif"
      Size            =   8.25
      Charset         =   0
      Weight          =   400
      Underline       =   0   'False
      Italic          =   -1  'True
      Strikethrough   =   0   'False
   EndProperty
End

可以很容易地看到它解析为 VB.Form.Font.<Property Name>。

对于 ImageList,没有名为 Images 的属性。与属性 Images 关联的 GUID 指示实现接口 IImages 的类型 ListImages。这种类型是有意义的,因为 ImageList 控件有一个名为 ListImages 的属性,它是 IImages 类型的。其次,属性 ListImage1、ListImage2 和 ListImage3 在 IImage 类型上不存在,但与这些属性关联的 GUID 指示实现接口 IImage 的 ListImage 类型。这种类型也很有意义,因为 IImages 实际上是 IImage 的集合。

对我来说没有意义的是 VB6 如何建立这些关联。VB6 怎么知道在名称 Images -> ListImages 之间建立关联,纯粹是因为关联类型(由 GUID 提供)——也许是因为它是该类型的唯一属性?其次,它如何将 ListImage1、ListImage2 和 ListImage3 解析为集合 IImages 的添加,它是否使用 Add 方法?或者也许是 ControlDefault 属性?

也许 VB6 对此控件有特定的知识并且不存在逻辑解决方案?

4

2 回答 2

3

你可以看到这个相当人为的例子发生了什么。从 ActiveX 项目开始,添加Class1并标记为Persistable = 1

' Class1
Option Explicit

Private m_sText As String

Property Get Text() As String
    Text = m_sText
End Property

Property Let Text(sValue As String)
    m_sText = sValue
End Property

Private Sub Class_ReadProperties(PropBag As PropertyBag)
    With PropBag
        m_sText = .ReadProperty("txt", "")
    End With
End Sub

Private Sub Class_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "txt", m_sText, ""
    End With
End Sub

添加用户控件1

' UserControl1
Option Explicit

Private m_oData As Class1

Property Get Data() As Class1
    Set Data = m_oData
End Property

Private Sub UserControl_Initialize()
    Set m_oData = New Class1
    m_oData.Text = "this is a test"
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    With PropBag
        Set m_oData = .ReadProperty("rs", Nothing)
    End With
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "rs", m_oData, Nothing
    End With
End Sub

添加 Form1 并在其上放置一个 UserControl1 作为保存。您可能希望为 Sub Main 添加 Module1

' Module1
Sub Main()
    With New Form1
        .Show
    End With
End Sub

这是我的Form1.frm文件

VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   2400
   ClientLeft      =   48
   ClientTop       =   432
   ClientWidth     =   3744
   LinkTopic       =   "Form1"
   ScaleHeight     =   2400
   ScaleWidth      =   3744
   StartUpPosition =   3  'Windows Default
   Begin Project1.UserControl1 UserControl11 
      Height          =   516
      Left            =   924
      TabIndex        =   0
      Top             =   588
      Width           =   1020
      _ExtentX        =   1799
      _ExtentY        =   910
      BeginProperty rs {326250A4-CA0D-4F88-8F20-DAA391CF8E79} 
         txt             =   "this is a test"
      EndProperty
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

因此UserControl1确定该对象在其重载中m_oData作为属性保留。确定其成员变量(或公共属性)作为成员在传递的 frm 中被持久化。没有什么需要公共属性名称来匹配内部属性包名称。我个人会使用缩短的 ID 来尽量减少膨胀(如果可能的话,使用 VB6)。rsWritePropertyClass1m_sTextTexttxtIPropertyBag

于 2010-03-20T12:41:50.323 回答
0

我猜 GUID ({2C247F25-8591-11D1-B16A-00C0F0283628}) 指向关联的 ImageList 控件和 ListImage1、ListImage2 等...只是用于枚举所有图像。

它有点像早期版本的 WPF 关联控件(例如,TextBox 可以引用其封闭网格进行放置)。

于 2010-03-19T19:26:35.553 回答